1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 from collections import deque
22 from weakref import WeakValueDictionary
23 import gc
24
26 """Caching dictionary like object that discards the least recently
27 used objects when number of cached items exceeds maxsize.
28
29 cullsize is the fraction of items that will be discarded when
30 maxsize is reached.
31 """
32
33 - def __init__(self, maxsize, cullsize=2, *args, **kwargs):
34 self.cullsize = max(2, cullsize)
35 self.maxsize = max(cullsize, maxsize)
36 self.queue = deque()
37 WeakValueDictionary.__init__(self, *args, **kwargs)
38
40
41 while len(self.queue) and self.queue[0][0] == key:
42
43
44 self.queue.popleft()
45
46 while len(self.queue) and self.queue[-1][0] == key:
47
48
49 self.queue.pop()
50
51 if len(self) >= self.maxsize:
52
53
54
55
56
57
58
59
60 while len(self) >= self.maxsize <= len(self.queue):
61 cullsize = max(int(len(self.queue) / self.cullsize), 2)
62 try:
63 for i in range(cullsize):
64 self.queue.popleft()
65 except IndexError:
66
67
68 break
69
70
71
72
73 for i in range(5):
74 if gc.collect() == 0:
75 break
76 self.queue.append((key, value))
77 WeakValueDictionary.__setitem__(self, key, value)
78
79
81 value = WeakValueDictionary.__getitem__(self, key)
82
83 while len(self.queue) > 0 and self.queue[0][0] == key:
84
85
86 self.queue.popleft()
87
88
89 if not (len(self.queue) and self.queue[-1][0] == key):
90 self.queue.append((key, value))
91
92 return value
93
95
96
97 while len(self.queue) and self.queue[0][0] == key:
98
99
100 self.queue.popleft()
101
102 while len(self.queue) and self.queue[-1][0] == key:
103
104
105 self.queue.pop()
106
107 return WeakValueDictionary.__delitem__(self, key)
108
110 self.queue.clear()
111 return WeakValueDictionary.clear(self)
112
114 if key not in self:
115 self[key] = default
116
117 return self[key]
118