lru-cache
Advanced tools
Comparing version 2.5.2 to 2.6.0
@@ -89,7 +89,9 @@ ;(function () { // closure for web browsers | ||
thisp = thisp || this | ||
var i = 0; | ||
for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) { | ||
var i = 0 | ||
var itemCount = this._itemCount | ||
for (var k = this._mru - 1; k >= 0 && i < itemCount; k--) if (this._lruList[k]) { | ||
i++ | ||
var hit = this._lruList[k] | ||
if (this._maxAge && (Date.now() - hit.now > this._maxAge)) { | ||
if (isStale(this, hit)) { | ||
del(this, hit) | ||
@@ -149,7 +151,9 @@ if (!this._allowStale) hit = undefined | ||
LRUCache.prototype.set = function (key, value) { | ||
LRUCache.prototype.set = function (key, value, maxAge) { | ||
if (hOP(this._cache, key)) { | ||
// dispose of the old one before overwriting | ||
if (this._dispose) this._dispose(key, this._cache[key].value) | ||
if (this._maxAge) this._cache[key].now = Date.now() | ||
if (maxAge || this._maxAge) this._cache[key].now = Date.now() | ||
delete this._cache[key]['maxAge'] | ||
if (maxAge) this._cache[key].maxAge = maxAge | ||
this._cache[key].value = value | ||
@@ -161,4 +165,5 @@ this.get(key) | ||
var len = this._lengthCalculator(value) | ||
var age = this._maxAge ? Date.now() : 0 | ||
var hit = new Entry(key, value, this._mru++, len, age) | ||
var now = (maxAge || this._maxAge) ? Date.now() : 0 | ||
var maxAge = maxAge || this._maxAge | ||
var hit = new Entry(key, value, this._mru++, len, now, maxAge) | ||
@@ -182,3 +187,3 @@ // oversized objects fall out of cache automatically. | ||
var hit = this._cache[key] | ||
if (this._maxAge && (Date.now() - hit.now > this._maxAge)) { | ||
if (isStale(this, hit)) { | ||
return false | ||
@@ -210,3 +215,3 @@ } | ||
if (hit) { | ||
if (self._maxAge && (Date.now() - hit.now > self._maxAge)) { | ||
if (isStale(self, hit)) { | ||
del(self, hit) | ||
@@ -222,2 +227,14 @@ if (!self._allowStale) hit = undefined | ||
function isStale(self, hit) { | ||
if (!hit || (!hit.maxAge && !self._maxAge)) return false | ||
var stale = false; | ||
var diff = Date.now() - hit.now | ||
if (hit.maxAge) { | ||
stale = diff > hit.maxAge | ||
} else { | ||
stale = self._maxAge && (diff > self._maxAge) | ||
} | ||
return stale; | ||
} | ||
function use (self, hit) { | ||
@@ -251,3 +268,3 @@ shiftLU(self, hit) | ||
// classy, since V8 prefers predictable objects. | ||
function Entry (key, value, lu, length, now) { | ||
function Entry (key, value, lu, length, now, maxAge) { | ||
this.key = key | ||
@@ -258,4 +275,5 @@ this.value = value | ||
this.now = now | ||
if (maxAge) this.maxAge = maxAge | ||
} | ||
})() |
{ | ||
"name": "lru-cache", | ||
"description": "A cache object that deletes the least-recently-used items.", | ||
"version": "2.5.2", | ||
"version": "2.6.0", | ||
"author": "Isaac Z. Schlueter <i@izs.me>", | ||
"keywords": [ | ||
"mru", | ||
"lru", | ||
"cache" | ||
], | ||
"scripts": { | ||
@@ -7,0 +12,0 @@ "test": "tap test --gc" |
@@ -57,7 +57,8 @@ # lru cache | ||
* `set(key, value)` | ||
* `set(key, value, max)` | ||
* `get(key) => value` | ||
Both of these will update the "recently used"-ness of the key. | ||
They do what you think. | ||
They do what you think. `max` is optional and overrides the | ||
cache `max` option if provided. | ||
@@ -99,1 +100,12 @@ * `peek(key)` | ||
Return an array of the values in the cache. | ||
* `length()` | ||
Return total length of objects in cache taking into account | ||
`length` options function. | ||
* `itemCount()` | ||
Return total quantity of objects currently in cache. Note, that | ||
`stale` (see options) items are returned as part of this item | ||
count. |
@@ -231,2 +231,28 @@ var test = require("tap").test | ||
test("individual item can have it's own maxAge", function(t) { | ||
var cache = new LRU({ | ||
max: 5, | ||
maxAge: 50 | ||
}) | ||
cache.set("a", "A", 20) | ||
setTimeout(function () { | ||
t.notOk(cache.get("a")) | ||
t.end() | ||
}, 25) | ||
}) | ||
test("individual item can have it's own maxAge > cache's", function(t) { | ||
var cache = new LRU({ | ||
max: 5, | ||
maxAge: 20 | ||
}) | ||
cache.set("a", "A", 50) | ||
setTimeout(function () { | ||
t.equal(cache.get("a"), "A") | ||
t.end() | ||
}, 25) | ||
}) | ||
test("disposal function", function(t) { | ||
@@ -233,0 +259,0 @@ var disposed = false |
@@ -31,2 +31,3 @@ var test = require('tap').test | ||
}) | ||
t.equal(i, order.length); | ||
@@ -54,1 +55,69 @@ t.end() | ||
}) | ||
test('all entries are iterated over', function(t) { | ||
var l = new LRU(5) | ||
for (var i = 0; i < 10; i ++) { | ||
l.set(i.toString(), i.toString(2)) | ||
} | ||
var i = 0 | ||
l.forEach(function (val, key, cache) { | ||
if (i > 0) { | ||
cache.del(key) | ||
} | ||
i += 1 | ||
}) | ||
t.equal(i, 5) | ||
t.equal(l.keys().length, 1) | ||
t.end() | ||
}) | ||
test('all stale entries are removed', function(t) { | ||
var l = new LRU({ max: 5, maxAge: -5, stale: true }) | ||
for (var i = 0; i < 10; i ++) { | ||
l.set(i.toString(), i.toString(2)) | ||
} | ||
var i = 0 | ||
l.forEach(function () { | ||
i += 1 | ||
}) | ||
t.equal(i, 5) | ||
t.equal(l.keys().length, 0) | ||
t.end() | ||
}) | ||
test('expires', function (t) { | ||
var l = new LRU({ | ||
max: 10, | ||
maxAge: 50 | ||
}) | ||
for (var i = 0; i < 10; i++) { | ||
l.set(i.toString(), i.toString(2), ((i % 2) ? 25 : undefined)) | ||
} | ||
var i = 0 | ||
var order = [ 8, 6, 4, 2, 0 ] | ||
setTimeout(function () { | ||
l.forEach(function (val, key, cache) { | ||
var j = order[i++] | ||
t.equal(cache, l) | ||
t.equal(key, j.toString()) | ||
t.equal(val, j.toString(2)) | ||
}) | ||
t.equal(i, order.length); | ||
t.end() | ||
setTimeout(function () { | ||
var count = 0; | ||
l.forEach(function (val, key, cache) { count++; }) | ||
t.equal(0, count); | ||
t.end() | ||
}, 25) | ||
}, 26) | ||
}) |
24538
726
110
10