lru-cache@2.0.4

This commit is contained in:
isaacs
2012-09-25 08:23:05 -07:00
parent b185df1260
commit d8fb1ea87e
3 changed files with 52 additions and 37 deletions

View File

@@ -1,6 +1,6 @@
;(function () { // closure for web browsers
if (module) {
if (typeof module === 'object' && module.exports) {
module.exports = LRUCache
} else {
// just set the global for non-node platforms.
@@ -21,7 +21,7 @@ function LRUCache (options) {
var max
if (typeof options === 'number') {
max = options
options = {max: max}
options = { max: max }
}
max = options.max
@@ -33,6 +33,7 @@ function LRUCache (options) {
lengthCalculator = naiveLength
}
if (!max || !(typeof max === "number") || max <= 0 ) {
// a little bit silly. maybe this should throw?
max = Infinity
}
@@ -40,9 +41,8 @@ function LRUCache (options) {
var dispose = options.dispose
var cache = {} // hash of items by key
, lruList = {} // list of items in order of use recency
, lru = 0 // least recently used
var cache = Object.create(null) // hash of items by key
, lruList = Object.create(null) // list of items in order of use recency
, mru = 0 // most recently used
, length = 0 // number of items in the list
, itemCount = 0
@@ -67,16 +67,16 @@ function LRUCache (options) {
if (typeof lC !== "function") {
lengthCalculator = naiveLength
length = itemCount
Object.keys(cache).forEach(function (key) {
for (var key in cache) {
cache[key].length = 1
})
}
} else {
lengthCalculator = lC
length = 0
Object.keys(cache).forEach(function (key) {
for (var key in cache) {
cache[key].length = lengthCalculator(cache[key].value)
length += cache[key].length
})
}
}
if (length > max) trim()
@@ -98,13 +98,12 @@ function LRUCache (options) {
this.reset = function () {
if (dispose) {
Object.keys(cache).forEach(function (k) {
for (var k in cache) {
dispose(k, cache[k].value)
})
}
}
cache = {}
lruList = {}
lru = 0
mru = 0
length = 0
itemCount = 0
@@ -126,16 +125,15 @@ function LRUCache (options) {
return true
}
var hit = {
key:key,
value:value,
lu:mru++,
length:lengthCalculator(value),
now: (maxAge) ? Date.now() : 0
}
var len = lengthCalculator(value)
var age = maxAge ? Date.now() : 0
var hit = new Entry(key, value, mru++, len, age)
// oversized objects fall out of cache automatically.
if (hit.length > max) return false
if (hit.length > max) {
if (dispose) dispose(key, value)
return false
}
length += hit.length
lruList[hit.lu] = cache[key] = hit
@@ -153,7 +151,6 @@ function LRUCache (options) {
return
}
delete lruList[hit.lu]
if (hit.lu === lru) lruWalk()
hit.lu = mru ++
lruList[hit.lu] = hit
return hit.value
@@ -165,31 +162,30 @@ function LRUCache (options) {
if (dispose) dispose(key, hit.value)
delete cache[key]
delete lruList[hit.lu]
if (hit.lu === lru) lruWalk()
length -= hit.length
itemCount --
}
function lruWalk () {
// lru has been deleted, hop up to the next hit.
for (var key in lruList) {
return key
}
}
function trim () {
if (length <= max) return
var prune = Object.keys(lruList)
for (var i = 0; i < prune.length && length > max; i ++) {
var hit = lruList[prune[i]]
for (var k in lruList) {
if (length <= max) break;
var hit = lruList[k]
if (dispose) dispose(hit.key, hit.value)
length -= hit.length
delete cache[ hit.key ]
delete lruList[prune[i]]
delete lruList[k]
}
lruWalk()
}
}
// classy, since V8 prefers predictable objects.
function Entry (key, value, mru, len, age) {
this.key = key
this.value = value
this.lu = mru
this.length = len
this.now = age
}
})()

View File

@@ -1,7 +1,7 @@
{
"name": "lru-cache",
"description": "A cache object that deletes the least-recently-used items.",
"version": "2.0.2",
"version": "2.0.4",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me"
@@ -52,6 +52,6 @@
}
],
"readme": "# lru cache\n\nA cache object that deletes the least-recently-used items.\n\n## Usage:\n\n```javascript\nvar LRU = require(\"lru-cache\")\n , options = { max: 500\n , length: function (n) { return n * 2 }\n , dispose: function (key, n) { n.close() }\n , maxAge: 1000 * 60 * 60 }\n , cache = LRU(options)\n , otherCache = LRU(50) // sets just the max size\n\ncache.set(\"key\", \"value\")\ncache.get(\"key\") // \"value\"\n\ncache.reset() // empty the cache\n```\n\nIf you put more stuff in it, then items will fall out.\n\nIf you try to put an oversized thing in it, then it'll fall out right\naway.\n\n## Options\n\n* `max` The maximum number of items. Not setting this is kind of\n silly, since that's the whole purpose of this lib, but it defaults\n to `Infinity`.\n* `maxAge` Maximum age in ms. Items are not pro-actively pruned out\n as they age, but if you try to get an item that is too old, it'll\n drop it and return undefined instead of giving it to you.\n* `length` Function that is used to calculate the length of stored\n items. If you're storing strings or buffers, then you probably want\n to do something like `function(n){return n.length}`. The default is\n `function(n){return 1}`, which is fine if you want to store `n`\n like-sized things.\n* `dispose` Function that is called on items when they are dropped\n from the cache. This can be handy if you want to close file\n descriptors or do other cleanup tasks when items are no longer\n accessible. Called with `key, value`. It's called *before*\n actually removing the item from the internal cache, so if you want\n to immediately put it back in, you'll have to do that in a\n `nextTick` or `setTimeout` callback or it won't do anything.\n",
"_id": "lru-cache@2.0.2",
"_id": "lru-cache@2.0.4",
"_from": "lru-cache@~2.0.0"
}

19
node_modules/lru-cache/test/basic.js generated vendored
View File

@@ -246,3 +246,22 @@ test("disposal function", function(t) {
t.equal(disposed, 3)
t.end()
})
test("disposal function on too big of item", function(t) {
var disposed = false
var cache = new LRU({
max: 1,
length: function (k) {
return k.length
},
dispose: function (k, n) {
disposed = n
}
})
var obj = [ 1, 2 ]
t.equal(disposed, false)
cache.set("obj", obj)
t.equal(disposed, obj)
t.end()
})