您的位置:首页 > Web前端 > JavaScript

js实现的一个lru缓存

2015-08-11 23:23 721 查看
把angularjs里面的一个lru缓存给拿出来了,完全照搬的

function CacheFactory(cacheId, option){
var caches = {};

if(caches[cacheId]){
return caches[cacheId];
}

function Cache(cachedId , options){
var size = 0,
stats = extend({}, options),
data = {},
capacity = (options && options.capacity) || Number.MAX_VALUE,
lruHash = {},
freshEnd = null,//最近使用的元素
staleEnd = null;//未使用时间最长的元素

return {
/**
* 往缓存中添加一个元素
* 将最近使用的元素置为新增元素
* @param key
* @param value
* @returns {*}
*/
put : function(key, value){
var lruEntry = lruHash[key] || (lruHash[key] = {key:key});
refresh(lruEntry);

if(!(key in data)){
size++;
}
data[key] = value;
if(size > capacity){
this.remove(staleEnd.key);
}
return value;
},

/**
* 获取key指定值的value
* 将最近使用的置置为该值
* @param key
* @returns {*}
*/
get : function(key){
var lruEntry = lruHash[key];
if(!lruEntry){
return;
}
refresh(lruEntry);
return data[key];
},

remove : function(key){
var lruEntry = lruHash[key];
if(!lruEntry){
return;
}
if(lruEntry == freshEnd){
freshEnd = lruEntry.p;
}

if(lruEntry == staleEnd){
staleEnd = staleEnd.n;
}

link(lruEntry.n, lruEntry.p);
delete lruHash[key];
delete data[key];
size--;
},
removeAll:function(){
data = {};
size = 0;
lruHash = {};
freshEnd = staleEnd = null;
},
destroy: function() {
data = null;
stats = null;
lruHash = null;
delete caches[cacheId];
},
info:function(){
return extend({}, stats, {size:size});
}
}

function refresh(entry){
if(entry != freshEnd){
if(!staleEnd){
staleEnd = entry;
}else if(staleEnd == entry){
staleEnd = staleEnd.n;
}
link(entry.n, entry.p);
link(entry, freshEnd);
}
}

function link(nextEntry, prevEntry){
if(nextEntry != prevEntry){
if(nextEntry){
nextEntry.p = prevEntry;
}
if(prevEntry){
prevEntry.n = nextEntry;
}
}
}
}

caches[cacheId] = Cache(Cache, option);

CacheFactory.info = function(){
var info = {};
forEach(caches, function(cache, cacheId){
info[cacheId] = cache.info();
});
return info;
};

return caches[cacheId];
}
var slice = [].slice;
var toString = Object.prototype.toString();
var getPrototypeOf = Object.getPrototypeOf;

function isArrayLike(obj){
if(obj == null || isWindow(obj)){
return false;
}

var length = 'length' in Object(obj) && obj.length;
if(obj.nodeType === NODE_TYPE_ELEMENT && length){
return true;
}

return isString(obj) || isArray(obj) || length === 0 || typeof length === 'number' && length > 0 && (length - 1) in obj;
}

function isWindow(obj){
return obj && obj.window === obj;
}

function isBlankObject(value){
return value !== null && typeof value === 'object' && !getPrototypeOf(value);
}

function forEach(obj, iterator, context){
var key, length;
if(obj){
if(isFunction(obj)){
for(key in obj){
if(key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))){
iterator.call(context, obj[key], key, obj);
}
}
}else if(isArray(obj) || isArrayLike(obj)){
var isPrimitive = typeof obj != 'object';
for(key = 0, length = obj.length; key < length; key++){
if(isPrimitive || key in obj){
iterator.call(context, obj[key], key, obj);
}
}
}else if(obj.forEach && obj.forEach !== forEach){
obj.forEach(iterator, context, obj);
}else if(isBlankObject(obj)){
for(key in obj){
iterator.call(context, obj[key], key, obj);
}
}else if(typeof obj.hasOwnProperty === 'function'){
for(key in obj){
iterator.call(context, obj[key], key, obj);
}
}else{
for(key in obj){
if(hasOwnProperty.call(obj, key)){
iterator.call(context, obj[key], key, obj);
}
}
}
}
return obj;
}

function extend(dst){
var objs = slice.call(arguments, 1);
for(var i = 0, ii = objs.length; i < ii; ++i){
var obj = objs[i];
if(!isObject(obj) && !isFunction(obj)) continue;
var keys = Object.keys(obj);
for(var j = 0, jj = keys.length; j < jj; j++){
var key = keys[j];
var src = obj[key];

if(isObject(src)){
if(isDate(src)){
dst[key] = new Date(src.valueOf());
}else if(isRegExp(src)){
dst[key] = new RegExp(src);
}else{
if(!isObject(dst[key])){
dst[key] = isArray(src) ? [] : {};
}
extend(dst[key], [src]);
}
}else{
dst[key] = src;
}
}
}

}

var isArray = Array.isArray;

function isRegExp(value){
return toString.call(value) === '[object RegExp]';
}

function isDate(value){
return toString.call(value) === '[object Date]';
}

function isObject(value){
return value !== null && typeof value === 'object';
}

function isFunction(value){
return typeof value === 'function';
}

var cache1 = CacheFactory("test1",{capacity:2});
cache1.put("key1", "value1");
cache1.put("key2", "value2");
cache1.put("key3", "value3");
alert(cache1.get("key1") + "--" + cache1.get("key2") + "--" + cache1.get("key3"));
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: