mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-09 02:36:01 +02:00
Bug 515500: Preserve known line numbers when updating ui
This resolves a significant UI performance regression so
now line numbers don't need to be recalculated for areas
where they are already known.
Change-Id: I4668d620cde24b7cd8c6a22e9c022eaf5b237ff2
(cherry picked from commit 679896ec6e
)
This commit is contained in:
parent
e37a9e015e
commit
3c6f7a3e9e
3 changed files with 50 additions and 14 deletions
|
@ -53,24 +53,30 @@ public class BuildConsolePartitionerEditDataTest {
|
|||
assertThat(update0.getNewContents(), is(""));
|
||||
assertThat(update0.getStreamsNeedingNotifcation(), is(empty()));
|
||||
assertThat(update0.needsClearDocumentMarkerManager(), is(true));
|
||||
assertThat(update0.getOffset(), is(0L));
|
||||
|
||||
data.append("Line of text\n", stream1, null);
|
||||
UpdateUIData update1 = data.getUpdate();
|
||||
assertThat(update1.getNewContents(), is("Line of text\n"));
|
||||
assertThat(update1.getStreamsNeedingNotifcation(), is(Arrays.asList(stream1)));
|
||||
assertThat(update1.needsClearDocumentMarkerManager(), is(false));
|
||||
assertThat(update1.getOffset(), is(0L));
|
||||
|
||||
data.append("Another line of text\n", stream2, null);
|
||||
UpdateUIData update2 = data.getUpdate();
|
||||
assertThat(update2.getNewContents(), is("Line of text\nAnother line of text\n"));
|
||||
assertThat(update2.getStreamsNeedingNotifcation(), is(Arrays.asList(stream2)));
|
||||
assertThat(update2.needsClearDocumentMarkerManager(), is(false));
|
||||
assertThat(update2.getOffset(), is(0L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverflow() {
|
||||
StringBuilder all = new StringBuilder();
|
||||
for (int i = 0; i < DEFAULT_MAX_LINES * 4; i++) {
|
||||
data.append("Line " + i + "\n", stream1, null);
|
||||
String text = "Line " + i + "\n";
|
||||
data.append(text, stream1, null);
|
||||
all.append(text);
|
||||
}
|
||||
|
||||
UpdateUIData update = data.getUpdate();
|
||||
|
@ -86,6 +92,9 @@ public class BuildConsolePartitionerEditDataTest {
|
|||
assertThat(contents, endsWith("Line " + lastLine + "\n"));
|
||||
int firstLine = lastLine - newlines + 1;
|
||||
assertThat(contents, startsWith("Line " + firstLine + "\n"));
|
||||
|
||||
long expectedOffset = all.indexOf(contents);
|
||||
assertThat(update.getOffset(), is(expectedOffset));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.eclipse.core.filesystem.EFS;
|
|||
import org.eclipse.core.filesystem.IFileStore;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.DocumentEvent;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IDocumentPartitioner;
|
||||
|
@ -104,6 +105,8 @@ public class BuildConsolePartitioner
|
|||
|
||||
private int fUpdateDelay = BuildConsolePreferencePage.DEFAULT_BUILDCONSOLE_UPDATE_DELAY_MS;
|
||||
|
||||
private long fOffset;
|
||||
|
||||
/**
|
||||
* Construct a partitioner that is not associated with a specific project
|
||||
*/
|
||||
|
@ -251,19 +254,23 @@ public class BuildConsolePartitioner
|
|||
fDocumentMarkerManager.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
* This call is slow, it updates the UI as a side effect.
|
||||
*
|
||||
* XXX: Doing a set on the whole document means that all the line
|
||||
* numbers need to be recalculated. This can be optimized further by
|
||||
* keeping track of what needs to be edited. However, for now this
|
||||
* optimization has not been done because although this leads to
|
||||
* increased CPU usage, it does not lead to a delay in total processing
|
||||
* time, but rather to a decrease in frame rate. Furthermore, if the
|
||||
* document overflows, the document's line numbers need to be
|
||||
* recalculated anyway, so little benefit.
|
||||
*/
|
||||
fDocument.set(update.getNewContents());
|
||||
try {
|
||||
long offsetChangeSinceLastUpdate = update.getOffset() - fOffset;
|
||||
int toTrim = (int) Math.min(offsetChangeSinceLastUpdate, fDocument.getLength());
|
||||
|
||||
int length = fDocument.getLength();
|
||||
String newContents = update.getNewContents();
|
||||
String appendContents = newContents.substring(length - toTrim);
|
||||
// The append has to be done before the delete from head
|
||||
// to avoid document becoming 0 length and therefore the
|
||||
// listeners assume the document has been cleared
|
||||
fDocument.replace(length + toTrim, 0, appendContents);
|
||||
fDocument.replace(0, toTrim, ""); //$NON-NLS-1$
|
||||
} catch (BadLocationException e) {
|
||||
fDocument.set(update.getNewContents());
|
||||
}
|
||||
|
||||
fOffset = update.getOffset();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,6 +36,11 @@ public class BuildConsolePartitionerEditData {
|
|||
*/
|
||||
boolean needsClearDocumentMarkerManager();
|
||||
|
||||
/**
|
||||
* The content's offset since beginning of time.
|
||||
*/
|
||||
long getOffset();
|
||||
|
||||
/**
|
||||
* New contents for the build console.
|
||||
*/
|
||||
|
@ -70,6 +75,11 @@ public class BuildConsolePartitionerEditData {
|
|||
*/
|
||||
private boolean fClearDocumentMarkerManager = false;
|
||||
|
||||
/**
|
||||
* Offset of the start of the document since the beginning of time.
|
||||
*/
|
||||
private long fOffset = 0;
|
||||
|
||||
/**
|
||||
* Editable document, all modifications are made to this copy of the
|
||||
* document, then the UI thread occasionally gets these updates
|
||||
|
@ -86,6 +96,7 @@ public class BuildConsolePartitionerEditData {
|
|||
*/
|
||||
private Set<IBuildConsoleStreamDecorator> fEditStreams = new HashSet<>();
|
||||
|
||||
|
||||
public BuildConsolePartitionerEditData(int maxLines) {
|
||||
fMaxLines = maxLines;
|
||||
}
|
||||
|
@ -105,6 +116,7 @@ public class BuildConsolePartitionerEditData {
|
|||
synchronized (this) {
|
||||
fEditPartitions.clear();
|
||||
fClearDocumentMarkerManager = true;
|
||||
fOffset += fEditStringBuilder.length();
|
||||
fEditStringBuilder.setLength(0);
|
||||
fEditLineCount = 0;
|
||||
}
|
||||
|
@ -239,6 +251,7 @@ public class BuildConsolePartitionerEditData {
|
|||
fEditPartitions = newParitions;
|
||||
fClearDocumentMarkerManager = true;
|
||||
|
||||
fOffset += offsetToOffset;
|
||||
fEditStringBuilder.delete(0, offsetToOffset);
|
||||
fEditLineCount = newNewlineCount;
|
||||
|
||||
|
@ -287,11 +300,13 @@ public class BuildConsolePartitionerEditData {
|
|||
*/
|
||||
public UpdateUIData getUpdate() {
|
||||
boolean clearDocumentMarkerManager;
|
||||
long newOffset;
|
||||
String newConents;
|
||||
List<ITypedRegion> newPartitions;
|
||||
List<IBuildConsoleStreamDecorator> streamsNeedingNotifcation;
|
||||
|
||||
synchronized (this) {
|
||||
newOffset = fOffset;
|
||||
newConents = fEditStringBuilder.toString();
|
||||
newPartitions = new ArrayList<>(fEditPartitions);
|
||||
clearDocumentMarkerManager = fClearDocumentMarkerManager;
|
||||
|
@ -321,6 +336,11 @@ public class BuildConsolePartitionerEditData {
|
|||
public String getNewContents() {
|
||||
return newConents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getOffset() {
|
||||
return newOffset;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue