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 break
68 finally:
69
70
71
72 for i in range(5):
73 if gc.collect() == 0:
74 break
75 self.queue.append((key, value))
76 WeakValueDictionary.__setitem__(self, key, value)
77
78
80 value = WeakValueDictionary.__getitem__(self, key)
81
82 while len(self.queue) > 0 and self.queue[0][0] == key:
83
84
85 self.queue.popleft()
86
87
88 if not (len(self.queue) and self.queue[-1][0] == key):
89 self.queue.append((key, value))
90
91 return value
92
94
95
96 while len(self.queue) and self.queue[0][0] == key:
97
98
99 self.queue.popleft()
100
101 while len(self.queue) and self.queue[-1][0] == key:
102
103
104 self.queue.pop()
105
106 return WeakValueDictionary.__delitem__(self, key)
107
109 self.queue.clear()
110 return WeakValueDictionary.clear(self)
111
113 if key not in self:
114 self[key]=default
115
116 return self[key]
117