diff --git a/platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternSearcher.java b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternSearcher.java index 846b0c1de91d..9b9bdc1ee552 100644 --- a/platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternSearcher.java +++ b/platform/editor-ui-ex/src/com/intellij/psi/impl/search/IndexPatternSearcher.java @@ -25,6 +25,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import com.intellij.util.Processor; import com.intellij.util.QueryExecutor; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.CharArrayUtil; import com.intellij.util.text.CharSequenceSubSequence; import gnu.trove.TIntArrayList; @@ -135,55 +136,11 @@ public class IndexPatternSearcher implements QueryExecutor target, List source) { - if (target.isEmpty()) { - target.addAll(source); - return; - } - - mergeSortedArrays(target, source); - } - - /** - * Merge sorted points, which are sorted by x and with equal x by y. - * Result is put to x1 y1. - */ - static void mergeSortedArrays(@NotNull List target, @NotNull List source) { - List result = new ArrayList<>(); - - int i = 0; - int j = 0; - - while (i < target.size() && j < source.size()) { - CommentRange targetRange = target.get(i); - CommentRange sourceRange = source.get(j); - if (targetRange.startOffset < sourceRange.startOffset || - targetRange.startOffset == sourceRange.startOffset && targetRange.endOffset < sourceRange.endOffset) { - result.add(targetRange); - i++; - } - else if (targetRange.startOffset > sourceRange.startOffset || targetRange.endOffset > sourceRange.endOffset) { - result.add(sourceRange); - j++; - } - else { //equals - result.add(targetRange); - i++; - j++; - } - } - - while (i < target.size()) { - result.add(target.get(i)); - i++; - } - - while (j < source.size()) { - result.add(source.get(j)); - j++; - } - + List merged = target.isEmpty() + ? source + : ContainerUtil.mergeSortedLists(target, source, CommentRange.BY_START_OFFSET_THEN_BY_END_OFFSET, true); target.clear(); - target.addAll(result); + target.addAll(merged); } private static List findComments(final Lexer lexer, @@ -345,12 +302,15 @@ public class IndexPatternSearcher implements QueryExecutor BY_START_OFFSET_THEN_BY_END_OFFSET = + Comparator.comparingInt((CommentRange o) -> o.startOffset).thenComparingInt((CommentRange o) -> o.endOffset); + private final int startOffset; private final int endOffset; private final String allowedContinuationPrefixChars; - CommentRange(int startOffset, int endOffset) { + private CommentRange(int startOffset, int endOffset) { this(startOffset, endOffset, ""); } @@ -359,20 +319,5 @@ public class IndexPatternSearcher implements QueryExecutor target = new ArrayList<>(Arrays.asList( - new CommentRange(0, 0), - new CommentRange(2, 2), - new CommentRange(4, 4), - new CommentRange(6, 6) - )); - List source = Arrays.asList( - new CommentRange(1, 1), - new CommentRange(2, 2), - new CommentRange(2, 3) - ); - IndexPatternSearcher.mergeSortedArrays(target, source); - assertEquals(Arrays.asList( - new CommentRange(0, 0), - new CommentRange(1, 1), - new CommentRange(2, 2), - new CommentRange(2, 3), - new CommentRange(4, 4), - new CommentRange(6, 6) - ), target); - IndexPatternSearcher.mergeSortedArrays(target, source); - assertEquals(Arrays.asList( - new CommentRange(0, 0), - new CommentRange(1, 1), - new CommentRange(2, 2), - new CommentRange(2, 3), - new CommentRange(4, 4), - new CommentRange(6, 6) - ), target); - IndexPatternSearcher.mergeSortedArrays(target, Arrays.asList( - new CommentRange(-1, -1), - new CommentRange(-1, -2), - new CommentRange(-2, -3) - )); - assertEquals(Arrays.asList( - new CommentRange(-1, -1), - new CommentRange(-1, -2), - new CommentRange(-2, -3), - new CommentRange(0, 0), - new CommentRange(1, 1), - new CommentRange(2, 2), - new CommentRange(2, 3), - new CommentRange(4, 4), - new CommentRange(6, 6) - ), target); - } } diff --git a/platform/platform-tests/testSrc/com/intellij/util/containers/ContainerUtilTest.java b/platform/platform-tests/testSrc/com/intellij/util/containers/ContainerUtilTest.java index 732637fb1868..f6d2578706a8 100644 --- a/platform/platform-tests/testSrc/com/intellij/util/containers/ContainerUtilTest.java +++ b/platform/platform-tests/testSrc/com/intellij/util/containers/ContainerUtilTest.java @@ -16,6 +16,8 @@ package com.intellij.util.containers; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Segment; +import com.intellij.openapi.util.UnfairTextRange; import com.intellij.testFramework.PlatformTestUtil; import com.intellij.util.ArrayUtil; import one.util.streamex.IntStreamEx; @@ -241,4 +243,61 @@ public class ContainerUtilTest { List actual = ContainerUtil.newArrayList(value); assertEquals(expected, actual); } + + @Test + public void testMergeSortedLists() { + List target = new ArrayList<>(Arrays.asList( + range(0, 0), + range(2, 2), + range(4, 4), + range(6, 6) + )); + List source = Arrays.asList( + range(1, 1), + range(2, 2), + range(2, 3) + ); + target = mergeSegmentLists(target, source); + assertEquals(Arrays.asList( + range(0, 0), + range(1, 1), + range(2, 2), + range(2, 3), + range(4, 4), + range(6, 6) + ), target); + target = mergeSegmentLists(target, source); + assertEquals(Arrays.asList( + range(0, 0), + range(1, 1), + range(2, 2), + range(2, 3), + range(4, 4), + range(6, 6) + ), target); + target = mergeSegmentLists(target, Arrays.asList( + range(-1, -1), + range(-1, -2), + range(-2, -3) + )); + assertEquals(Arrays.asList( + range(-1, -1), + range(-1, -2), + range(-2, -3), + range(0, 0), + range(1, 1), + range(2, 2), + range(2, 3), + range(4, 4), + range(6, 6) + ), target); + } + + private static Segment range(int start, int end) { + return new UnfairTextRange(start, end); + } + + private static List mergeSegmentLists(List list1, List list2) { + return ContainerUtil.mergeSortedLists(list1, list2, Segment.BY_START_OFFSET_THEN_END_OFFSET, true); + } } \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java index bf9ffdde5079..dc77461ab89a 100644 --- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java +++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java @@ -637,7 +637,18 @@ public class ContainerUtil extends ContainerUtilRt { T element1 = list1.get(index1); T element2 = list2.get(index2); int c = comparator.compare(element1, element2); - if (c <= 0) { + if (c == 0) { + index1++; + index2++; + if (mergeEqualItems) { + e = element1; + } + else { + processor.consume(element1); + e = element2; + } + } + else if (c < 0) { e = element1; index1++; } @@ -645,11 +656,6 @@ public class ContainerUtil extends ContainerUtilRt { e = element2; index2++; } - if (c == 0 && !mergeEqualItems) { - processor.consume(e); - index2++; - e = element2; - } } processor.consume(e); }