UNPKG

magix

Version:

view manager framewrok

167 lines (165 loc) 4.65 kB
let Magix_CacheSort = (a, b) => /*#if(modules.cnum){#*/ b.n - a.n || /*#}#*/ b.f - a.f || b.t - a.t; /** * Magix.Cache 类 * @name Cache * @constructor * @param {Integer} [max] 缓存最大值,默认20 * @param {Integer} [buffer] 缓冲区大小,默认5 * @param {Function} [remove] 当缓存的元素被删除时调用 * @example * let c = new Magix.cache(5,2);//创建一个可缓存5个,且缓存区为2个的缓存对象 * c.set('key1',{});//缓存 * c.get('key1');//获取 * c.del('key1');//删除 * c.has('key1');//判断 * //注意:缓存通常配合其它方法使用,在Magix中,对路径的解析等使用了缓存。在使用缓存优化性能时,可以达到节省CPU和内存的双赢效果 */ function G_Cache(max, buffer, remove, me) { me = this; me.c = []; me.b = buffer || 5; //buffer先取整,如果为0则再默认5 me.x = me.b + (max || 20); me.r = remove; } G_Assign(G_Cache[G_PROTOTYPE], { /** * @lends Cache# */ /** * 获取缓存的值 * @param {String} key * @return {Object} 初始设置的缓存对象 */ get(key) { let me = this; let c = me.c; let r = c[G_SPLITER + key]; if (r) { r.f++; r.t = G_COUNTER++; //console.log(r.f); r = r.v; //console.log('hit cache:'+key); } return r; }, /*#if(modules.cnum){#*/ /** * 获取引用值,仅启动cnum模块时该方法才存在 * @param {String} key 缓存key * @param {Boolean} increase 是否是增长 * @beta * @module cnum */ num(key, increase) { let me = this, c = me.c, k = G_SPLITER + key, o; if (increase && !c[k]) { me.set(key, 0); } o = c[k]; if (o) { if (increase) { o.n++; } else if (o.n > 0) { o.n--; } o.f++; } }, /*#}#*/ /*#if(modules.ceach||modules.service){#*/ /** * 循环缓存 * @param {Function} cb 回调 * @param {Object} [ops] 回调时传递的额外参数 * @beta * @module ceach|service */ each(cb, ops, me, c, i) { me = this; c = me.c; for (i of c) { cb(i.v, ops, me); } }, /*#}#*/ /** * 设置缓存 * @param {String} key 缓存的key * @param {Object} value 缓存的对象 */ set(okey, value) { let me = this; let c = me.c; let key = G_SPLITER + okey; let r = c[key]; let t = me.b, f; if (!r) { if (c.length >= me.x) { c.sort(Magix_CacheSort); while (t--) { /*#if(modules.cnum){#*/ r = c[c.length - 1]; //弹出最后一个 if (r.n) { //如果有引用 break; //直接跳出循环 } c.pop(); /*#}else{#*/ r = c.pop(); /*#}#*/ //为什么要判断r.f>0,考虑这样的情况:用户设置a,b,主动删除了a,重新设置a,数组中的a原来指向的对象残留在列表里,当排序删除时,如果不判断则会把新设置的删除,因为key都是a // if (r.f > 0) me.del(r.o); //如果没有引用,则删除 /*#if(modules.cnum){#*/ f = 1; //标记无引用 /*#}#*/ } /*#if(modules.cnum){#*/ if (!f) { //auto increase me.x += me.b; } /*#}#*/ } r = { /*#if(modules.cnum){#*/ n: 0, /*#}#*/ o: okey }; c.push(r); c[key] = r; } r.v = value; r.f = 1; r.t = G_COUNTER++; }, /** * 删除缓存 * @param {String} key 缓存key */ del(k) { k = G_SPLITER + k; let c = this.c; let r = c[k], m = this.r; if (r) { r.f = -1; r.v = G_EMPTY; delete c[k]; if (m) { G_ToTry(m, r.o); } } }, /** * 检测缓存中是否有给定的key * @param {String} key 缓存key * @return {Boolean} */ has(k) { return G_Has(this.c, G_SPLITER + k); } });