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