From 056d654564a996d4f30a14e0fc2240f2545f8ae6 Mon Sep 17 00:00:00 2001 From: Thomas Wilkerling Date: Thu, 22 Mar 2018 13:35:52 +0100 Subject: [PATCH] ADD flexible cache --- flexsearch.js | 70 +++++++++++++++++++++++++++++++++++++++++---- flexsearch.light.js | 18 ++++++------ flexsearch.min.js | 48 +++++++++++++++---------------- package.json | 2 +- test/index.html | 2 +- 5 files changed, 100 insertions(+), 40 deletions(-) diff --git a/flexsearch.js b/flexsearch.js index 42c819a..0dc0aa3 100644 --- a/flexsearch.js +++ b/flexsearch.js @@ -1,5 +1,5 @@ ;/**! - * @preserve FlexSearch v0.2.4 + * @preserve FlexSearch v0.2.41 * Copyright 2017-2018 Thomas Wilkerling * Released under the Apache 2.0 Licence * https://github.com/nextapps-de/flexsearch @@ -1737,27 +1737,87 @@ var SUPPORT_ASYNC = true; var cache = SUPPORT_CACHE ? (function(){ /** @this {Cache} */ - function Cache(){ + function Cache(limit){ - this.cache = {}; + this.reset(); + this.limit = limit || 1000; } /** @this {Cache} */ Cache.prototype.reset = function(){ this.cache = {}; + this.count = {}; + this.index = {}; + this.keys = []; }; /** @this {Cache} */ Cache.prototype.set = function(id, value){ + if(!this.count[id]){ + + var length = this.keys.length; + + if(length === this.limit){ + + length--; + + var last_id = this.keys[length]; + + delete this.cache[last_id]; + delete this.count[last_id]; + delete this.index[last_id]; + } + + this.index[id] = length; + this.keys[length] = id; + this.count[id] = 1; + } + this.cache[id] = value; + + // shift up counter +1 + + this.get(id); }; - /** @this {Cache} */ + /** + * Note: It is a lot better to have the complexity when fetching the cache: + * @this {Cache} + */ Cache.prototype.get = function(id){ - return this.cache[id]; + var cache = this.cache[id]; + + if(cache){ + + var count = ++this.count[id]; + var index = this.index; + var current_index = index[id]; + + if(current_index > 0){ + + var keys = this.keys; + var old_index = current_index; + + while(current_index && this.count[keys[current_index--]] <= count){} + + if(current_index >= 0 && ((current_index + 1) !== old_index)){ + + var tmp = keys[current_index]; + + // TODO splice is too slow + index[id] = current_index; + keys.splice(current_index, 1, id); + + index[tmp] = old_index; + keys.splice(old_index, 1, tmp); + } + } + } + + return cache; }; return Cache; diff --git a/flexsearch.light.js b/flexsearch.light.js index 6ee6e03..1c60bae 100644 --- a/flexsearch.light.js +++ b/flexsearch.light.js @@ -1,5 +1,5 @@ /* - FlexSearch v0.2.4 + FlexSearch v0.2.41 Copyright 2017-2018 Thomas Wilkerling Released under the Apache 2.0 Licence https://github.com/nextapps-de/flexsearch @@ -8,11 +8,11 @@ typeof c){for(c=0;c=g&&(a=a[e+.5|0],a=a[c]||(a[c]=[]),a[a.length]=h)}return e||b[c]}function z(a,b){if(a)for(var c=Object.keys(a),h=0,f=c.length;ha?1:0a?-1:0b&&(c=c.slice(0,b)));return c}var y={encode:"icase",mode:"ngram",cache:!1,async:!1,m:!1,threshold:0,depth:0},A={memory:{encode:"extra",mode:"strict",threshold:7},speed:{encode:"icase",mode:"strict",threshold:7,depth:2},match:{encode:"extra",mode:"full"},score:{encode:"extra",mode:"strict",threshold:5, -depth:4},balance:{encode:"balance",mode:"ngram",threshold:6,depth:3},fastest:{encode:"icase",mode:"strict",threshold:9,depth:1}},v=[],D=0,C=l("[ -/]");d.new=function(a){return new this(a)};d.create=function(a){return d.new(a)};d.addMatcher=function(a){for(var b in a)a.hasOwnProperty(b)&&(v[v.length]=l(b),v[v.length]=a[b]);return this};d.register=function(a,b){w[a]=b;return this};d.encode=function(a,b){return w[a].call(w,b)};d.prototype.init=function(a){this.b=[];if(a){var b=a.profile;b=b?A[b]:{}; -this.mode=a.mode||b.mode||this.mode||y.mode;this.threshold=a.threshold||b.threshold||this.threshold||y.threshold;this.depth=a.depth||b.depth||this.depth||y.depth;this.j=(b=a.encode||b.encode)&&w[b]||("function"===typeof b?b:this.j||!1);(b=a.matcher)&&this.addMatcher(b)}this.g=[{},{},{},{},{},{},{},{},{},{}];this.c={};this.a={};this.f="";this.h=!0;return this};d.prototype.encode=function(a){a&&v.length&&(a=q(a,v));a&&this.b.length&&(a=q(a,this.b));a&&this.j&&(a=this.j.call(w,a));if(a&&this.i){a=a.split(" "); -for(var b=0;bm;l--)u=n.substring(m,l),x(p,f,u,a,b,g);break;default:if(m=x(p,f,n,a,b,g),e&&1=g)for(r=f._ctx[n]||(f._ctx[n]={}),n=this.c[n]||(this.c[n]=[{},{},{},{},{},{},{},{},{},{}]),m=d-e,l=d+e,0>m&&(m=0),l>k-1&&(l=k-1);m<=l;m++)m!== -d&&x(n,r,h[m],a,b,g)}}}this.a[a]="1";this.h=!1}return this};d.prototype.update=function(a,b){this.a[a]&&b&&"string"===typeof b&&(this.remove(a),b&&this.add(a,b,!0));return this};d.prototype.remove=function(a){if(this.a[a]){for(var b=0;10>b;b++)z(this.g[b],a);this.depth&&z(this.c,a);delete this.a[a];this.h=!1}return this};d.prototype.search=function(a,b,c){var h=[];if(a&&"object"===typeof a){c=a.callback||b;b=a.limit;var f=a.threshold;a=a.query}f=(f||this.threshold||0)|0;"function"===typeof b?(c=b, -b=1E3):b||(b=1E3);if(c){var g=this;H(function(){c(g.search(a,b));g=null},1,"search-"+this.id);return null}if(!a||"string"!==typeof a)return h;if(!this.h)this.h=!0;else if(this.f&&0===a.indexOf(this.f))return h;var e=this.encode(a);if(!e.length)return h;var d=this.mode;e="function"===typeof d?d(e):"ngram"===d?B(e):e.split(C);d=e.length;var k=!0,l=[],n={};if(1=f;z--)if(v=(r?m[u]:this.g)[z][t])w[y++]=v,x=!0;if(x)l[l.length]=1m;l--)u=n.substring(m,l),x(p,f,u,a,b,g);break;default:if(m=x(p,f,n,a,b,g),e&&1=g)for(r=f._ctx[n]||(f._ctx[n]={}),n=this.b[n]||(this.b[n]=[{},{},{},{},{},{},{},{},{},{}]),m=d-e,l=d+e+1,0>m&&(m=0),l>k&&(l=k);mb;b++)z(this.f[b],a);this.depth&&z(this.b,a);delete this.a[a];this.g=!1}return this};d.prototype.search=function(a,b,c){var h=[];if(a&&"object"===typeof a){c=a.callback||b;b=a.limit;var f=a.threshold;a=a.query}f=(f||this.threshold||0)|0;"function"===typeof b?(c=b,b=1E3):b||(b=1E3); +if(c){var g=this;H(function(){c(g.search(a,b));g=null},1,"search-"+this.id);return null}if(!a||"string"!==typeof a)return h;if(!this.g)this.g=!0;else if(this.c&&0===a.indexOf(this.c))return h;var e=this.encode(a);if(!e.length)return h;var d=this.mode;e="function"===typeof d?d(e):"ngram"===d?B(e):e.split(C);d=e.length;var k=!0,l=[],n={};if(1=f;z--)if(v=(r?m[u]:this.f)[z][t])w[y++]=v,x=!0;if(x)l[l.length]=1=k&&(a=a[f+.5|0],a=a[e]||(a[e]=[]),a[a.length]=c)}return f||b[e]}function m(a,b){if(a)for(var e=Object.keys(a),c=0,l=e.length;ca?1:0a?-1:0b&&(e=e.slice(0,b)));return e}function E(a){a.C||(a.C=I(function(){a.C=null;var b=a.async;b&&(a.async=!1);if(a.f.length){for(var e=J(),c;(c=a.f.shift())||0===c;){var d=a.h[c];switch(d[0]){case C.add:a.add(d[1],d[2]);break; -case C.update:a.update(d[1],d[2]);break;case C.remove:a.remove(d[1])}a.h[c]=null;delete a.h[c];if(100=l&&(a=a[h+.5|0],a=a[d]||(a[d]=[]),a[a.length]=c)}return h||b[d]}function m(a,b){if(a)for(var d=Object.keys(a),c=0,f=d.length;ca?1:0a?-1:0b&&(d=d.slice(0,b)));return d}function E(a){a.C||(a.C=I(function(){a.C=null;var b=a.async;b&&(a.async=!1);if(a.f.length){for(var d=J(),c;(c=a.f.shift())||0===c;){var f=a.h[c];switch(f[0]){case C.add:a.add(f[1],f[2]);break; +case C.update:a.update(f[1],f[2]);break;case C.remove:a.remove(f[1])}a.h[c]=null;delete a.h[c];if(100=d&&(c.o=c.b),c.B&&c.o===c.b&&(c.g.length?c.c="":c.c||(c.c=b),c.cache&&c.j.set(b,c.g),c.B(c.g),c.g=[]))})}this.mode=a.mode||e.mode||this.mode||w.mode;this.cache=a.cache||this.cache||w.cache;this.async=a.async||this.async||w.async;this.b=a.worker||this.b||w.b;this.threshold=a.threshold||e.threshold||this.threshold||w.threshold;this.depth=a.depth||e.depth||this.depth||w.depth;this.w=(b=a.encode||e.encode)&&z[b]||("function"===typeof b?b:this.w||!1);this.F=a.debug|| -this.F;(b=a.matcher)&&this.addMatcher(b);if(b=a.filter)this.A=N(!0===b?T:b,this.w);if(b=a.stemmer)this.D=O(!0===b?H:b,this.w)}this.l=[{},{},{},{},{},{},{},{},{},{}];this.s={};this.a={};this.h={};this.f=[];this.C=null;this.c="";this.v=!0;this.j=this.cache?new U(3E4,50,!0):!1;return this};g.prototype.encode=function(a){a&&A.length&&(a=x(a,A));a&&this.m.length&&(a=x(a,this.m));a&&this.w&&(a=this.w.call(z,a));if(a&&this.A){a=a.split(" ");for(var b=0;b=this.i.length&&(this.u=0),this.i[this.u].postMessage(this.u,{add:!0,id:a,content:b}),this.a[a]=""+this.u,this;if(this.async)return this.h[a]||(this.f[this.f.length]=a),this.h[a]= -[C.add,a,b],E(this),this;b=this.encode(b);if(!b.length)return this;e=this.mode;for(var c="function"===typeof e?e(b):"ngram"===e?G(b):b.split(K),d={_ctx:{}},k=this.threshold,f=this.depth,h=this.l,g=c.length,t=0;tn;m--)v=p.substring(n,m),y(h,d,v,a,b,k);break;default:if(n= -y(h,d,p,a,b,k),f&&1=k)for(u=d._ctx[p]||(d._ctx[p]={}),p=this.s[p]||(this.s[p]=[{},{},{},{},{},{},{},{},{},{}]),n=t-f,m=t+f,0>n&&(n=0),m>g-1&&(m=g-1);n<=m;n++)n!==t&&y(p,u,c[n],a,b,k)}}}this.a[a]="1";this.v=!1}return this};g.prototype.update=function(a,b){this.a[a]&&b&&"string"===typeof b&&(this.remove(a),b&&this.add(a,b,!0));return this};g.prototype.remove=function(a){if(this.a[a]){if(this.b){var b=parseInt(this.a[a],10);this.i[b].postMessage(b,{remove:!0,id:a});delete this.a[a];return this}if(this.async)return this.h[a]|| -(this.f[this.f.length]=a),this.h[a]=[C.remove,a],E(this),this;for(b=0;10>b;b++)m(this.l[b],a);this.depth&&m(this.s,a);delete this.a[a];this.v=!1}return this};g.prototype.search=function(a,b,d){var c=[];if(a&&"object"===typeof a){d=a.callback||b;b=a.limit;var e=a.threshold;a=a.query}e=(e||this.threshold||0)|0;"function"===typeof b?(d=b,b=1E3):b||(b=1E3);if(this.b){this.B=d;this.o=0;this.g=[];for(c=0;c=e;A--)if(x=(u?n[v]:this.l)[A][q])w[z++]=x,y=!0;if(y)t[t.length]=1f;f++)for(b=Object.keys(this.l[f]),a=0;a=f&&(c.m=c.b),c.w&&c.m===c.b&&(c.g.length?c.c="":c.c||(c.c=b),c.cache&&c.j.set(b,c.g),c.w(c.g),c.g=[]))})}this.mode=a.mode||d.mode||this.mode||y.mode;this.cache=a.cache||this.cache||y.cache;this.async=a.async||this.async||y.async;this.b=a.worker||this.b||y.b;this.threshold=a.threshold||d.threshold||this.threshold||y.threshold;this.depth=a.depth||d.depth||this.depth||y.depth;this.v=(b=a.encode||d.encode)&&x[b]||("function"===typeof b?b:this.v||!1);this.F=a.debug|| +this.F;(b=a.matcher)&&this.addMatcher(b);if(b=a.filter)this.A=N(!0===b?T:b,this.v);if(b=a.stemmer)this.D=O(!0===b?H:b,this.v)}this.l=[{},{},{},{},{},{},{},{},{},{}];this.o={};this.a={};this.h={};this.f=[];this.C=null;this.c="";this.u=!0;this.j=this.cache?new U(3E4,50,!0):!1;return this};g.prototype.encode=function(a){a&&A.length&&(a=w(a,A));a&&this.B.length&&(a=w(a,this.B));a&&this.v&&(a=this.v.call(x,a));if(a&&this.A){a=a.split(" ");for(var b=0;b=this.i.length&&(this.s=0),this.i[this.s].postMessage(this.s,{add:!0,id:a,content:b}),this.a[a]=""+this.s,this;if(this.async)return this.h[a]||(this.f[this.f.length]=a),this.h[a]=[C.add,a,b],E(this),this; +b=this.encode(b);if(!b.length)return this;d=this.mode;for(var c="function"===typeof d?d(b):"ngram"===d?G(b):b.split(K),f={_ctx:{}},e=this.threshold,h=this.depth,k=this.l,g=c.length,m=0;mn;z--)v=p.substring(n,z),u(k,f,v,a,b,e);break;default:if(n=u(k,f,p,a,b,e),h&&1< +g&&n>=e)for(r=f._ctx[p]||(f._ctx[p]={}),p=this.o[p]||(this.o[p]=[{},{},{},{},{},{},{},{},{},{}]),n=m-h,z=m+h+1,0>n&&(n=0),z>g&&(z=g);nb;b++)m(this.l[b],a);this.depth&&m(this.o,a);delete this.a[a];this.u=!1}return this};g.prototype.search=function(a,b,d){var c=[];if(a&&"object"===typeof a){d=a.callback||b;b=a.limit;var f=a.threshold;a=a.query}f=(f||this.threshold||0)|0;"function"===typeof b?(d=b,b=1E3):b||(b=1E3);if(this.b){this.w=d;this.m=0;this.g=[];for(c=0;c=f;x--)if(t=(r?n[v]:this.l)[x][q])u[y++]=t,w=!0;if(w)m[m.length]=1h;h++)for(b=Object.keys(this.l[h]),a=0;a - +