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
25
27 """Caching dictionary like object that discards the least recently
28 used objects when number of cached items exceeds maxsize.
29
30 cullsize is the fraction of items that will be discarded when
31 maxsize is reached.
32 """
33
34 - def __init__(self, maxsize, cullsize=2, *args, **kwargs):
35 self.cullsize = max(2, cullsize)
36 self.maxsize = max(cullsize, maxsize)
37 self.queue = deque()
38 WeakValueDictionary.__init__(self, *args, **kwargs)
39
41 """free memory by deleting old items from cache"""
42
43
44
45
46
47
48
49
50 while len(self) >= self.maxsize <= len(self.queue):
51 cullsize = max(int(len(self.queue) / self.cullsize), 2)
52 try:
53 for i in range(cullsize):
54 self.queue.popleft()
55 except IndexError:
56
57
58 break
59
60
61
62
63 for i in xrange(5):
64 gc.collect()
65
67
68 while len(self.queue) and self.queue[0][0] == key:
69
70
71 self.queue.popleft()
72
73 while len(self.queue) and self.queue[-1][0] == key:
74
75
76 self.queue.pop()
77
78 if len(self) >= self.maxsize:
79 self.cull()
80
81 self.queue.append((key, value))
82 WeakValueDictionary.__setitem__(self, key, value)
83
85 value = WeakValueDictionary.__getitem__(self, key)
86
87 while len(self.queue) > 0 and self.queue[0][0] == key:
88
89
90 self.queue.popleft()
91
92
93 if not (len(self.queue) and self.queue[-1][0] == key):
94 self.queue.append((key, value))
95
96 return value
97
99
100
101 while len(self.queue) and self.queue[0][0] == key:
102
103
104 self.queue.popleft()
105
106 while len(self.queue) and self.queue[-1][0] == key:
107
108
109 self.queue.pop()
110
111 return WeakValueDictionary.__delitem__(self, key)
112
114 self.queue.clear()
115 return WeakValueDictionary.clear(self)
116
118 if key not in self:
119 self[key] = default
120
121 return self[key]
122