Last active
September 25, 2015 22:28
-
-
Save db/995108 to your computer and use it in GitHub Desktop.
LRU cache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Cache = function(pMaxSize) { | |
this.lastID = 0; | |
this.items = {}; | |
this.numItems = 0; | |
var maxSize = parseInt(pMaxSize, 10); | |
if (isNaN(maxSize)) maxSize = -1; | |
this.maxNumItems = maxSize; | |
this.itemDefault = { | |
ttl : 3600, // time to live = 1 hour | |
priority : 2 // 1=low, 2=medium, 3=high | |
}; | |
}; | |
Cache.prototype = { | |
add : function(pKey, pValue, pTtl, pPriority) { | |
if (!pKey || !pValue) return false; | |
var ttl = pTtl || this.itemDefault.ttl, priority = pPriority || this.itemDefault.priority; | |
if (this.items[pKey] !== null) { | |
this.lastID++; | |
this.del(pKey); | |
this.items[pKey] = { | |
id : this.lastID, | |
key : pKey, | |
value : pValue, | |
ttl : ttl * 1000, | |
priority : priority, | |
accessed : new Date().getTime() | |
}; | |
} | |
if (this.maxNumItems > 0 && this.numItems >= this.maxNumItems) this.purge(); | |
this.numItems += 1; | |
return this.items[pKey]; | |
}, | |
get : function(pKey) { | |
var item = this.items[pKey]; | |
var get = null; | |
if (item) { | |
if (!this.isExpired(item)) { | |
item.accessed = new Date().getTime(); | |
get = item.value; | |
} | |
else { | |
this.del(pKey); | |
} | |
} | |
return get; | |
}, | |
del : function(pKey) { | |
if (!pKey) return false; | |
if (this.items[pKey]) { | |
delete this.items[pKey]; | |
this.numItems -= 1; | |
return true; | |
} | |
return false; | |
}, | |
clear : function() { | |
for ( var key in this.items) this.del(key); | |
return true; | |
}, | |
purge : function() { | |
var cacheSize = this.numItems, itemsToKeep = [], item, lastItem; | |
for ( var key in this.items) { | |
item = this.items[key]; | |
if (this.isExpired(item)) { | |
this.del(key); | |
} | |
else { | |
itemsToKeep.push(item); | |
} | |
} | |
if (itemsToKeep.length > this.maxNumItems) { | |
// sort by priority and last accessed time | |
itemsToKeep = itemsToKeep.sort(function(pItemA, pItemB) { | |
// lower priority expires first | |
if (pItemA.priority != pItemB.priority) { | |
return pItemB.priority - pItemA.priority; | |
} | |
// least recently accessed is less important, | |
// it expires first | |
if (pItemA.accessed != pItemB.accessed) { | |
return pItemB.accessed - pItemA.accessed; | |
} | |
// earliest created expires first | |
return pItemB.id - pItemA.id; | |
}); | |
// remove excess | |
while (itemsToKeep.length > this.maxNumItems) { | |
lastItem = itemsToKeep.pop(); | |
this.del(lastItem.key); | |
} | |
} | |
return (this.numItems - cacheSize); | |
}, | |
isExpired : function(pItem) { | |
var now = new Date().getTime(); | |
return (pItem.ttl < (now - pItem.accessed)); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment