~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/lru_cache.py

  • Committer: Martin Packman
  • Date: 2011-10-14 18:42:17 UTC
  • mto: This revision was merged to the branch mainline in revision 6235.
  • Revision ID: martin.packman@canonical.com-20111014184217-2fmnziqqo4duhgbz
Remove unneeded _LRUNode.cleanup callback ability and deprecate LRUCache.add

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
class _LRUNode(object):
27
27
    """This maintains the linked-list which is the lru internals."""
28
28
 
29
 
    __slots__ = ('prev', 'next_key', 'key', 'value', 'cleanup')
 
29
    __slots__ = ('prev', 'next_key', 'key', 'value')
30
30
 
31
 
    def __init__(self, key, value, cleanup=None):
 
31
    def __init__(self, key, value):
32
32
        self.prev = None
33
33
        self.next_key = _null_key
34
34
        self.key = key
35
35
        self.value = value
36
 
        self.cleanup = cleanup
37
36
 
38
37
    def __repr__(self):
39
38
        if self.prev is None:
43
42
        return '%s(%r n:%r p:%r)' % (self.__class__.__name__, self.key,
44
43
                                     self.next_key, prev_key)
45
44
 
46
 
    def run_cleanup(self):
47
 
        try:
48
 
            if self.cleanup is not None:
49
 
                self.cleanup(self.key, self.value)
50
 
        finally:
51
 
            # cleanup might raise an exception, but we want to make sure
52
 
            # to break refcycles, etc
53
 
            self.cleanup = None
54
 
            self.value = None
55
 
 
56
45
 
57
46
class LRUCache(object):
58
47
    """A class which manages a cache of entries, removing unused ones."""
102
91
    def __len__(self):
103
92
        return len(self._cache)
104
93
 
 
94
    @symbol_versioning.deprecated_method(
 
95
        symbol_versioning.deprecated_in((2, 5, 0)))
105
96
    def add(self, key, value, cleanup=None):
106
 
        """Add a new value to the cache.
107
 
 
108
 
        Also, if the entry is ever removed from the cache, call
109
 
        cleanup(key, value).
110
 
 
111
 
        :param key: The key to store it under
112
 
        :param value: The object to store
113
 
        :param cleanup: None or a function taking (key, value) to indicate
114
 
                        'value' should be cleaned up.
115
 
        """
 
97
        if cleanup is not None:
 
98
            raise ValueError("Per-node cleanup functions no longer supported")
 
99
        return self.__setitem__(key, value)
 
100
 
 
101
    def __setitem__(self, key, value):
 
102
        """Add a new value to the cache"""
116
103
        if key is _null_key:
117
104
            raise ValueError('cannot use _null_key as a key')
118
105
        if key in self._cache:
119
106
            node = self._cache[key]
120
 
            try:
121
 
                node.run_cleanup()
122
 
            finally:
123
 
                # Maintain the LRU properties, even if cleanup raises an
124
 
                # exception
125
 
                node.value = value
126
 
                node.cleanup = cleanup
127
 
                self._record_access(node)
 
107
            node.value = value
 
108
            self._record_access(node)
128
109
        else:
129
 
            node = _LRUNode(key, value, cleanup=cleanup)
 
110
            node = _LRUNode(key, value)
130
111
            self._cache[key] = node
131
112
            self._record_access(node)
132
113
 
173
154
        while len(self._cache) > self._after_cleanup_count:
174
155
            self._remove_lru()
175
156
 
176
 
    def __setitem__(self, key, value):
177
 
        """Add a value to the cache, there will be no cleanup function."""
178
 
        self.add(key, value, cleanup=None)
179
 
 
180
157
    def _record_access(self, node):
181
158
        """Record that key was accessed."""
182
159
        # Move 'node' to the front of the queue
210
187
        # If we have removed all entries, remove the head pointer as well
211
188
        if self._least_recently_used is None:
212
189
            self._most_recently_used = None
213
 
        try:
214
 
            node.run_cleanup()
215
 
        finally:
216
 
            # cleanup might raise an exception, but we want to make sure to
217
 
            # maintain the linked list
218
 
            if node.prev is not None:
219
 
                node.prev.next_key = node.next_key
220
 
            if node.next_key is not _null_key:
221
 
                node_next = self._cache[node.next_key]
222
 
                node_next.prev = node.prev
223
 
            # And remove this node's pointers
224
 
            node.prev = None
225
 
            node.next_key = _null_key
 
190
        if node.prev is not None:
 
191
            node.prev.next_key = node.next_key
 
192
        if node.next_key is not _null_key:
 
193
            node_next = self._cache[node.next_key]
 
194
            node_next.prev = node.prev
 
195
        # And remove this node's pointers
 
196
        node.prev = None
 
197
        node.next_key = _null_key
226
198
 
227
199
    def _remove_lru(self):
228
200
        """Remove one entry from the lru, and handle consequences.
285
257
        self._update_max_size(max_size, after_cleanup_size=after_cleanup_size)
286
258
        LRUCache.__init__(self, max_cache=max(int(max_size/512), 1))
287
259
 
288
 
    def add(self, key, value, cleanup=None):
289
 
        """Add a new value to the cache.
290
 
 
291
 
        Also, if the entry is ever removed from the cache, call
292
 
        cleanup(key, value).
293
 
 
294
 
        :param key: The key to store it under
295
 
        :param value: The object to store
296
 
        :param cleanup: None or a function taking (key, value) to indicate
297
 
                        'value' should be cleaned up.
298
 
        """
 
260
    def __setitem__(self, key, value):
 
261
        """Add a new value to the cache"""
299
262
        if key is _null_key:
300
263
            raise ValueError('cannot use _null_key as a key')
301
264
        node = self._cache.get(key, None)
310
273
            if node is not None:
311
274
                # We won't be replacing the old node, so just remove it
312
275
                self._remove_node(node)
313
 
            if cleanup is not None:
314
 
                cleanup(key, value)
315
276
            return
316
277
        if node is None:
317
 
            node = _LRUNode(key, value, cleanup=cleanup)
 
278
            node = _LRUNode(key, value)
318
279
            self._cache[key] = node
319
280
        else:
320
281
            self._value_size -= self._compute_size(node.value)