From 8b2a300ab058078f07280a0b443fadbc31c575fb Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 11 May 2011 14:20:04 +0400 Subject: [PATCH] optimisation: visit only overlapping highlighters during paint --- .../injected/editor/MarkupModelWindow.java | 16 +- .../openapi/editor/ex/MarkupModelEx.java | 18 +- .../impl/EditorGutterComponentImpl.java | 35 +-- .../openapi/editor/impl/EmptyMarkupModel.java | 8 +- .../openapi/editor/impl/IntervalTree.java | 2 +- .../openapi/editor/impl/IntervalTreeImpl.java | 221 ++++++++++-------- .../openapi/editor/impl/IterationState.java | 14 +- .../openapi/editor/impl/MarkupModelImpl.java | 8 +- 8 files changed, 171 insertions(+), 151 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/injected/editor/MarkupModelWindow.java b/platform/lang-impl/src/com/intellij/injected/editor/MarkupModelWindow.java index e681c577d784..6afa8d6b6d18 100644 --- a/platform/lang-impl/src/com/intellij/injected/editor/MarkupModelWindow.java +++ b/platform/lang-impl/src/com/intellij/injected/editor/MarkupModelWindow.java @@ -23,7 +23,6 @@ import com.intellij.openapi.editor.impl.event.MarkupModelListener; import com.intellij.openapi.editor.markup.HighlighterTargetArea; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.editor.markup.TextAttributes; -import com.intellij.openapi.editor.impl.Interval; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.util.ProperTextRange; @@ -130,18 +129,15 @@ class MarkupModelWindow extends UserDataHolderBase implements MarkupModelEx { return false; } - public Iterator iterator() { - // todo - return null; + @NotNull + @Override + public Iterator overlappingIterator(int startOffset, int endOffset) { + // todo convert + return myHostModel.overlappingIterator(startOffset, endOffset); } - @NotNull - public Iterator iteratorFrom(@NotNull Interval interval) { - // todo convert - return myHostModel.iteratorFrom(interval); - } public boolean sweep(int start, int end, @NotNull SweepProcessor sweepProcessor) { // todo convert return myHostModel.sweep(start, end, sweepProcessor); } -} \ No newline at end of file +} diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/MarkupModelEx.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/MarkupModelEx.java index 21801c1691b3..7f87859f38c6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/MarkupModelEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/MarkupModelEx.java @@ -15,7 +15,6 @@ */ package com.intellij.openapi.editor.ex; -import com.intellij.openapi.editor.impl.Interval; import com.intellij.openapi.editor.impl.event.MarkupModelListener; import com.intellij.openapi.editor.markup.HighlighterTargetArea; import com.intellij.openapi.editor.markup.MarkupModel; @@ -31,7 +30,7 @@ import java.util.Iterator; /** * @author max */ -public interface MarkupModelEx extends MarkupModel, Iterable { +public interface MarkupModelEx extends MarkupModel { void dispose(); RangeHighlighter addPersistentLineHighlighter(int lineNumber, int layer, TextAttributes textAttributes); @@ -43,17 +42,18 @@ public interface MarkupModelEx extends MarkupModel, Iterable void setRangeHighlighterAttributes(@NotNull RangeHighlighter highlighter, TextAttributes textAttributes); boolean processHighlightsOverlappingWith(int start, int end, @NotNull Processor processor); + @NotNull - Iterator iteratorFrom(@NotNull Interval interval); + Iterator overlappingIterator(int startOffset, int endOffset); // optimization: creates highlighter and fires only one event: highlighterCreated RangeHighlighterEx addRangeHighlighterAndChangeAttributes(int startOffset, - int endOffset, - int layer, - TextAttributes textAttributes, - @NotNull HighlighterTargetArea targetArea, - boolean isPersistent, - Consumer changeAttributesAction); + int endOffset, + int layer, + TextAttributes textAttributes, + @NotNull HighlighterTargetArea targetArea, + boolean isPersistent, + Consumer changeAttributesAction); // runs change attributes action and fires highlighterChanged event if there were changes void changeAttributesInBatch(@NotNull RangeHighlighterEx highlighter, @NotNull Consumer changeAttributesAction); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java index 61907a85524c..c587297d2ada 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java @@ -377,18 +377,23 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse void process(RangeHighlighter highlighter); } - private void processRangeHighlighters(RangeHighlighterProcessor processor, int startOffset, int endOffset) { - final MarkupModelEx docMarkup = (MarkupModelEx)myEditor.getDocument().getMarkupModel(myEditor.getProject()); - Iterator docHighlighters = docMarkup.iterator(); + private void processRangeHighlighters(int startOffset, int endOffset, RangeHighlighterProcessor processor) { + Document document = myEditor.getDocument(); + final MarkupModelEx docMarkup = (MarkupModelEx)document.getMarkupModel(myEditor.getProject()); + // we limit highlighters to process to between line starting at startOffset and line ending at endOffset + int docLength = document.getTextLength(); + int patchedStartOffset = startOffset < docLength ? document.getLineStartOffset(document.getLineNumber(startOffset)) : docLength; + int patchedEndOffset = endOffset <= docLength ? document.getLineEndOffset(document.getLineNumber(endOffset)) + 1 : docLength; + Iterator docHighlighters = docMarkup.overlappingIterator(patchedStartOffset, patchedEndOffset); final MarkupModelEx editorMarkup = (MarkupModelEx)myEditor.getMarkupModel(); - Iterator editorHighlighters = editorMarkup.iterator(); + Iterator editorHighlighters = editorMarkup.overlappingIterator(startOffset, endOffset); RangeHighlighterEx lastDocHighlighter = null; RangeHighlighterEx lastEditorHighlighter = null; while (true) { - if (lastDocHighlighter == null && docHighlighters != null && docHighlighters.hasNext()) { + if (lastDocHighlighter == null && docHighlighters.hasNext()) { lastDocHighlighter = docHighlighters.next(); if (!lastDocHighlighter.isValid() || lastDocHighlighter.getAffectedAreaStartOffset() > endOffset) { lastDocHighlighter = null; @@ -396,12 +401,11 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } if (lastDocHighlighter.getAffectedAreaEndOffset() < startOffset) { lastDocHighlighter = null; - //docHighlighters = null; continue; } } - if (lastEditorHighlighter == null && editorHighlighters != null && editorHighlighters.hasNext()) { + if (lastEditorHighlighter == null && editorHighlighters.hasNext()) { lastEditorHighlighter = editorHighlighters.next(); if (!lastEditorHighlighter.isValid() || lastEditorHighlighter.getAffectedAreaStartOffset() > endOffset) { lastEditorHighlighter = null; @@ -409,7 +413,6 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } if (lastEditorHighlighter.getAffectedAreaEndOffset() < startOffset) { lastEditorHighlighter = null; - //editorHighlighters = null; continue; } } @@ -431,10 +434,10 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse if (!lowerHighlighter.isValid()) continue; int startLineIndex = lowerHighlighter.getDocument().getLineNumber(startOffset); - if (startLineIndex < 0 || startLineIndex >= myEditor.getDocument().getLineCount()) continue; + if (startLineIndex < 0 || startLineIndex >= document.getLineCount()) continue; int endLineIndex = lowerHighlighter.getDocument().getLineNumber(endOffset); - if (endLineIndex < 0 || endLineIndex >= myEditor.getDocument().getLineCount()) continue; + if (endLineIndex < 0 || endLineIndex >= document.getLineCount()) continue; if (lowerHighlighter.getEditorFilter().avaliableIn(myEditor)) { processor.process(lowerHighlighter); @@ -487,7 +490,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse private void calcIconAreaWidth() { myLineToGutterRenderers = new TIntObjectHashMap>(); - processRangeHighlighters(new RangeHighlighterProcessor() { + processRangeHighlighters(0, myEditor.getDocument().getTextLength(), new RangeHighlighterProcessor() { public void process(RangeHighlighter highlighter) { GutterIconRenderer renderer = highlighter.getGutterIconRenderer(); if (renderer == null) return; @@ -505,7 +508,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse renderers.add(renderer); } } - }, 0, myEditor.getDocument().getTextLength()); + }); myIconsAreaWidth = START_ICON_AREA_WIDTH; @@ -534,11 +537,11 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse Object hint = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); try { - processRangeHighlighters(new RangeHighlighterProcessor() { + processRangeHighlighters(firstVisibleOffset, lastVisibleOffset, new RangeHighlighterProcessor() { public void process(RangeHighlighter highlighter) { paintLineMarkerRenderer(highlighter, g); } - }, firstVisibleOffset, lastVisibleOffset); + }); } finally { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, hint); @@ -1199,7 +1202,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse int lastVisibleOffset = myEditor.logicalPositionToOffset( myEditor.xyToLogicalPosition(new Point(0, clip.y + clip.height + myEditor.getLineHeight()))); - processRangeHighlighters(new RangeHighlighterProcessor() { + processRangeHighlighters(firstVisibleOffset, lastVisibleOffset, new RangeHighlighterProcessor() { public void process(RangeHighlighter highlighter) { if (gutterRenderer[0] != null) return; Rectangle rectangle = getLineRendererRectangle(highlighter); @@ -1218,7 +1221,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse } } } - }, firstVisibleOffset, lastVisibleOffset); + }); return gutterRenderer[0]; } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EmptyMarkupModel.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EmptyMarkupModel.java index 9c7fea62df50..0fd18a8a5615 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EmptyMarkupModel.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EmptyMarkupModel.java @@ -106,14 +106,12 @@ public class EmptyMarkupModel implements MarkupModelEx { return false; } - public Iterator iterator() { + @NotNull + @Override + public Iterator overlappingIterator(int startOffset, int endOffset) { return ContainerUtil.emptyIterator(); } - @NotNull - public Iterator iteratorFrom(@NotNull Interval interval) { - return iterator(); - } public boolean sweep(int start, int end, @NotNull SweepProcessor sweepProcessor) { return false; } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTree.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTree.java index 2225a43bd179..8e3f6d0966cf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTree.java @@ -21,7 +21,7 @@ import org.jetbrains.annotations.NotNull; /** * User: cdr */ -public interface IntervalTree extends Iterable { +public interface IntervalTree { boolean process(@NotNull Processor processor); boolean processOverlappingWith(int start, int end, @NotNull Processor processor); boolean processOverlappingWith(int offset, @NotNull Processor processor); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java index bdf8679ff91e..cd8adc5c54ca 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java @@ -25,10 +25,7 @@ import gnu.trove.TLongHashSet; import org.jetbrains.annotations.NotNull; import java.lang.ref.ReferenceQueue; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; @@ -37,16 +34,15 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; /** * User: cdr */ -public abstract class IntervalTreeImpl extends RedBlackTree implements IntervalTree { +public abstract class IntervalTreeImpl extends RedBlackTree implements IntervalTree/*, Iterable*/{ private int keySize; // number of all intervals, counting all duplicates, some of them maybe gced protected final ReadWriteLock l = new ReentrantReadWriteLock(); - private IntervalNode minNode; // left most node in the tree protected abstract EqualStartIntervalComparator getComparator(); private final ReferenceQueue myReferenceQueue = new ReferenceQueue(); private int deadReferenceCount; - protected class IntervalNode extends Node implements MutableInterval { + protected class IntervalNode extends RedBlackTree.Node implements MutableInterval { private volatile int myStart; private volatile int myEnd; private volatile boolean isValid = true; @@ -314,6 +310,121 @@ public abstract class IntervalTreeImpl extends RedBla } } + @NotNull + Iterator overlappingIterator(final int startOffset, final int endOffset) { + final IntervalNode firstOverlap = findMinOverlappingWith(getRoot(), new TextRangeInterval(startOffset, endOffset), modCount, 0); + if (firstOverlap == null) { + return ContainerUtil.emptyIterator(); + } + normalize(); + final int modCountBefore = modCount; + return new Iterator() { + IntervalNode currentNode = firstOverlap; + int[] deltaUpToRootExclusive = {0}; + private int indexInCurrentList = 0; + T current; + + @Override + public boolean hasNext() { + if (current != null) return true; + if (currentNode == null) return false; + + if (modCount != modCountBefore) throw new ConcurrentModificationException(); + while (indexInCurrentList != currentNode.intervals.size()) { + T t = currentNode.intervals.get(indexInCurrentList++).get(); + if (t != null) { + current = t; + return true; + } + } + indexInCurrentList = 0; + while (true) { + currentNode = nextNode(currentNode, startOffset, endOffset, deltaUpToRootExclusive); + if (currentNode == null) { + return false; + } + if (overlaps(currentNode, startOffset, endOffset, deltaUpToRootExclusive[0])) { + assert currentNode.intervalStart() >= firstOverlap.intervalStart(); + indexInCurrentList = 0; + while (indexInCurrentList != currentNode.intervals.size()) { + T t = currentNode.intervals.get(indexInCurrentList++).get(); + if (t != null) { + current = t; + return true; + } + } + indexInCurrentList = 0; + } + } + } + + @Override + public T next() { + if (!hasNext()) throw new NoSuchElementException(); + T t = current; + current = null; + return t; + } + + @Override + public void remove() { + throw new IncorrectOperationException(); + } + }; + } + + private boolean overlaps(IntervalNode root, + int startOffset, int endOffset, + int deltaUpToRootExclusive) { + if (root == null) return false; + int delta = root.delta + deltaUpToRootExclusive; + int start = root.intervalStart() + delta; + int end = root.intervalEnd() + delta; + return Math.max(start, startOffset) <= Math.min(end, endOffset); + } + + private IntervalNode nextNode(@NotNull IntervalNode root, + int startOffset, int endOffset, + @NotNull int[] newDeltaUpToRootExclusive) { + assert root.isValid(); + int deltaUpToRootExclusive = newDeltaUpToRootExclusive[0]; + int delta = deltaUpToRootExclusive + root.delta; + //int myStartOffset = root.intervalStart() + delta; + //int myEndOffset = root.intervalEnd() + delta; + int myMaxEnd = maxEndOf(root, deltaUpToRootExclusive); + assert startOffset <= myMaxEnd; + + // try to go right down + IntervalNode right = root.getRight(); + if (right != null) { + int rightMaxEnd = maxEndOf(right, delta); + if (startOffset <= rightMaxEnd) { + int rightDelta = delta + right.delta; + while (right.getLeft() != null && startOffset <= maxEndOf(right.getLeft(), rightDelta)) { + right = right.getLeft(); + rightDelta += right.delta; + } + newDeltaUpToRootExclusive[0] = rightDelta - right.delta; + return right; + } + } + + // go up + while (true) { + IntervalNode parent = root.getParent(); + if (parent == null) return null; + if (parent.intervalStart() + deltaUpToRootExclusive > endOffset) return null; // can't move right + deltaUpToRootExclusive -= parent.delta; + + if (parent.getLeft() == root) { + newDeltaUpToRootExclusive[0] = deltaUpToRootExclusive; + return parent; + } + + root = parent; + } + } + private boolean processOverlapping(IntervalNode root, int offset, Processor processor, @@ -355,7 +466,7 @@ public abstract class IntervalTreeImpl extends RedBla node.setLeft(null); node.setRight(null); - List gced = new ArrayList(); + List gced = new SmartList(); if (root == null) { root = node; } @@ -387,7 +498,6 @@ public abstract class IntervalTreeImpl extends RedBla node.delta = -delta; node.setParent(current); } - linkNode(node); correctMaxUp(node); onInsertNode(); assertUnderWriteLock(); @@ -399,29 +509,6 @@ public abstract class IntervalTreeImpl extends RedBla return node; } - private void linkNode(@NotNull IntervalNode node) { - IntervalNode previous = previous(node); - if (previous == null) { - node.next = minNode; - minNode = node; - } - else { - node.next = previous.next; - previous.next = node; - } - } - - private void unlinkNode(@NotNull IntervalNode node) { - IntervalNode previous = previous(node); - if (previous == null) { - minNode = node.next; - } - else { - previous.next = node.next; - } - node.next = null; - } - // finds previous in the in-order traversal private IntervalNode previous(@NotNull IntervalNode node) { IntervalNode left = node.getLeft(); @@ -447,7 +534,6 @@ public abstract class IntervalTreeImpl extends RedBla for (IntervalNode node : collectedAway) { removeNode(node); } - checkMax(true); } finally { l.writeLock().unlock(); @@ -493,10 +579,6 @@ public abstract class IntervalTreeImpl extends RedBla assert nodeSize() == nodeCounter.get() : "node size: "+ nodeSize() +"; actual: "+nodeCounter; assert keySize == keyCounter.get() : "key size: "+ keySize +"; actual: "+keyCounter; assert keySize >= nodeSize() : keySize + "; "+nodeSize(); - - IntervalNode left = getRoot(); - while (left != null && left.getLeft() != null) left = left.getLeft(); - assert minNode == left; } return allValid.get(); } @@ -640,7 +722,6 @@ public abstract class IntervalTreeImpl extends RedBla assertUnderWriteLock(); IntervalNode node = (IntervalNode)n; pushDeltaFromRoot(node); - unlinkNode(node); super.deleteNode(n); @@ -744,6 +825,7 @@ public abstract class IntervalTreeImpl extends RedBla if (r2 != null) r2.setParent(n1); } + // returns real max endOffset of all intervals below private int maxEndOf(IntervalNode node, int deltaUpToRootExclusive) { if (node == null) { return 0; @@ -751,6 +833,7 @@ public abstract class IntervalTreeImpl extends RedBla if (node.isValid()) { return node.maxEnd + node.delta + deltaUpToRootExclusive; } + // since node is invalid, ignore node.delta return Math.max(maxEndOf(node.getLeft(), deltaUpToRootExclusive), maxEndOf(node.getRight(), deltaUpToRootExclusive)); } @@ -831,14 +914,6 @@ public abstract class IntervalTreeImpl extends RedBla } } - public Iterator iterator() { - IntervalNode firstNode = minNode; - if (firstNode == null) { - return ContainerUtil.emptyIterator(); - } - return createIteratorFrom(firstNode); - } - private IntervalNode findMinOverlappingWith(IntervalNode root, Interval interval, int modCountBefore, int deltaUpToRootExclusive) { if (root == null) { return null; @@ -865,59 +940,7 @@ public abstract class IntervalTreeImpl extends RedBla return findMinOverlappingWith(root.getRight(), interval, modCountBefore, delta); } - @NotNull - Iterator iteratorFrom(@NotNull Interval interval) { - IntervalNode firstOverlap = findMinOverlappingWith(getRoot(), interval, modCount, 0); - if (firstOverlap == null) { - return ContainerUtil.emptyIterator(); - } - return createIteratorFrom(firstOverlap); - } - - private Iterator createIteratorFrom(@NotNull final IntervalNode firstNode) { - checkMax(true); - normalize(); - - final int modCountBefore = modCount; - return new Iterator() { - private IntervalNode node = firstNode; - private int indexInCurrentList = 0; - T current; - - public boolean hasNext() { - if (current != null) return true; - while (node != null) { - while (indexInCurrentList != node.intervals.size()) { - current = node.intervals.get(indexInCurrentList).get(); - if (current != null) return true; - indexInCurrentList++; - } - indexInCurrentList = 0; - node = node.next; - } - return false; - } - - public T next() { - assert modCount == modCountBefore : "Must not modify range markers during iterate"; - if (!hasNext()) throw new NoSuchElementException(); - - T t = current; - current = null; - - indexInCurrentList++; - return t; - } - - - public void remove() { - throw new IncorrectOperationException(); - } - }; - } - protected volatile boolean normalized = true; - public void normalize() { if (normalized) return; try { @@ -982,13 +1005,13 @@ public abstract class IntervalTreeImpl extends RedBla List gced = new ArrayList(); collectGced(getRoot(), gced); deleteNodes(gced); + checkMax(true); } @Override public void clear() { super.clear(); keySize = 0; - minNode = null; } private void collectGced(IntervalNode root, List gced) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/IterationState.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/IterationState.java index a321ef03b5ed..93aff891a42e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/IterationState.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/IterationState.java @@ -120,13 +120,17 @@ public final class IterationState { private Iterator myIterator; private void init(MarkupModelEx markupModel, int start) { - myIterator = markupModel.iteratorFrom(new TextRangeInterval(start, myDocument.getTextLength())); - + myIterator = markupModel.overlappingIterator(start, myDocument.getTextLength()); + int skipped = 0; while (myIterator.hasNext()) { - myNextHighlighter = myIterator.next(); - if (!skipHighlighter(myNextHighlighter)) break; - else myNextHighlighter = null; + RangeHighlighterEx highlighter = myIterator.next(); + if (!skipHighlighter(highlighter)) { + myNextHighlighter = highlighter; + break; + } + skipped++; } + int i = skipped; } private void advance() { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java index 520c16ae5868..fef5de229164 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/MarkupModelImpl.java @@ -231,13 +231,9 @@ public class MarkupModelImpl extends UserDataHolderBase implements MarkupModelEx return myHighlighterTree.processOverlappingWith(start, end, processor); } - public Iterator iterator() { - return myHighlighterTree.iterator(); - } - @NotNull - public Iterator iteratorFrom(@NotNull Interval interval) { - return myHighlighterTree.iteratorFrom(interval); + public Iterator overlappingIterator(int startOffset, int endOffset) { + return myHighlighterTree.overlappingIterator(startOffset, endOffset); } public boolean sweep(int start, int end, @NotNull SweepProcessor sweepProcessor) {