15815213711
2024-08-26 67b8b6731811983447e053d4396b3708c14dfe3c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// https://medium.com/dsinjs/implementing-lru-cache-in-javascript-94ba6755cda9
 
class Node {
  constructor(key, value, next = null, prev = null) {
    this.key = key;
    this.value = value;
    this.next = next;
    this.prev = prev;
  }
}
 
export default class LRUCache {
  //set default limit of 10 if limit is not passed.
  constructor(limit = 10) {
    this.size = 0;
    this.limit = limit;
    this.head = null;
    this.tail = null;
    this.cache = {};
  }
 
  // Write Node to head of LinkedList
  // update cache with Node key and Node reference
  put(key, value){
    this.ensureLimit();
 
    if(!this.head){
      this.head = this.tail = new Node(key, value);
    }else{
      const node = new Node(key, value, this.head);
      this.head.prev = node;
      this.head = node;
    }
 
    //Update the cache map
    this.cache[key] = this.head;
    this.size++;
  }
 
  // Read from cache map and make that node as new Head of LinkedList
  get(key){
    if(this.cache[key]){
      const value = this.cache[key].value;
 
      // node removed from it's position and cache
      this.remove(key)
      // write node again to the head of LinkedList to make it most recently used
      this.put(key, value);
 
      return value;
    }
 
    console.log(`Item not available in cache for key ${key}`);
  }
 
  ensureLimit(){
    if(this.size === this.limit){
      this.remove(this.tail.key)
    }
  }
 
  remove(key){
    const node = this.cache[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
    }
 
    delete this.cache[key];
    this.size--;
  }
 
  clear() {
    this.head = null;
    this.tail = null;
    this.size = 0;
    this.cache = {};
  }
 
  // // Invokes the callback function with every node of the chain and the index of the node.
  // forEach(fn) {
  //   let node = this.head;
  //   let counter = 0;
  //   while (node) {
  //     fn(node, counter);
  //     node = node.next;
  //     counter++;
  //   }
  // }
 
  // // To iterate over LRU with a 'for...of' loop
  // *[Symbol.iterator]() {
  //   let node = this.head;
  //   while (node) {
  //     yield node;
  //     node = node.next;
  //   }
  // }
}