/** * lru - an LRU (least recently used) cache implementation. * * Implemented using double-linked list and hash-map that * gives O(1) time complexity and O(n) in space usage. * * @author Andrey Antukh , 2016 * @license MIT License */ "use strict"; goog.provide("lru"); goog.require("goog.asserts"); goog.scope(function() { const assert = goog.asserts.assert; class Node { constructor(key, value) { this.key = key; this.value = value; this.prev = null; this.next = null; } } class Cache { constructor(limit) { assert(goog.isNumber(limit), "`limit` should be a number") this.limit = limit this.clear(); } clear() { this.map = new Map(); this.size = 0; this.head = null; this.tail = null; } setHead(node) { assert(node instanceof Node, "Node instance expected"); node.next = this.head; node.prev = null; if (this.head !== null) { this.head.prev = node; } this.head = node; if (this.tail === null) { this.tail = node; } this.size++; this.map.set(node.key, node); return this; } setItem(key, value) { const node = new Node(key, value); if (this.map.has(key)) { const item = this.map.get(key); item.value = node.value; this.removeItem(node.key); } else { if (this.size >= this.limit) { this.map.delete(key); this.size--; this.tail = this.tail.prev; this.tail.next = null; } } this.setHead(node); return this; } getItem(key) { if (this.map.has(key)) { const value = this.map.get(key).value; const node = new Node(key, value); this.removeItem(key); this.setHead(node); return value; } else { return undefined; } } removeItem(key) { if (!this.map.has(key)) { return this; } const node = this.map.get(key); if (node.prev !== null) { node.prev.next = node.next; } else { this.head = node.next; } if (node.next !== null) { node.next.prev = node.prev; } else { this.tail = node.prev; } this.map.delete(key); this.size--; return this; } } function create(limit) { limit = limit || 50; return new Cache(limit); } lru.create = create; lru.get = (c, key) => c.getItem(key); lru.set = (c, key, val) => c.setItem(key, val); lru.remove = (c, key) => c.removeItem(key); });