Created
February 3, 2015 00:59
-
-
Save proudlygeek/31dc8425ccb356824717 to your computer and use it in GitHub Desktop.
LRU Cache Implementation
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
/** | |
* LRU Cache | |
* | |
* http://www.codewars.com/kata/53b406e67040e51e17000c0a | |
* | |
*/ | |
function LRUCache(capacity, init) { | |
var data = init || {}; | |
var timestamps = {}; | |
var capacity = capacity; | |
var getTimestamp = function() { | |
var time = Date.now(); | |
while(time === Date.now()); | |
return Date.now(); | |
}; | |
var findLRU = function() { | |
var keys = Object.keys(timestamps); | |
return keys | |
.reduce(function(acc, x) { | |
if (timestamps[x] < acc.time) { | |
return {key: x, time: timestamps[x]} ; | |
} else { return acc;} | |
}, {key: keys[0], time: timestamps[keys[0]] }); | |
}; | |
var cache = function(key, val) { | |
if (!key) return data; | |
if (key && val) { | |
setCache(key, val); | |
} | |
if (this.size > this.capacity) { | |
var lruItem = findLRU(); | |
deleteCache(lruItem.key); | |
} | |
return this; | |
}.bind(this); | |
var setCache = function(key, value) { | |
if (!this[key]) { | |
Object.defineProperty(this, key, { | |
get: function() { return data[key]; }, | |
set: function(value) { data[key] = value; timestamps[key] = getTimestamp(); }, | |
enumerable: true, | |
configurable: true | |
}); | |
} | |
this[key] = value; | |
}.bind(this); | |
var deleteCache = function(key) { | |
if (typeof this[key] === 'function' || key === 'capacity' || key === 'size') { | |
return false; | |
} | |
if (typeof data[key] !== 'undefined' && data[key]) { | |
delete data[key]; | |
delete this[key]; | |
} | |
if (typeof timestamps[key] !== 'undefined') { | |
delete timestamps[key]; | |
} | |
return true; | |
}.bind(this); | |
Object.defineProperty(this, 'size', { | |
get: function() { | |
return Object.keys(data).length; | |
} | |
}); | |
Object.defineProperty(this, 'cache', { | |
value: cache, | |
enumerable: false, | |
writable: false, | |
configurable: false | |
}); | |
Object.defineProperty(this, 'delete', { | |
value: function(key) { return deleteCache(key); }, | |
enumerable: false, | |
writable: false, | |
configurable: false | |
}); | |
Object.defineProperty(this, 'capacity', { | |
get: function() { return capacity; }, | |
set: function(value) { | |
for (var i = 0; i < (this.size - value); i++) { | |
var lruItem = findLRU(); | |
deleteCache(lruItem.key); | |
} | |
} | |
}); | |
for (key in init) { | |
setCache(key, init[key]); | |
} | |
} |
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 store = new LRUCache(3, {a: 1}); | |
Test.assertEquals(store.size, 1, 'store.size'); | |
Test.assertEquals(store.capacity, 3, 'store.capacity'); | |
Test.assertEquals(store.a, 1, 'store.a'); | |
Test.assertEquals(store.cache('b', 2)['b'], 2, 'store.b'); | |
store.a = 5; | |
Test.assertEquals(store.a, 5, 'store.a'); | |
store.cache('c', 3).cache('d', 4); | |
Test.assertEquals(store.b, undefined, 'store.b'); | |
Test.assertEquals(store.c, 3, 'store.c'); | |
Test.assertEquals(store.d, 4, 'store.d'); | |
Test.assertEquals(store.a, 5, 'store.a'); | |
Test.assertEquals(store.size, 3, 'store.size'); | |
Test.assertEquals(store.delete('delete'), false, "store.delete('delete')"); | |
Test.assertEquals(store.delete('d'), true, "store.delete('d')"); | |
Test.assertEquals(store.d, undefined, 'store.d'); | |
Test.assertEquals(store.delete('e'), true, "store.delete('e')"); | |
Test.assertEquals(store.size, 2, 'store.size'); | |
store.cache('c', 4); | |
Test.assertEquals(store.c, 4, 'store.c'); | |
store.capacity = 1; | |
Test.assertEquals(Object.keys(store).length, 1, "Object.keys(store).length"); | |
Test.assertEquals(Object.keys(store)[0], 'c', "Object.keys(store).length"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment