Caching results of insertLineNumbers and extractRangeByLineNumbers

This commit is contained in:
Tobias Hößl 2016-10-27 16:49:38 +02:00
parent 4d48f2d8a5
commit 36e519a798
2 changed files with 942 additions and 898 deletions

View File

@ -4,11 +4,16 @@
angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumbering'])
.service('diffService', function (lineNumberingService) {
.service('diffService', [
'lineNumberingService',
'$cacheFactory',
function (lineNumberingService, $cacheFactory) {
var ELEMENT_NODE = 1,
TEXT_NODE = 3,
DOCUMENT_FRAGMENT_NODE = 11;
var diffCache = $cacheFactory('diff.service');
this.TYPE_REPLACEMENT = 0;
this.TYPE_INSERTION = 1;
this.TYPE_DELETION = 2;
@ -322,6 +327,13 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi
*
*/
this.extractRangeByLineNumbers = function(fragment, fromLine, toLine, debug) {
var cacheKey = fromLine + "-" + toLine + "-" + lineNumberingService.djb2hash(fragment),
cached = diffCache.get(cacheKey);
if (!angular.isUndefined(cached)) {
return cached;
}
if (typeof(fragment) == 'string') {
fragment = this.htmlToFragment(fragment);
}
@ -418,7 +430,7 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi
currNode = currNode.parentNode;
}
return {
var ret = {
'html': html,
'ancestor': ancestor,
'outerContextStart': outerContextStart,
@ -430,6 +442,9 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi
'followingHtml': followingHtml,
'followingHtmlStartSnippet': followingHtmlStartSnippet
};
diffCache.put(cacheKey, ret);
return ret;
};
/*
@ -627,7 +642,7 @@ angular.module('OpenSlidesApp.motions.diff', ['OpenSlidesApp.motions.lineNumberi
return this._serializeDom(mergedFragment, true);
};
});
}
]);
}());

View File

@ -14,7 +14,9 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
* No constructs like <a...><div></div></a> are allowed. CSS-attributes like 'display: block' are ignored.
*/
.service('lineNumberingService', function () {
.service('lineNumberingService', [
'$cacheFactory',
function ($cacheFactory) {
var ELEMENT_NODE = 1,
TEXT_NODE = 3;
@ -22,6 +24,17 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
this._currentLineNumber = null;
this._prependLineNumberToFirstText = false;
var lineNumberCache = $cacheFactory('linenumbering.service');
this.djb2hash = function(str) {
var hash = 5381, char;
for (var i = 0; i < str.length; i++) {
char = str.charCodeAt(i);
hash = ((hash << 5) + hash) + char;
}
return hash.toString();
};
this._isInlineElement = function (node) {
var inlineElements = [
'SPAN', 'A', 'EM', 'S', 'B', 'I', 'STRONG', 'U', 'BIG', 'SMALL', 'SUB', 'SUP', 'TT'
@ -361,13 +374,28 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
};
this.insertLineNumbers = function (html, lineLength, highlight, callback, firstLine) {
var newRoot = this.insertLineNumbersNode(html, lineLength, highlight, firstLine);
var newHtml, newRoot;
if (highlight > 0) {
// Caching versions with highlighted line numbers is probably not worth it
newRoot = this.insertLineNumbersNode(html, lineLength, highlight, firstLine);
newHtml = newRoot.innerHTML;
} else {
var cacheKey = this.djb2hash(html);
newHtml = lineNumberCache.get(cacheKey);
if (angular.isUndefined(newHtml)) {
newRoot = this.insertLineNumbersNode(html, lineLength, highlight, firstLine);
newHtml = newRoot.innerHTML;
lineNumberCache.put(cacheKey, newHtml);
}
}
if (callback) {
callback();
}
return newRoot.innerHTML;
return newHtml;
};
this.stripLineNumbers = function (html) {
@ -376,7 +404,8 @@ angular.module('OpenSlidesApp.motions.lineNumbering', [])
this._stripLineNumbers(root);
return root.innerHTML;
};
});
}
]);
}());