-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathLRUCache.py
85 lines (69 loc) · 2.49 KB
/
LRUCache.py
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
import time
#Copyright (c) 2018 - Nathan Corbin - @ncorbuk(Twitter)
class Node:
#Nodes - (n)=(n)=(n)=(n)
def __init__(self, key, val):
self.key = key
self.val = val
self.next = None
self.prev = None
class LRUCache:
cache_limit = None
DEBUG = False # If DEBUG is equal to TRUE, you will get cache list printed on each and be able to
# see cached results printed etc
def __init__(self, func):
self.func = func
self.cache = {}
self.head = Node(0,0)
self.tail = Node(0,0)
self.head.next = self.tail
self.tail.prev = self.head
def __call__(self, *args, **kwargs):
#If in cache, pull results
if args in self.cache:
self.llist(args)
if self.DEBUG == True:
return f'Cached...{args}\n{self.cache[args]}\nCache: {self.cache}'
return self.cache[args]
#If cache-limit reached - Remove LRU from node link list and dict - cache.
if self.cache_limit is not None:
if len(self.cache) > self.cache_limit:
n = self.head.next
self._remove(n)
del self.cache[n.key]
#Compute and cache and node - if not in cache
result = self.func(*args, **kwargs)
self.cache[args] = result
node = Node(args, result)
self._add(node)
if self.DEBUG == True:
return f'{result}\nCache: {self.cache}'
return result
#Remove from double linked-list - Node.
def _remove(self, node):
p = node.prev
n = node.next
p.next = n
n.prev = p
#Add to double linked-list - Node.
def _add(self, node):
p = self.tail.prev
p.next = node
self.tail.prev = node
node.prev = p
node.next = self.tail
#If in result in cache, move to top of Cache/linked-list - Node.
def llist(self, args):
current = self.head
while True:
if current.key == args :
node = current
self._remove(node)
self._add(node)
if self.DEBUG == True:
del self.cache[node.key] # Debugging/ to view cache list in order of linked-list...
self.cache[node.key] = node.val # Debugging/ to view cache list in order of linked-list...
break
else:
current = current.next
#Copyright (c) 2018 - Nathan Corbin - @ncorbuk(Twitter)