|
1 |
| -class DoubleLinkedListNode { |
2 |
| - // Double Linked List Node built specifically for LRU Cache |
3 |
| - constructor (key, val) { |
4 |
| - this.key = key |
5 |
| - this.val = val |
6 |
| - this.next = null |
7 |
| - this.prev = null |
8 |
| - } |
9 |
| -} |
10 |
| - |
11 |
| -class DoubleLinkedList { |
12 |
| - // Double Linked List built specifically for LRU Cache |
13 |
| - constructor () { |
14 |
| - this.head = new DoubleLinkedListNode(null, null) |
15 |
| - this.rear = new DoubleLinkedListNode(null, null) |
16 |
| - this.head.next = this.rear |
17 |
| - this.rear.prev = this.head |
18 |
| - } |
19 |
| - |
20 |
| - add (node) { |
21 |
| - // Adds the given node to the end of the list (before rear) |
22 |
| - const temp = this.rear.prev |
23 |
| - temp.next = node |
24 |
| - node.prev = temp |
25 |
| - this.rear.prev = node |
26 |
| - node.next = this.rear |
27 |
| - } |
28 |
| - |
29 |
| - remove (node) { |
30 |
| - // Removes and returns the given node from the list |
31 |
| - const tempLast = node.prev |
32 |
| - const tempNext = node.next |
33 |
| - node.prev = null |
34 |
| - node.next = null |
35 |
| - tempLast.next = tempNext |
36 |
| - tempNext.prev = tempLast |
37 |
| - |
38 |
| - return node |
39 |
| - } |
40 |
| -} |
41 |
| - |
42 | 1 | class LRUCache {
|
43 | 2 | // LRU Cache to store a given capacity of data
|
44 | 3 | constructor (capacity) {
|
45 |
| - this.list = new DoubleLinkedList() |
| 4 | + this.cache = new Map() |
46 | 5 | this.capacity = capacity
|
47 |
| - this.numKeys = 0 |
48 | 6 | this.hits = 0
|
49 | 7 | this.miss = 0
|
50 |
| - this.cache = {} |
51 | 8 | }
|
52 | 9 |
|
53 | 10 | cacheInfo () {
|
54 | 11 | // Return the details for the cache instance [hits, misses, capacity, current_size]
|
55 |
| - return `CacheInfo(hits=${this.hits}, misses=${this.miss}, capacity=${this.capacity}, current size=${this.numKeys})` |
| 12 | + return `CacheInfo(hits=${this.hits}, misses=${this.miss}, capacity=${this.capacity}, current size=${this.cache.size})` |
56 | 13 | }
|
57 | 14 |
|
58 | 15 | set (key, value) {
|
59 |
| - // Sets the value for the input key and updates the Double Linked List |
60 |
| - if (!(key in this.cache)) { |
61 |
| - if (this.numKeys >= this.capacity) { |
62 |
| - const keyToDelete = this.list.head.next.key |
63 |
| - this.list.remove(this.cache[keyToDelete]) |
64 |
| - delete this.cache[keyToDelete] |
65 |
| - this.numKeys -= 1 |
66 |
| - } |
67 |
| - this.cache[key] = new DoubleLinkedListNode(key, value) |
68 |
| - this.list.add(this.cache[key]) |
69 |
| - this.numKeys += 1 |
70 |
| - } else { |
71 |
| - const node = this.list.remove(this.cache[key]) |
72 |
| - node.val = value |
73 |
| - this.list.add(node) |
| 16 | + // Sets the value for the input key and if the key exists it updates the existing key |
| 17 | + if (this.cache.size === this.capacity) { |
| 18 | + // delete oldest key existing in map |
| 19 | + this.cache.delete(this.cache.keys().next().value) |
74 | 20 | }
|
| 21 | + this.cache.set(key, value) |
75 | 22 | }
|
76 | 23 |
|
77 | 24 | get (key) {
|
78 |
| - // Returns the value for the input key and updates the Double Linked List. Returns null if key is not present in cache |
79 |
| - if (key in this.cache) { |
| 25 | + // Returns the value for the input key. Returns null if key is not present in cache |
| 26 | + if (this.cache.has(key)) { |
| 27 | + const value = this.cache.get(key) |
| 28 | + // refresh the cache to update the order of key |
| 29 | + this.cache.delete(key) |
| 30 | + this.cache.set(key, value) |
80 | 31 | this.hits += 1
|
81 |
| - this.list.add(this.list.remove(this.cache[key])) |
82 |
| - return this.cache[key].val |
| 32 | + return value |
| 33 | + } else { |
| 34 | + this.miss += 1 |
| 35 | + return null |
83 | 36 | }
|
84 |
| - this.miss += 1 |
85 |
| - return null |
86 | 37 | }
|
87 | 38 | }
|
88 | 39 |
|
|
0 commit comments