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 self.queue.append((key, value))
52 WeakValueDictionary.__setitem__(self, key, value)
53
54 if len(self) > self.maxsize:
55 while len(self) > (self.maxsize - self.maxsize / self.cullsize):
56
57 self.queue.popleft()
58 while gc.collect() > 0:
59 pass
60
62 value = WeakValueDictionary.__getitem__(self, key)
63
64 while len(self.queue) > 1 and self.queue[0][0] == key:
65
66
67 self.queue.popleft()
68
69
70 if not (len(self.queue) and self.queue[-1][0] == key):
71 self.queue.append((key, value))
72
73 return value
74
76
77
78 while len(self.queue) and self.queue[0][0] == key:
79
80
81 self.queue.popleft()
82
83 while len(self.queue) and self.queue[-1][0] == key:
84
85
86 self.queue.pop()
87
88 return WeakValueDictionary.__delitem__(self, key)
89
91 self.queue.clear()
92 return WeakValueDictionary.clear(self)
93
95 if key not in self:
96 self[key]=default
97
98 return self[key]
99