1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 from util import *
23
24 DEFAULT_CACHE_CAPACITY = 1000
25
27 """
28 A cache of values such that least recently used element is flushed when
29 the cache fills.
30
31 This lets us retrieve the key given the timestamp, and the
32 timestamp given the key. (Also the value given either one.)
33 That's necessary so that we can reorder the history given a key,
34 and also manipulate the values dict given a timestamp.
35
36 I haven't tried changing history to a List. An earlier
37 implementation of history as a List was slower than what's here,
38 but the two implementations aren't directly comparable.
39
40 @type values: C{dict}
41 @ivar values: A dict from key -> (value, timestamp)
42
43 @type history: C{dict}
44 @ivar history: A dict from timestamp -> key
45
46 @type nextTimestamp: C{int}
47 @ivar nextTimestamp: Timestamp to use with the next value that's added.
48
49 @type oldestTimestamp: C{int}
50 @ivar oldestTimestamp: Timestamp of the oldest element (the next one to
51 remove), or slightly lower than that.
52 """
53
55 """
56 Initialize a new cache
57
58 @type capacity: int
59 @param capacity: Size of the cache (number of Sense -> Synset mappings)
60 """
61 self.capacity = capacity
62 self.clear()
63
65 """
66 Flush the cache
67 """
68 self.values = {}
69 self.history = {}
70 self.oldestTimestamp = 0
71 self.nextTimestamp = 1
72
74 """
75 Remove the oldest entry from the cache.
76 """
77 while self.oldestTimestamp < self.nextTimestamp:
78
79 if self.history.get(self.oldestTimestamp):
80 key = self.history[self.oldestTimestamp]
81 del self.history[self.oldestTimestamp]
82 del self.values[key]
83 return
84
85 self.oldestTimestamp = self.oldestTimestamp + 1
86
88 """
89 Set the capacity of the cache.
90
91 @type capacity: int
92 @param capacity: new size of the cache
93 """
94 if capacity == 0: self.clear()
95
96 else:
97 self.capacity = capacity
98
99 while len(self.values) > self.capacity:
100 self.removeOldestEntry()
101
102 - def get(self, key, loadfn=None):
103 """
104 Get an item from the cache.
105
106 @type key: unknown
107 @param key: identifier of a cache entry
108
109 @type loadfn: function reference
110 @param loadfn: a function used to load the cached entry
111
112 @return: a cached item
113 """
114 value = None
115
116
117 if self.values:
118 try:
119 value, timestamp = self.values.get(key)
120 del self.history[timestamp]
121 except KeyError:
122 value = None
123
124
125 if value == None:
126 value = loadfn and loadfn()
127
128
129 if self.values:
130 timestamp = self.nextTimestamp
131 self.nextTimestamp = self.nextTimestamp + 1
132 self.values[key] = (value, timestamp)
133 self.history[timestamp] = key
134
135 if len(self.values) > self.capacity:
136 self.removeOldestEntry()
137
138 return value
139
141 """
142 A NullCache implements the Cache interface (the interface that
143 LRUCache implements), but doesn't store any values.
144 """
145
148
149 - def get(self, key, loadfn=None):
150 return loadfn and loadfn()
151
155
160
164
166 """
167 Set the capacity of the entity cache.
168
169 @type capacity: int
170 @param capacity: new size of the cache.
171 """
172 enableCache()
173 entityCache.setCapacity(capacity)
174
179
180
181 entityCache = _LRUCache(DEFAULT_CACHE_CAPACITY)
182