1+ class CacheNode :
2+ def __init__ (self , key , value ):
3+ self .key = key
4+ self .value = value
5+ self .previous = None
6+ self .next = None
7+
8+ class LruCache :
9+ def __init__ (self , limit : int ):
10+ if limit <= 0 :
11+ raise ValueError ("Cache limit must be greater than 0" )
12+
13+ self .limit = limit
14+ self .lookup = {}
15+ self .head = None
16+ self .tail = None
17+
18+ def _remove_node (self , node : CacheNode ):
19+ if node == self .head :
20+ self .head = node .next
21+ if node == self .tail :
22+ self .tail = node .previous
23+
24+ if node .previous is not None :
25+ node .previous .next = node .next
26+ if node .next is not None :
27+ node .next .previous = node .previous
28+
29+ node .next = None
30+ node .previous = None
31+
32+ def _move_to_head (self , node : CacheNode ):
33+ node .next = self .head
34+ node .previous = None
35+
36+ if self .head is None :
37+ self .head = node
38+ self .tail = node
39+ else :
40+ self .head .previous = node
41+ self .head = node
42+
43+ def get (self , key ):
44+ if key not in self .lookup :
45+ return None
46+
47+ node = self .lookup [key ]
48+ self ._remove_node (node )
49+ self ._move_to_head (node )
50+ return node .value
51+
52+ def set (self , key , value ) -> None :
53+ if key in self .lookup :
54+ node = self .lookup [key ]
55+ node .value = value
56+ self ._remove_node (node )
57+ self ._move_to_head (node )
58+ else :
59+ new_node = CacheNode (key , value )
60+
61+ if len (self .lookup ) >= self .limit :
62+ oldest_node = self .tail
63+ if oldest_node is not None :
64+ del self .lookup [oldest_node .key ]
65+ self ._remove_node (oldest_node )
66+
67+ self ._move_to_head (new_node )
68+ self .lookup [key ] = new_node
0 commit comments