Skip to content

Commit 1908cab

Browse files
committed
complete lru-cache
1 parent f13588d commit 1908cab

1 file changed

Lines changed: 73 additions & 0 deletions

File tree

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
class Node:
2+
def __init__(self, key, value):
3+
self.key = key
4+
self.value = value
5+
self.next = None
6+
self.previous = None
7+
8+
class LruCache:
9+
def __init__(self, limit):
10+
if limit <= 0:
11+
raise ValueError
12+
13+
self.limit = limit
14+
self.cache = {}
15+
self.head = None
16+
self.tail = None
17+
18+
def _remove_node(self, node):
19+
if node.previous is not None:
20+
node.previous.next = node.next
21+
else:
22+
self.head = node.next
23+
24+
if node.next is not None:
25+
node.next.previous = node.previous
26+
else:
27+
self.tail = node.previous
28+
29+
def _add_to_tail(self, node):
30+
node.next = None
31+
node.previous = self.tail
32+
33+
if self.tail is not None:
34+
self.tail.next = node
35+
else:
36+
self.head = node
37+
38+
self.tail = node
39+
40+
def get(self, key):
41+
if key not in self.cache:
42+
return None
43+
44+
node = self.cache[key]
45+
46+
# Move node to the most-recently-used position
47+
if node is not self.tail:
48+
self._remove_node(node)
49+
self._add_to_tail(node)
50+
51+
return node.value
52+
53+
def set(self, key, value):
54+
if key in self.cache:
55+
node = self.cache[key]
56+
node.value = value
57+
58+
# Updating an item counts as using it
59+
if node is not self.tail:
60+
self._remove_node(node)
61+
self._add_to_tail(node)
62+
63+
return
64+
65+
node = Node(key, value)
66+
self.cache[key] = node
67+
self._add_to_tail(node)
68+
69+
if len(self.cache) > self.limit:
70+
lru_node = self.head
71+
72+
self._remove_node(lru_node)
73+
del self.cache[lru_node.key]

0 commit comments

Comments
 (0)