From 8ed36b16dfe418a76450aa05ee9b902fc2f9ca34 Mon Sep 17 00:00:00 2001 From: irengrig Date: Tue, 31 May 2011 22:25:28 +0400 Subject: [PATCH] VCS: remove equal start and end parts on Diff class level - for all calls --- .../intellij/util/containers/Enumerator.java | 10 ++++-- .../util/src/com/intellij/util/diff/Diff.java | 36 +++++++++++++++---- .../util/containers/EnumeratorTest.java | 8 +++-- .../com/intellij/util/diff/DiffTest.java | 21 +++++++---- .../com/intellij/util/diff/IntLCSTest.java | 2 +- .../util/diff/LinkedDiffPathsTest.java | 2 +- .../openapi/vcs/ex/RangesBuilder.java | 29 +-------------- 7 files changed, 60 insertions(+), 48 deletions(-) diff --git a/platform/util/src/com/intellij/util/containers/Enumerator.java b/platform/util/src/com/intellij/util/containers/Enumerator.java index d387840d30ab..c74d3ec22de3 100644 --- a/platform/util/src/com/intellij/util/containers/Enumerator.java +++ b/platform/util/src/com/intellij/util/containers/Enumerator.java @@ -39,11 +39,15 @@ public class Enumerator { } public int[] enumerate(T[] objects) { - int[] idx = ArrayUtil.newIntArray(objects.length); - for (int i = 0; i < objects.length; i++) { + return enumerate(objects, 0, 0); + } + + public int[] enumerate(T[] objects, final int startShift, final int endCut) { + int[] idx = ArrayUtil.newIntArray(objects.length - startShift - endCut); + for (int i = startShift; i < (objects.length - endCut); i++) { final T object = objects[i]; final int number = enumerate(object); - idx[i] = number; + idx[i - startShift] = number; } return idx; } diff --git a/platform/util/src/com/intellij/util/diff/Diff.java b/platform/util/src/com/intellij/util/diff/Diff.java index d35e13d14743..b3f85da2c673 100644 --- a/platform/util/src/com/intellij/util/diff/Diff.java +++ b/platform/util/src/com/intellij/util/diff/Diff.java @@ -32,30 +32,54 @@ public class Diff { private static final Logger LOG = Logger.getInstance("#com.intellij.util.diff.Diff"); @Nullable - public static Change buildChanges(@NotNull CharSequence before, @NotNull CharSequence after) { + public static Change buildChanges(@NotNull CharSequence before, @NotNull CharSequence after) throws FilesTooBigForDiffException { final String[] strings1 = LineTokenizer.tokenize(before, false); final String[] strings2 = LineTokenizer.tokenize(after, false); return buildChanges(strings1, strings2); } - public static Change buildChanges(T[] objects1, T[] objects2) { + public static Change buildChanges(T[] objects1, T[] objects2) throws FilesTooBigForDiffException { // Old variant of enumerator worked incorrectly with null values. // This check is to ensure that the corrected version does not introduce bugs. for (T anObjects1 : objects1) LOG.assertTrue(anObjects1 != null); for (T anObjects2 : objects2) LOG.assertTrue(anObjects2 != null); + final int startShift = getStartShift(objects1, objects2); + final int endCut = getEndCut(objects1, objects2, startShift); + Enumerator enumerator = new Enumerator(objects1.length + objects2.length, TObjectHashingStrategy.CANONICAL); - int[] ints1 = enumerator.enumerate(objects1); - int[] ints2 = enumerator.enumerate(objects2); + int[] ints1 = enumerator.enumerate(objects1, startShift, endCut); + int[] ints2 = enumerator.enumerate(objects2, startShift, endCut); Reindexer reindexer = new Reindexer(); int[][] discarded = reindexer.discardUnique(ints1, ints2); IntLCS intLCS = new IntLCS(discarded[0], discarded[1]); intLCS.execute(); - ChangeBuilder builder = new ChangeBuilder(); + ChangeBuilder builder = new ChangeBuilder(startShift); reindexer.reindex(intLCS.getPaths(), builder); return builder.getFirstChange(); } + private static int getStartShift(final T[] o1, final T[] o2) { + final int size = Math.min(o1.length, o2.length); + int idx = 0; + for (int i = 0; i < size; i++) { + if (! o1[i].equals(o2[i])) break; + ++ idx; + } + return idx; + } + + private static int getEndCut(final T[] o1, final T[] o2, final int startShift) { + final int size = Math.min(o1.length, o2.length) - startShift; + int idx = 0; + + for (int i = 0; i < size; i++) { + if (! o1[o1.length - i - 1].equals(o2[o2.length - i - 1])) break; + ++ idx; + } + return idx; + } + /** * Tries to translate given line that pointed to the text before change to the line that points to the same text after the change. * @@ -64,7 +88,7 @@ public class Diff { * @param line target line before change * @return translated line if the processing is ok; negative value otherwise */ - public static int translateLine(@NotNull CharSequence before, @NotNull CharSequence after, int line) { + public static int translateLine(@NotNull CharSequence before, @NotNull CharSequence after, int line) throws FilesTooBigForDiffException { Change change = buildChanges(before, after); if (change == null) { return -1; diff --git a/platform/util/testSrc/com/intellij/util/containers/EnumeratorTest.java b/platform/util/testSrc/com/intellij/util/containers/EnumeratorTest.java index 28486f47a92b..f6d32dbe26b6 100644 --- a/platform/util/testSrc/com/intellij/util/containers/EnumeratorTest.java +++ b/platform/util/testSrc/com/intellij/util/containers/EnumeratorTest.java @@ -21,8 +21,6 @@ import junit.framework.TestCase; import java.util.Arrays; -import com.intellij.util.containers.Enumerator; - /** * @author dyoma */ @@ -34,4 +32,10 @@ public class EnumeratorTest extends TestCase { indecies = enumerator.enumerate(new Object[]{"a", "c", "b"}); assertTrue(Arrays.equals(new int[]{1, 3, 2}, indecies)); } + + public void testWithShift() { + Enumerator enumerator = new Enumerator(10, TObjectHashingStrategy.CANONICAL); + int[] indecies = enumerator.enumerate(new Object[]{"1","a", "b", "a", "2"}, 1, 1); + assertTrue(Arrays.equals(new int[]{1, 2, 1}, indecies)); + } } diff --git a/platform/util/testSrc/com/intellij/util/diff/DiffTest.java b/platform/util/testSrc/com/intellij/util/diff/DiffTest.java index fb348ddfb7ad..f633e8fa334b 100644 --- a/platform/util/testSrc/com/intellij/util/diff/DiffTest.java +++ b/platform/util/testSrc/com/intellij/util/diff/DiffTest.java @@ -27,34 +27,41 @@ public class DiffTest extends TestCase { private static final Object[] DATA_123 = new Object[]{"1", "2", "3"}; private static final Object[] DATA_AB = new Object[]{"a", "b"}; private static final Object[] DATA_12AB23 = new Object[]{"1", "2", "a", "b", "2", "3"}; + private static final Object[] DATA_123_ = new Object[]{"x","y","z","1", "2","3","alpha","beta"}; + private static final Object[] DATA_12AB23_ = new Object[]{"x","y","z","1", "2", "a", "b", "2", "3","alpha","beta"}; - public void testEqual() { + public void testEqual() throws FilesTooBigForDiffException { Diff.Change change = Diff.buildChanges(DATA_123, DATA_123); assertNull(change); } - public void testCompletelyDifferent() { + public void testCompletelyDifferent() throws FilesTooBigForDiffException { Diff.Change change = Diff.buildChanges(DATA_AB, DATA_123); IntLCSTest.checkLastChange(change, 0, 0, 3, 2); } - public void testSameMiddle() { + public void testSameMiddle() throws FilesTooBigForDiffException { Diff.Change change = Diff.buildChanges(DATA_123, new Object[]{"a", "2", "b"}); IntLCSTest.checkChange(change, 0, 0, 1, 1); IntLCSTest.checkLastChange(change.link, 2, 2, 1, 1); } - public void testOverlap() { + public void testOverlap() throws FilesTooBigForDiffException { Diff.Change change = Diff.buildChanges(DATA_123, DATA_12AB23); IntLCSTest.checkLastChange(change, 2, 2, 3, 0); // inserted: AB2 } - public void testEqualUpToOneEnd() { + public void testTrim() throws FilesTooBigForDiffException { + Diff.Change change = Diff.buildChanges(DATA_123_, DATA_12AB23_); + IntLCSTest.checkLastChange(change, 5, 5, 3, 0); // inserted: AB2 + } + + public void testEqualUpToOneEnd() throws FilesTooBigFirDiffException { Diff.Change change = Diff.buildChanges(DATA_AB, new Object[]{"a", "b", "1"}); IntLCSTest.checkLastChange(change, 2, 2, 1, 0); } - public void testEmptyAgainstSmth() { + public void testEmptyAgainstSmth() throws FilesTooBigForDiffException { Object[] empty = ArrayUtil.EMPTY_OBJECT_ARRAY; Diff.Change change = Diff.buildChanges(empty, empty); assertNull(change); @@ -64,7 +71,7 @@ public class DiffTest extends TestCase { IntLCSTest.checkLastChange(change, 0, 0, 3, 0); } - public void testPerfomance() { + public void testPerfomance() throws FilesTooBigForDiffException { ArrayList first = new ArrayList(); ArrayList second = new ArrayList(); int max = 1000; diff --git a/platform/util/testSrc/com/intellij/util/diff/IntLCSTest.java b/platform/util/testSrc/com/intellij/util/diff/IntLCSTest.java index 557db8947f5c..57a028ed115f 100644 --- a/platform/util/testSrc/com/intellij/util/diff/IntLCSTest.java +++ b/platform/util/testSrc/com/intellij/util/diff/IntLCSTest.java @@ -67,7 +67,7 @@ public class IntLCSTest extends TestCase { assertEquals(expectedNonDiags, intLCS.execute()); Reindexer reindexer = new Reindexer(); reindexer.idInit(first.length, second.length); - Diff.ChangeBuilder builder = new Diff.ChangeBuilder(); + Diff.ChangeBuilder builder = new Diff.ChangeBuilder(0); reindexer.reindex(intLCS.getPaths(), builder); return builder.getFirstChange(); } diff --git a/platform/util/testSrc/com/intellij/util/diff/LinkedDiffPathsTest.java b/platform/util/testSrc/com/intellij/util/diff/LinkedDiffPathsTest.java index 31b8d70e1a82..f9b2b23632eb 100644 --- a/platform/util/testSrc/com/intellij/util/diff/LinkedDiffPathsTest.java +++ b/platform/util/testSrc/com/intellij/util/diff/LinkedDiffPathsTest.java @@ -69,7 +69,7 @@ public class LinkedDiffPathsTest extends TestCase { private Diff.Change decode(LinkedDiffPaths paths) { Reindexer reindexer = new Reindexer(); reindexer.idInit(paths.getXSize(), paths.getYSize()); - Diff.ChangeBuilder builder = new Diff.ChangeBuilder(); + Diff.ChangeBuilder builder = new Diff.ChangeBuilder(0); reindexer.reindex(paths, builder); return builder.getFirstChange(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java index 594b125f9aa6..a344c2b7bb04 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/RangesBuilder.java @@ -36,38 +36,11 @@ public class RangesBuilder { public RangesBuilder(List current, List upToDate, int shift, int uShift) { myRanges = new LinkedList(); - int shiftBefore = 0; - - int minSize = Math.min(upToDate.size(), current.size()); - - for (int i = 0; i < minSize; i++) { - if (upToDate.get(0).equals(current.get(0))) { - upToDate.remove(0); - current.remove(0); - shiftBefore += 1; - } - else { - break; - } - } - - minSize = Math.min(upToDate.size(), current.size()); - - for (int i = 0; i < minSize; i++) { - if (upToDate.get(upToDate.size() - 1).equals(current.get(current.size() - 1))) { - upToDate.remove(upToDate.size() - 1); - current.remove(current.size() - 1); - } - else { - break; - } - } - Diff.Change ch = Diff.buildChanges(ArrayUtil.toStringArray(upToDate), ArrayUtil.toStringArray(current)); while (ch != null) { - Range range = Range.createOn(ch, shift + shiftBefore, uShift + shiftBefore); + Range range = Range.createOn(ch, shift, uShift); myRanges.add(range); ch = ch.link; }