Use a cache to speed up doc->screen and screen->doc mapping on very long document.

This commit is contained in:
Julian Viereck 2011-04-29 13:38:59 +02:00
commit a3496dfad1
4 changed files with 45 additions and 8 deletions

View file

@ -85,7 +85,7 @@ exports.launch = function(env) {
// Make the lorem ipsum text a little bit longer.
var loreIpsum = document.getElementById("plaintext").innerHTML;
for (var i = 0; i < 5; i++) {
for (var i = 0; i < 11; i++) {
loreIpsum += loreIpsum;
}
docs.plain = new EditSession(loreIpsum);

View file

@ -92,6 +92,7 @@ var EditSession = function(text, mode) {
doc.on("change", this.onChange.bind(this));
doc.on("changeStart", this.onChangeStart.bind(this));
doc.on("changeEnd", this.onChangeEnd.bind(this));
this.on("changeFold", this.onChangeFold.bind(this));
};
this.getDocument = function() {
@ -99,13 +100,11 @@ var EditSession = function(text, mode) {
};
this.onChangeStart = function() {
console.log(">>> onChangeStart", this.$docChangeCounter);
this.$docChangeCounter ++;
};
this.onChangeEnd = function() {
this.$docChangeCounter --;
console.log("<<< onChangeEnd", this.$docChangeCounter);
if (this.$docChangeCounter == 0
&& !this.$fromUndo && this.$undoManager)
{
@ -127,24 +126,36 @@ var EditSession = function(text, mode) {
}
};
this.onChangeFold = function(e) {
var fold = e.data;
if (this.$cacheRowData
&& fold.start.row < this.$cacheRowData.docRow)
{
this.$cacheRowData = null;
}
};
this.onChange = function(e) {
var delta = e.data;
this.$modified = true;
if (this.$cacheRowData
&& delta.range.start.row < this.$cacheRowData.docRow)
{
this.$cacheRowData = null;
}
var removedFolds = this.$updateInternalDataOnChange(e);
if (!this.$fromUndo && this.$undoManager && !delta.ignore) {
console.log("onChange", JSON.stringify(delta));
this.$deltasDoc.push(delta);
if (removedFolds && removedFolds.length != 0) {
this.$deltasFold.push({
action: "removeFolds",
folds: removedFolds
});
console.log("onChangeFold", removedFolds[0].toString());
}
}
this.bgTokenizer.start(delta.range.start.row);
this._dispatchEvent("change", e);
};
@ -154,6 +165,7 @@ var EditSession = function(text, mode) {
this.$deltas = [];
this.$deltasDoc = [];
this.$deltasFold = [];
this.$cacheRowData = null;
this.getUndoManager().reset();
};
@ -1361,6 +1373,17 @@ var EditSession = function(text, mode) {
return this.screenToDocumentPosition(screenRow, screenColumn).column;
};
this.setCacheRow = function(docRow) {
// Don't update the cache if the docRow stayed the same.
if (this.$cacheRowData && this.$cacheRowData.docRow == docRow) {
return;
}
this.$cacheRowData = {
docRow: docRow,
screenRow: this.documentToScreenRow(docRow, 0)
}
}
this.screenToDocumentPosition = function(screenRow, screenColumn) {
var line;
var docRow = 0;
@ -1373,6 +1396,12 @@ var EditSession = function(text, mode) {
var splits = null;
var split = 0;
var cacheRowData = this.$cacheRowData;
if (cacheRowData && cacheRowData.screenRow < screenRow) {
row = cacheRowData.screenRow ;
docRow = cacheRowData.docRow;
}
while (row <= screenRow) {
rowLength = this.getRowLength(docRow);
if (row + rowLength - 1 >= screenRow) {
@ -1457,6 +1486,12 @@ var EditSession = function(text, mode) {
}
var rowEnd, row = 0;
var cacheRowData = this.$cacheRowData;
if (cacheRowData && cacheRowData.docRow < docRow) {
row = cacheRowData.docRow ;
screenRow = cacheRowData.screenRow// + this.getRowLength(row);;
}
while (row < docRow) {
rowEnd = this.getRowFoldEnd(row);
if (rowEnd >= docRow) {

View file

@ -329,7 +329,7 @@ function Folding() {
// Notify that fold data has changed.
this.$modified = true;
this._dispatchEvent("changeFold");
this._dispatchEvent("changeFold", { data: fold });
return fold;
};
@ -387,7 +387,7 @@ function Folding() {
// Notify that fold data has changed.
this.$modified = true;
this._dispatchEvent("changeFold");
this._dispatchEvent("changeFold", { data: fold });
}
this.removeFolds = function(folds) {

View file

@ -479,6 +479,8 @@ var VirtualRenderer = function(container, theme) {
var lineHeight = { lineHeight: this.lineHeight };
firstRow = session.screenToDocumentRow(firstRow, 0);
session.setCacheRow(firstRow);
// Check if firstRow is inside of a foldLine. If true, then use the first
// row of the foldLine.
var foldLine = session.getFoldLine(firstRow);