Skip to content

Commit 435109a

Browse files
committed
feat: implement lru cache cleanly
1 parent e718fb4 commit 435109a

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import sys
2+
import os
3+
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../implement_linked_list")))
4+
5+
from linked_list import LinkedList, Node # type:ignore
6+
from typing import Any
7+
8+
class LruCache:
9+
def __init__(self, limit: int):
10+
if limit <= 0:
11+
raise ValueError("Limit must be greater than 0")
12+
self.capacity = limit
13+
# maps key
14+
self.cache: dict[Any, Node] = {}
15+
# tracking the usage order head first tail last.
16+
self.list = LinkedList()
17+
18+
def get(self, key: Any) -> Any:
19+
# If key not exist return None
20+
if key not in self.cache:
21+
return None
22+
23+
node_handle = self.cache[key]
24+
25+
# we get the value to return
26+
_, value = node_handle.value
27+
28+
# we use remove() and push_head() to remove it from the position to the head
29+
self.list.remove(node_handle)
30+
self.cache[key] = self.list.push_head((key, value))
31+
32+
return value
33+
34+
def set(self, key: Any, value: Any) -> None:
35+
if key in self.cache:
36+
self.list.remove(self.cache[key])
37+
# we do this because the position and value about to change.
38+
del self.cache[key]
39+
40+
# we call pop_tail() to cut off the tail
41+
elif len(self.cache) >= self.capacity:
42+
# return the value stored in the tail node
43+
oldest_item = self.list.pop_tail()
44+
if oldest_item:
45+
oldest_key, _ = oldest_item
46+
del self.cache[oldest_key]
47+
48+
## place the new items at the head of stack and update and return the object Node.
49+
new_node = self.list.push_head((key, value))
50+
self.cache[key] = new_node

0 commit comments

Comments
 (0)