Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions lib/simple_lru.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
* LRU cache based on a double linked list
*/

function ListElement(before,next,key,value){
function ListElement(before,next,time,key,value){
this.before = before
this.next = next
this.key = key
this.value = value
this.time = time
}

ListElement.prototype.setKey = function(key){
Expand All @@ -19,11 +20,11 @@ ListElement.prototype.setValue = function(value){
this.value = value
}


function Cache(options){
if(!options)
options = {}
this.maxSize = options.maxSize
this.maxTime = options.maxTime
this.reset()
}

Expand All @@ -43,10 +44,12 @@ Cache.prototype.get = function(key,hit){
* it to the head of linked list
*/
hit = hit != undefined && hit != null ? hit : true;
if(cacheVal && hit)

if(cacheVal && hit && (!cacheVal.time || (Date.now() - cacheVal.time) < this.maxTime))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need to delete this.cache[key] if it's expired to keep the cache clean.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did that at first, but probably you will set it with an updated item right after the get function return undefined.

And there still gonna be expired item in the cache that we haven't checked.

So I think it's a little bit better to leave it there and it might be pushed out if it isn't used.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we need to test to update the cacheValue, think there is a bug there. Not setting a new timestamp :-)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point

this.hit(cacheVal)
else
else
return undefined

return cacheVal.value
}

Expand All @@ -61,7 +64,11 @@ Cache.prototype.set = function(key,val,hit){

if(actual){
actual.value = val
if(hit) this.hit(actual)
if(hit)
{
this.hit(actual)
actual.time = this.maxTime ? Date.now() : undefined
}
}else{
var cacheVal
if(this.size >= this.maxSize){
Expand All @@ -85,7 +92,7 @@ Cache.prototype.set = function(key,val,hit){
cacheVal.setValue(val)
}

cacheVal = cacheVal ? cacheVal : new ListElement(undefined,undefined,key,val)
cacheVal = cacheVal ? cacheVal : new ListElement(undefined,undefined, this.maxTime ? Date.now() : undefined, key, val)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to bump time here on hit: https://github.com/geisbruch/node-simple-lru-cache/pull/3/files#diff-df5bb34be0e9c31fb31e3b40e91f8793R67

This should do it

if(hit) {
 this.hit(actual);
 actual.time = this.maxTime ? Date.now() : undefined
}

this.cache[key] = cacheVal
this.attach(cacheVal)
}
Expand Down
37 changes: 37 additions & 0 deletions test/simple_lru_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,41 @@ describe("BigCache Config",function(){
for(var i = 0; i < 100; i++)
cache.get(i).should.equal("value_"+i+"_modif")
})

it("Should not return timeout item", function(done){
var cache = new SimpleCache({maxSize:1, maxTime: 1})
cache.set("hello", "world")
setTimeout(function()
{
should.equal(cache.get("hello"), undefined);
done();
}, 10);
})

it("Should return timeout item", function(done){
var cache = new SimpleCache({maxSize:1, maxTime:100})
cache.set("hello", "world")
setTimeout(function()
{
should.equal(cache.get("hello"), "world")
done();
}, 10);
})

it("Should set timestamp when you use Cache.set", function(done){
var cache = new SimpleCache({maxSize:1, maxTime:100})
cache.set("hello", "world")
setTimeout(function()
{
should.equal(cache.get("hello"), "world")
cache.set("hello", "world again")
setTimeout(function()
{
should.equal(cache.get("hello"), "world again");
done();
}, 75);
}, 75);
})


})