From af13eb544b2b119453368a328ffb8b95f4956568 Mon Sep 17 00:00:00 2001 From: Julian Viereck Date: Fri, 29 Apr 2011 14:31:19 +0200 Subject: [PATCH] Use a rowCache that does auto chaing every 1000 lines --- demo/demo.js | 2 +- lib/ace/edit_session.js | 90 ++++++++++++++++++++++++------------- lib/ace/virtual_renderer.js | 2 - 3 files changed, 60 insertions(+), 34 deletions(-) diff --git a/demo/demo.js b/demo/demo.js index 6ea4406f..8d57481e 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -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 < 11; i++) { + for (var i = 0; i < 5; i++) { loreIpsum += loreIpsum; } docs.plain = new EditSession(loreIpsum); diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index 1c55049b..1b853c71 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -55,6 +55,8 @@ var EditSession = function(text, mode) { this.$frontMarkers = {}; this.$backMarkers = {}; this.$markerId = 1; + this.$rowCache = []; + this.$rowCacheSize = 1000; this.$wrapData = []; this.$foldData = []; this.$foldData.toString = function() { @@ -103,6 +105,20 @@ var EditSession = function(text, mode) { this.$docChangeCounter ++; }; + this.$resetRowCache = function(row) { + var rowCache = this.$rowCache; + if (row == 0) { + rowCache = []; + return; + } + for (var i = 0; i < rowCache.length; i++) { + if (rowCache[i].docRow >= row) { + rowCache.splice(i, rowCache.length); + return; + } + } + } + this.onChangeEnd = function() { this.$docChangeCounter --; if (this.$docChangeCounter == 0 @@ -128,22 +144,14 @@ 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.$resetRowCache(fold.start.row); }; this.onChange = function(e) { var delta = e.data; this.$modified = true; - if (this.$cacheRowData - && delta.range.start.row < this.$cacheRowData.docRow) - { - this.$cacheRowData = null; - } + this.$resetRowCache(delta.range.start.row); var removedFolds = this.$updateInternalDataOnChange(e); if (!this.$fromUndo && this.$undoManager && !delta.ignore) { @@ -162,10 +170,10 @@ var EditSession = function(text, mode) { this.setValue = function(text) { this.doc.setValue(text); + this.$resetRowCache(0); this.$deltas = []; this.$deltasDoc = []; this.$deltasFold = []; - this.$cacheRowData = null; this.getUndoManager().reset(); }; @@ -188,6 +196,7 @@ var EditSession = function(text, mode) { this.setUndoManager = function(undoManager) { this.$undoManager = undoManager; + this.$resetRowCache(0); this.$deltas = []; this.$deltasDoc = []; this.$deltasFold = []; @@ -882,6 +891,7 @@ var EditSession = function(text, mode) { if (useWrapMode != this.$useWrapMode) { this.$useWrapMode = useWrapMode; this.$modified = true; + this.$resetRowCache(0); // If wrapMode is activaed, the wrapData array has to be initialized. if (useWrapMode) { @@ -924,6 +934,7 @@ var EditSession = function(text, mode) { this.$modified = true; if (this.$useWrapMode) { this.$updateWrapData(0, this.getLength() - 1); + this.$resetRowCache(0) this._dispatchEvent("changeWrapLimit"); } return true; @@ -1373,17 +1384,6 @@ 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; @@ -1396,13 +1396,26 @@ 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; + var rowCache = this.$rowCache; + var doCache = !rowCache.length; + for (var i = 0; i < rowCache.length; i++) { + if (rowCache[i].screenRow < screenRow) { + row = rowCache[i].screenRow; + docRow = rowCache[i].docRow; + doCache = i == rowCache.length - 1; + } } + var docRowCacheLast = docRow; while (row <= screenRow) { + if (doCache + && docRow - docRowCacheLast > this.$rowCacheSize) { + rowCache.push({ + docRow: docRow, + screenRow: row + }); + docRowCacheLast = docRow; + } rowLength = this.getRowLength(docRow); if (row + rowLength - 1 >= screenRow) { break; @@ -1486,13 +1499,28 @@ 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);; + var rowCache = this.$rowCache; + // + var doCache = !rowCache.length; + for (var i = 0; i < rowCache.length; i++) { + if (rowCache[i].docRow < docRow) { + screenRow = rowCache[i].screenRow; + row = rowCache[i].docRow; + doCache = i == rowCache.length - 1; + } } + var docRowCacheLast = row; while (row < docRow) { + if (doCache + && row - docRowCacheLast > this.$rowCacheSize) { + rowCache.push({ + docRow: row, + screenRow: screenRow + }); + docRowCacheLast = row; + } + rowEnd = this.getRowFoldEnd(row); if (rowEnd >= docRow) { break; @@ -1541,10 +1569,10 @@ var EditSession = function(text, mode) { this.getScreenLength = function() { var length = this.getLength(); + var screenRows = 0; if (!this.$useWrapMode) { screenRows = length; } else { - var screenRows = 0; for (var row = 0; row < this.$wrapData.length; row++) { screenRows += this.$wrapData[row].length + 1; } diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 35b38184..9c813ddc 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -479,8 +479,6 @@ 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);