Skip to content

Commit

Permalink
lru_cache: support multiple values with the same key
Browse files Browse the repository at this point in the history
  • Loading branch information
ansis committed Apr 2, 2018
1 parent 2534dc0 commit 06ea9c3
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 21 deletions.
41 changes: 21 additions & 20 deletions src/util/lru_cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
class LRUCache<T> {
max: number;
data: {[key: string]: T};
data: {[key: string]: Array<T>};
order: Array<string>;
onRemove: (element: T) => void;
/**
Expand All @@ -30,7 +30,9 @@ class LRUCache<T> {
*/
reset() {
for (const key in this.data) {
this.onRemove(this.data[key]);
for (const removedData of this.data[key]) {
this.onRemove(removedData);
}
}

this.data = {};
Expand All @@ -50,20 +52,15 @@ class LRUCache<T> {
* @private
*/
add(key: string, data: T) {
if (this.data[key] === undefined) {
this.data[key] = [];
}
this.data[key].push(data);
this.order.push(key);

if (this.has(key)) {
this.order.splice(this.order.indexOf(key), 1);
this.data[key] = data;
this.order.push(key);

} else {
this.data[key] = data;
this.order.push(key);

if (this.order.length > this.max) {
const removedData = this.getAndRemove(this.order[0]);
if (removedData) this.onRemove(removedData);
}
if (this.order.length > this.max) {
const removedData = this.getAndRemove(this.order[0]);
if (removedData) this.onRemove(removedData);
}

return this;
Expand Down Expand Up @@ -101,9 +98,11 @@ class LRUCache<T> {
getAndRemove(key: string): ?T {
if (!this.has(key)) { return null; }

const data = this.data[key];
const data = this.data[key].shift();

delete this.data[key];
if (this.data[key].length === 0) {
delete this.data[key];
}
this.order.splice(this.order.indexOf(key), 1);

return data;
Expand All @@ -120,7 +119,7 @@ class LRUCache<T> {
get(key: string): ?T {
if (!this.has(key)) { return null; }

const data = this.data[key];
const data = this.data[key].pop();
return data;
}

Expand All @@ -134,8 +133,10 @@ class LRUCache<T> {
remove(key: string) {
if (!this.has(key)) { return this; }

const data = this.data[key];
delete this.data[key];
const data = this.data[key].pop();
if (this.data[key].length === 0) {
delete this.data[key];
}
this.onRemove(data);
this.order.splice(this.order.indexOf(key), 1);

Expand Down
4 changes: 3 additions & 1 deletion test/unit/util/lru_cache.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ test('LRUCache - duplicate add', (t) => {
cache.add('a', 'b');
cache.add('a', 'c');

t.deepEqual(cache.keys(), ['a']);
t.deepEqual(cache.keys(), ['a', 'a']);
t.ok(cache.has('a'));
t.equal(cache.getAndRemove('a'), 'b');
t.ok(cache.has('a'));
t.equal(cache.getAndRemove('a'), 'c');
t.end();
Expand Down

0 comments on commit 06ea9c3

Please sign in to comment.