lst: optimization - do not collect lines for unchanged prefix/suffix of the document

GitOrigin-RevId: 73f2a2f2512cb76966101040965731e1de799777
This commit is contained in:
Aleksey Pivovarov
2019-09-24 17:02:09 +00:00
committed by intellij-monorepo-bot
parent 013338247b
commit 2f11c4eb3c
5 changed files with 140 additions and 3 deletions
@@ -120,6 +120,13 @@ public class DiffIterableUtil {
return new SubiterableDiffIterable(iterable, start1, end1, start2, end2);
}
@NotNull
public static DiffIterable expandedIterable(@NotNull DiffIterable iterable, int offset1, int offset2, int length1, int length2) {
assert offset1 + iterable.getLength1() <= length1 &&
offset2 + iterable.getLength2() <= length2;
return new ExpandedDiffIterable(iterable, offset1, offset2, length1, length2);
}
//
// Misc
//
@@ -0,0 +1,72 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.diff.comparison.iterables;
import com.intellij.diff.util.Range;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
class ExpandedDiffIterable extends ChangeDiffIterableBase {
@NotNull private final DiffIterable myIterable;
private final int myOffset1;
private final int myOffset2;
ExpandedDiffIterable(@NotNull DiffIterable iterable, int offset1, int offset2, int length1, int length2) {
super(length1, length2);
myIterable = iterable;
myOffset1 = offset1;
myOffset2 = offset2;
}
@NotNull
@Override
protected ChangeIterable createChangeIterable() {
return new ShiftedChangeIterable(myIterable, myOffset1, myOffset2);
}
private static class ShiftedChangeIterable implements ChangeIterable {
private final Iterator<Range> myIterator;
private final int myOffset1;
private final int myOffset2;
private Range myLast;
ShiftedChangeIterable(@NotNull DiffIterable iterable, int offset1, int offset2) {
myIterator = iterable.changes();
myOffset1 = offset1;
myOffset2 = offset2;
next();
}
@Override
public boolean valid() {
return myLast != null;
}
@Override
public void next() {
myLast = myIterator.hasNext() ? myIterator.next() : null;
}
@Override
public int getStart1() {
return myLast.start1 + myOffset1;
}
@Override
public int getStart2() {
return myLast.start2 + myOffset2;
}
@Override
public int getEnd1() {
return myLast.end1 + myOffset1;
}
@Override
public int getEnd2() {
return myLast.end2 + myOffset2;
}
}
}
@@ -29,6 +29,7 @@ import com.intellij.diff.util.Side
import com.intellij.openapi.editor.Document
import com.intellij.openapi.progress.DumbProgressIndicator
import java.util.*
import kotlin.math.max
fun createRanges(current: List<String>,
vcs: List<String>,
@@ -63,9 +64,16 @@ fun compareLines(text1: CharSequence,
text2: CharSequence,
lineOffsets1: LineOffsets,
lineOffsets2: LineOffsets): FairDiffIterable {
val lines1 = DiffUtil.getLines(text1, lineOffsets1)
val lines2 = DiffUtil.getLines(text2, lineOffsets2)
return compareLines(lines1, lines2)
val range = expand(text1, text2, 0, 0, text1.length, text2.length)
if (range.isEmpty) return fair(DiffIterableUtil.create(emptyList(), lineOffsets1.lineCount, lineOffsets2.lineCount));
val start = lineOffsets1.getLineNumber(range.start1)
val end1 = lineOffsets1.getLineNumber(range.end1)
val tail = max(lineOffsets1.lineCount - end1 - 1, 0)
val lineRange = Range(start, lineOffsets1.lineCount - tail, start, lineOffsets2.lineCount - tail)
val iterable = compareLines(lineRange, text1, text2, lineOffsets1, lineOffsets2)
return fair(DiffIterableUtil.expandedIterable(iterable, start, start, lineOffsets1.lineCount, lineOffsets2.lineCount))
}
fun compareLines(lineRange: Range,
@@ -1,6 +1,7 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.vcs
import com.intellij.diff.comparison.iterables.DiffIterableUtil
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.runWriteAction
import com.intellij.openapi.command.CommandProcessor
@@ -10,6 +11,7 @@ import com.intellij.openapi.command.undo.DocumentReferenceProvider
import com.intellij.openapi.command.undo.UndoManager
import com.intellij.openapi.editor.Document
import com.intellij.openapi.fileEditor.FileEditor
import com.intellij.openapi.util.registry.Registry
import com.intellij.openapi.vcs.BaseLineStatusTrackerTestCase.Companion.parseInput
import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager
import com.intellij.openapi.vcs.ex.*
@@ -28,6 +30,7 @@ abstract class BaseLineStatusTrackerManagerTest : BaseChangeListsTest() {
override fun setUp() {
super.setUp()
DiffIterableUtil.setVerifyEnabled(true)
lstm = LineStatusTrackerManager.getInstanceImpl(getProject())
undoManager = UndoManager.getInstance(getProject()) as UndoManagerImpl
shelveManager = ShelveChangesManager.getInstance(getProject())
@@ -39,6 +42,7 @@ abstract class BaseLineStatusTrackerManagerTest : BaseChangeListsTest() {
.append(ThrowableRunnable { UIUtil.dispatchAllInvocationEvents() })
.append(ThrowableRunnable { lstm.resetExcludedFromCommitMarkers() })
.append(ThrowableRunnable { lstm.releaseAllTrackers() })
.append(ThrowableRunnable { DiffIterableUtil.setVerifyEnabled(Registry.`is`("diff.verify.iterable")) })
.append(ThrowableRunnable { super.tearDown() })
.run()
}
@@ -18,6 +18,52 @@ package com.intellij.openapi.vcs
import com.intellij.openapi.vcs.ex.Range
class LineStatusTrackerModifyDocumentTest : BaseLineStatusTrackerTestCase() {
fun testInitialEmpty() {
test("", "") {
assertRanges()
compareRanges()
}
}
fun testInitialEquals() {
test("1234_2345_3456",
"1234_2345_3456") {
assertRanges()
compareRanges()
}
}
fun testInitialInsertion() {
test("1234_2345_3456",
"1234_3456") {
assertRanges(Range(1, 2, 1, 1))
compareRanges()
}
}
fun testInitialDeletion() {
test("1234_3456", "1234_2345_3456") {
assertRanges(Range(1, 1, 1, 2))
compareRanges()
}
}
fun testInitialModification1() {
test("1234_x_3456", "1234_2345_3456") {
assertRanges(Range(1, 2, 1, 2))
compareRanges()
}
}
fun testInitialModification2() {
test("1_3_4_5_6_7", "1_2_3_5_6_12") {
assertRanges(Range(1, 1, 1, 2),
Range(2, 3, 3, 3),
Range(5, 6, 5, 6))
compareRanges()
}
}
fun testSimpleInsert() {
test("1234_2345_3456") {
"12".insertAfter("a")