From e0ad7347aa0547e01d121d0fb8e27ce685f5d6a0 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Mon, 5 Sep 2016 16:44:33 +0300 Subject: [PATCH] lst: simplify RangesBuilder * we don't need this complex logic, as we no longer try to reuse ranges that were computed at the first step --- .../iterables/DiffIterableUtil.java | 62 +++++---- .../com/intellij/openapi/vcs/ex/Range.java | 9 +- .../openapi/vcs/ex/RangesBuilder.java | 124 ++++++------------ 3 files changed, 85 insertions(+), 110 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/comparison/iterables/DiffIterableUtil.java b/platform/diff-impl/src/com/intellij/diff/comparison/iterables/DiffIterableUtil.java index 6c6a283d7164..6d8ab9dce64e 100644 --- a/platform/diff-impl/src/com/intellij/diff/comparison/iterables/DiffIterableUtil.java +++ b/platform/diff-impl/src/com/intellij/diff/comparison/iterables/DiffIterableUtil.java @@ -257,17 +257,14 @@ public class DiffIterableUtil { // Helpers // - public static class ChangeBuilder { + public abstract static class ChangeBuilderBase { private final int myLength1; private final int myLength2; - @Nullable private Diff.Change myFirstChange; - @Nullable private Diff.Change myLastChange; - private int myIndex1 = 0; private int myIndex2 = 0; - public ChangeBuilder(int length1, int length2) { + public ChangeBuilderBase(int length1, int length2) { myLength1 = length1; myLength2 = length2; } @@ -280,17 +277,12 @@ public class DiffIterableUtil { return myIndex2; } - protected void addChange(int start1, int start2, int end1, int end2) { - Diff.Change change = new Diff.Change(start1, start2, end1 - start1, end2 - start2, null); - if (myLastChange != null) { - myLastChange.link = change; - } - else { - myFirstChange = change; - } - myLastChange = change; - myIndex1 = end1; - myIndex2 = end2; + public int getLength1() { + return myLength1; + } + + public int getLength2() { + return myLength2; } public void markEqual(int index1, int index2) { @@ -316,19 +308,43 @@ public class DiffIterableUtil { myIndex2 = end2; } - protected void finish(int length1, int length2) { - assert myIndex1 <= length1; - assert myIndex2 <= length2; + protected void doFinish() { + assert myIndex1 <= myLength1; + assert myIndex2 <= myLength2; - if (length1 != myIndex1 || length2 != myIndex2) { - addChange(myIndex1, myIndex2, length1, length2); + if (myLength1 != myIndex1 || myLength2 != myIndex2) { + addChange(myIndex1, myIndex2, myLength1, myLength2); + myIndex1 = myLength1; + myIndex2 = myLength2; } } + protected abstract void addChange(int start1, int start2, int end1, int end2); + } + + public static class ChangeBuilder extends ChangeBuilderBase { + @Nullable private Diff.Change myFirstChange; + @Nullable private Diff.Change myLastChange; + + public ChangeBuilder(int length1, int length2) { + super(length1, length2); + } + + protected void addChange(int start1, int start2, int end1, int end2) { + Diff.Change change = new Diff.Change(start1, start2, end1 - start1, end2 - start2, null); + if (myLastChange != null) { + myLastChange.link = change; + } + else { + myFirstChange = change; + } + myLastChange = change; + } + @NotNull public DiffIterable finish() { - finish(myLength1, myLength2); - return create(myFirstChange, myLength1, myLength2); + doFinish(); + return create(myFirstChange, getLength1(), getLength2()); } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java index 48c050cc5227..2a2ba83a54fa 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/Range.java @@ -35,8 +35,8 @@ public class Range { // index of first line is 0 private int myLine1; private int myLine2; - private final int myVcsLine1; - private final int myVcsLine2; + private int myVcsLine1; + private int myVcsLine2; @Nullable private final List myInnerRanges; @@ -108,6 +108,11 @@ public class Range { } } + public void vcsShift(int shift) { + myVcsLine1 += shift; + myVcsLine2 += shift; + } + @Nullable public List getInnerRanges() { return myInnerRanges; 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 04cd523e2e2e..fec32fd937d5 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 @@ -82,41 +82,27 @@ public class RangesBuilder { @NotNull private static List createRangesSmart(@NotNull List current, @NotNull List vcs, - int shift, + int currentShift, int vcsShift) throws FilesTooBigForDiffException { FairDiffIterable iwIterable = ByLine.compare(vcs, current, ComparisonPolicy.IGNORE_WHITESPACES, DumbProgressIndicator.INSTANCE); - RangeBuilder rangeBuilder = new RangeBuilder(current, vcs, shift, vcsShift); + RangeBuilder rangeBuilder = new RangeBuilder(current, vcs, currentShift, vcsShift); - for (Pair pair : DiffIterableUtil.iterateAll(iwIterable)) { - com.intellij.diff.util.Range range = pair.first; - Boolean equals = pair.second; - - if (equals) { - int count = range.end1 - range.start1; - for (int i = 0; i < count; i++) { - int vcsIndex = range.start1 + i; - int currentIndex = range.start2 + i; - String vcsLine = vcs.get(vcsIndex); - String currentLine = current.get(currentIndex); - - if (vcsLine.equals(currentLine)) { - rangeBuilder.flushChange(); - } - else { - rangeBuilder.markChanged(vcsIndex, currentIndex); - } + for (com.intellij.diff.util.Range range : iwIterable.iterateUnchanged()) { + int count = range.end1 - range.start1; + for (int i = 0; i < count; i++) { + int vcsIndex = range.start1 + i; + int currentIndex = range.start2 + i; + if (vcs.get(vcsIndex).equals(current.get(currentIndex))) { + rangeBuilder.markEqual(vcsIndex, currentIndex); } } - else { - rangeBuilder.markChanged(range.start1, range.end1, range.start2, range.end2); - } } return rangeBuilder.finish(); } - private static class RangeBuilder { + private static class RangeBuilder extends DiffIterableUtil.ChangeBuilderBase { @NotNull private final List myCurrent; @NotNull private final List myVcs; private final int myCurrentShift; @@ -124,86 +110,54 @@ public class RangesBuilder { @NotNull private final List myResult = new ArrayList<>(); - private int vcsLine1 = -1; - private int vcsLine2 = -1; - private int currentLine1 = -1; - private int currentLine2 = -1; - public RangeBuilder(@NotNull List current, @NotNull List vcs, int currentShift, int vcsShift) { + super(vcs.size(), current.size()); myCurrent = current; myVcs = vcs; myCurrentShift = currentShift; myVcsShift = vcsShift; } - public void flushChange() { - if (vcsLine1 == -1) return; - - int forward = TrimUtil.expandForward(myVcs, myCurrent, vcsLine1, currentLine1, vcsLine2, currentLine2); - vcsLine1 += forward; - currentLine1 += forward; - - int backward = TrimUtil.expandBackward(myVcs, myCurrent, vcsLine1, currentLine1, vcsLine2, currentLine2); - vcsLine2 -= backward; - currentLine2 -= backward; - - List vcs = myVcs.subList(vcsLine1, vcsLine2); - List current = myCurrent.subList(currentLine1, currentLine2); - List inner = calcInnerRanges(vcs, current, myCurrentShift + currentLine1); - - myResult.add(new Range(myCurrentShift + currentLine1, myCurrentShift + currentLine2, - myVcsShift + vcsLine1, myVcsShift + vcsLine2, - inner)); - - - currentLine1 = -1; - currentLine2 = -1; - vcsLine1 = -1; - vcsLine2 = -1; + @NotNull + public List finish() { + doFinish(); + return myResult; } - public void markChanged(int vcsIndex, int currentIndex) { - markChanged(vcsIndex, vcsIndex + 1, currentIndex, currentIndex + 1); - } + @Override + protected void addChange(int vcsStart, int currentStart, int vcsEnd, int currentEnd) { + com.intellij.diff.util.Range range = TrimUtil.expand(myVcs, myCurrent, vcsStart, currentStart, vcsEnd, currentEnd); + if (range.isEmpty()) return; - public void markChanged(int vcsStart, int vcsEnd, int currentStart, int currentEnd) { - if (vcsLine1 == -1) { - vcsLine1 = vcsStart; - vcsLine2 = vcsEnd; - currentLine1 = currentStart; - currentLine2 = currentEnd; - } - else { - assert vcsStart == vcsLine2; - assert currentStart == currentLine2; - vcsLine2 = vcsEnd; - currentLine2 = currentEnd; - } + List innerRanges = calcInnerRanges(range); + Range newRange = new Range(range.start2, range.end2, range.start1, range.end1, innerRanges); + newRange.shift(myCurrentShift); + newRange.vcsShift(myVcsShift); + + myResult.add(newRange); } @NotNull - public List finish() { - flushChange(); - return myResult; - } - } + private List calcInnerRanges(@NotNull com.intellij.diff.util.Range blockRange) { + List vcs = myVcs.subList(blockRange.start1, blockRange.end1); + List current = myCurrent.subList(blockRange.start2, blockRange.end2); - @NotNull - private static List calcInnerRanges(@NotNull List vcs, @NotNull List current, int startOffset) { - ArrayList result = new ArrayList<>(); - FairDiffIterable iwIterable = ByLine.compare(vcs, current, ComparisonPolicy.IGNORE_WHITESPACES, DumbProgressIndicator.INSTANCE); - for (Pair pair : DiffIterableUtil.iterateAll(iwIterable)) { - com.intellij.diff.util.Range range = pair.first; - Boolean equals = pair.second; + ArrayList result = new ArrayList<>(); + FairDiffIterable iwIterable = ByLine.compare(vcs, current, ComparisonPolicy.IGNORE_WHITESPACES, DumbProgressIndicator.INSTANCE); + for (Pair pair : DiffIterableUtil.iterateAll(iwIterable)) { + com.intellij.diff.util.Range range = pair.first; + Boolean equals = pair.second; - byte type = equals ? Range.EQUAL : getChangeType(range.start1, range.end1, range.start2, range.end2); - result.add(new InnerRange(range.start2 + startOffset, range.end2 + startOffset, type)); + byte type = equals ? Range.EQUAL : getChangeType(range.start1, range.end1, range.start2, range.end2); + result.add(new InnerRange(range.start2 + blockRange.start2, range.end2 + blockRange.start2, + type)); + } + result.trimToSize(); + return result; } - result.trimToSize(); - return result; } private static byte getChangeType(int vcsStart, int vcsEnd, int currentStart, int currentEnd) {