Skip to content

Commit 80fd47a

Browse files
DenisUngemachBeckerWdf
authored andcommitted
Compare View for big files with Line Spacing freezes eclipse
For big files with many differences, the compare view freezed eclipse, if the line spacing was set. The reason were the necessary resources to calculate the spacing in the method getHeightBetweenLines. We have to save the heights in a list and use them to increase the performance. Clear line heights cache at property changes. Fixes eclipse-platform/eclipse.platform.ui#2143 Signed-off-by: Denis Ungemach <[email protected]>
1 parent cde120b commit 80fd47a

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

team/bundles/org.eclipse.compare/compare/org/eclipse/compare/contentmergeviewer/TextMergeViewer.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.lang.reflect.InvocationTargetException;
3030
import java.text.MessageFormat;
3131
import java.util.ArrayList;
32+
import java.util.Collections;
3233
import java.util.HashMap;
3334
import java.util.Iterator;
3435
import java.util.List;
@@ -474,6 +475,12 @@ private static RGB interpolate(RGB fg, RGB bg, double scale) {
474475
private IUndoableOperation copyUndoable = null;
475476
private IOperationHistoryListener operationHistoryListener;
476477

478+
// https://github.com/eclipse-platform/eclipse.platform.ui/issues/2143
479+
// calling w.getLineHeight(line) + w.getLineSpacing() +
480+
// w.getLineVerticalIndent(line); again and again for the same line is too slow
481+
// we therefore introduce a line height cache by viewer
482+
private final Map<MergeSourceViewer, List<Integer>> lineHeightsByViewer = new HashMap<>();
483+
477484
/**
478485
* Preference key for highlighting current line.
479486
*/
@@ -4001,6 +4008,16 @@ && getCompareConfiguration().getContainer().getActionBars() != null) {
40014008

40024009
@Override
40034010
protected void handlePropertyChangeEvent(PropertyChangeEvent event) {
4011+
4012+
// Property changes might change the height of lines,
4013+
// which means the heights cache should be cleared.
4014+
// But the actual height change of lines in StyledText does not happen in this
4015+
// method.
4016+
// There are other property change listeners for example:
4017+
// AbstractTextEditor.PropertyChangeListener,
4018+
// and these handle the height changes of StyledText.
4019+
lineHeightsByViewer.clear();
4020+
40044021
String key= event.getProperty();
40054022

40064023
if (key.equals(CompareConfiguration.IGNORE_WHITESPACE)
@@ -4206,9 +4223,29 @@ private void updateLines(IDocument d) {
42064223
*/
42074224
private int getHeightBetweenLines(MergeSourceViewer tp, int fromLine, int toLine) {
42084225
StyledText w = tp.getSourceViewer().getTextWidget();
4226+
List<Integer> lineHeights = this.lineHeightsByViewer.get(tp);
4227+
if (lineHeights == null) {
4228+
lineHeights = new ArrayList<>();
4229+
lineHeights.addAll(Collections.nCopies(w.getLineCount(), null));
4230+
this.lineHeightsByViewer.put(tp, lineHeights);
4231+
tp.getSourceViewer().addTextListener(event -> {
4232+
List<Integer> lineHeightsList = lineHeightsByViewer.get(tp);
4233+
if (lineHeightsList != null) {
4234+
lineHeightsList.clear();
4235+
lineHeightsList.addAll(Collections.nCopies(w.getLineCount(), null));
4236+
}
4237+
});
4238+
}
4239+
int lineSpacing = w.getLineSpacing();
42094240
int height = 0;
42104241
for (int i = fromLine; i < toLine; i++) {
4211-
height += w.getLineHeight(i) + w.getLineSpacing() + w.getLineVerticalIndent(i);
4242+
Integer heightAtLine = lineHeights.get(i);
4243+
if (heightAtLine == null) {
4244+
int lineOffset = w.getOffsetAtLine(i);
4245+
heightAtLine = w.getLineHeight(lineOffset) + lineSpacing + w.getLineVerticalIndent(i);
4246+
lineHeights.set(i, heightAtLine);
4247+
}
4248+
height += heightAtLine;
42124249
}
42134250
return height;
42144251
}

0 commit comments

Comments
 (0)