Rev 6235: (gz) Refactor and deprecate unused parts of lru_cache (Martin Packman) in file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/

Patch Queue Manager pqm at pqm.ubuntu.com
Thu Oct 27 15:55:26 UTC 2011


At file:///srv/pqm.bazaar-vcs.org/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 6235 [merge]
revision-id: pqm at pqm.ubuntu.com-20111027155525-yyv39g64i4wp8wnm
parent: pqm at pqm.ubuntu.com-20111026185426-dj45600glpvn5vlt
parent: martin.packman at canonical.com-20111027151404-7bo6z5uinjdgo00d
committer: Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2011-10-27 15:55:25 +0000
message:
  (gz) Refactor and deprecate unused parts of lru_cache (Martin Packman)
modified:
  bzrlib/chk_map.py              chk_map.py-20081001014447-ue6kkuhofvdecvxa-1
  bzrlib/lru_cache.py            lru_cache.py-20070119165515-tlw203kuwh0id5gv-1
  bzrlib/tests/test_lru_cache.py test_lru_cache.py-20070119165535-hph6rk4h9rzy4180-1
  doc/en/release-notes/bzr-2.5.txt bzr2.5.txt-20110708125756-587p0hpw7oke4h05-1
=== modified file 'bzrlib/chk_map.py'
--- a/bzrlib/chk_map.py	2011-05-20 14:46:02 +0000
+++ b/bzrlib/chk_map.py	2011-10-14 19:24:19 +0000
@@ -920,7 +920,7 @@
         bytes = ''.join(lines)
         if len(bytes) != self._current_size():
             raise AssertionError('Invalid _current_size')
-        _get_cache().add(self._key, bytes)
+        _get_cache()[self._key] = bytes
         return [self._key]
 
     def refs(self):
@@ -1193,7 +1193,7 @@
                     prefix, node_key_filter = keys[record.key]
                     node_and_filters.append((node, node_key_filter))
                     self._items[prefix] = node
-                    _get_cache().add(record.key, bytes)
+                    _get_cache()[record.key] = bytes
                 for info in node_and_filters:
                     yield info
 
@@ -1319,7 +1319,7 @@
             lines.append(serialised[prefix_len:])
         sha1, _, _ = store.add_lines((None,), (), lines)
         self._key = StaticTuple("sha1:" + sha1,).intern()
-        _get_cache().add(self._key, ''.join(lines))
+        _get_cache()[self._key] = ''.join(lines)
         yield self._key
 
     def _search_key(self, key):

=== modified file 'bzrlib/lru_cache.py'
--- a/bzrlib/lru_cache.py	2010-07-15 13:05:40 +0000
+++ b/bzrlib/lru_cache.py	2011-10-14 18:42:17 +0000
@@ -17,6 +17,7 @@
 """A simple least-recently-used (LRU) cache."""
 
 from bzrlib import (
+    symbol_versioning,
     trace,
     )
 
@@ -25,18 +26,13 @@
 class _LRUNode(object):
     """This maintains the linked-list which is the lru internals."""
 
-    __slots__ = ('prev', 'next_key', 'key', 'value', 'cleanup', 'size')
+    __slots__ = ('prev', 'next_key', 'key', 'value')
 
-    def __init__(self, key, value, cleanup=None):
+    def __init__(self, key, value):
         self.prev = None
         self.next_key = _null_key
         self.key = key
         self.value = value
-        self.cleanup = cleanup
-        # TODO: We could compute this 'on-the-fly' like we used to, and remove
-        #       one pointer from this object, we just need to decide if it
-        #       actually costs us much of anything in normal usage
-        self.size = None
 
     def __repr__(self):
         if self.prev is None:
@@ -46,16 +42,6 @@
         return '%s(%r n:%r p:%r)' % (self.__class__.__name__, self.key,
                                      self.next_key, prev_key)
 
-    def run_cleanup(self):
-        try:
-            if self.cleanup is not None:
-                self.cleanup(self.key, self.value)
-        finally:
-            # cleanup might raise an exception, but we want to make sure
-            # to break refcycles, etc
-            self.cleanup = None
-            self.value = None
-
 
 class LRUCache(object):
     """A class which manages a cache of entries, removing unused ones."""
@@ -105,62 +91,23 @@
     def __len__(self):
         return len(self._cache)
 
-    def _walk_lru(self):
-        """Walk the LRU list, only meant to be used in tests."""
-        node = self._most_recently_used
-        if node is not None:
-            if node.prev is not None:
-                raise AssertionError('the _most_recently_used entry is not'
-                                     ' supposed to have a previous entry'
-                                     ' %s' % (node,))
-        while node is not None:
-            if node.next_key is _null_key:
-                if node is not self._least_recently_used:
-                    raise AssertionError('only the last node should have'
-                                         ' no next value: %s' % (node,))
-                node_next = None
-            else:
-                node_next = self._cache[node.next_key]
-                if node_next.prev is not node:
-                    raise AssertionError('inconsistency found, node.next.prev'
-                                         ' != node: %s' % (node,))
-            if node.prev is None:
-                if node is not self._most_recently_used:
-                    raise AssertionError('only the _most_recently_used should'
-                                         ' not have a previous node: %s'
-                                         % (node,))
-            else:
-                if node.prev.next_key != node.key:
-                    raise AssertionError('inconsistency found, node.prev.next'
-                                         ' != node: %s' % (node,))
-            yield node
-            node = node_next
-
+    @symbol_versioning.deprecated_method(
+        symbol_versioning.deprecated_in((2, 5, 0)))
     def add(self, key, value, cleanup=None):
-        """Add a new value to the cache.
-
-        Also, if the entry is ever removed from the cache, call
-        cleanup(key, value).
-
-        :param key: The key to store it under
-        :param value: The object to store
-        :param cleanup: None or a function taking (key, value) to indicate
-                        'value' should be cleaned up.
-        """
+        if cleanup is not None:
+            raise ValueError("Per-node cleanup functions no longer supported")
+        return self.__setitem__(key, value)
+
+    def __setitem__(self, key, value):
+        """Add a new value to the cache"""
         if key is _null_key:
             raise ValueError('cannot use _null_key as a key')
         if key in self._cache:
             node = self._cache[key]
-            try:
-                node.run_cleanup()
-            finally:
-                # Maintain the LRU properties, even if cleanup raises an
-                # exception
-                node.value = value
-                node.cleanup = cleanup
-                self._record_access(node)
+            node.value = value
+            self._record_access(node)
         else:
-            node = _LRUNode(key, value, cleanup=cleanup)
+            node = _LRUNode(key, value)
             self._cache[key] = node
             self._record_access(node)
 
@@ -190,10 +137,13 @@
         """
         return self._cache.keys()
 
-    def items(self):
-        """Get the key:value pairs as a dict."""
+    def as_dict(self):
+        """Get a new dict with the same key:value pairs as the cache"""
         return dict((k, n.value) for k, n in self._cache.iteritems())
 
+    items = symbol_versioning.deprecated_method(
+        symbol_versioning.deprecated_in((2, 5, 0)))(as_dict)
+
     def cleanup(self):
         """Clear the cache until it shrinks to the requested size.
 
@@ -204,10 +154,6 @@
         while len(self._cache) > self._after_cleanup_count:
             self._remove_lru()
 
-    def __setitem__(self, key, value):
-        """Add a value to the cache, there will be no cleanup function."""
-        self.add(key, value, cleanup=None)
-
     def _record_access(self, node):
         """Record that key was accessed."""
         # Move 'node' to the front of the queue
@@ -241,19 +187,14 @@
         # If we have removed all entries, remove the head pointer as well
         if self._least_recently_used is None:
             self._most_recently_used = None
-        try:
-            node.run_cleanup()
-        finally:
-            # cleanup might raise an exception, but we want to make sure to
-            # maintain the linked list
-            if node.prev is not None:
-                node.prev.next_key = node.next_key
-            if node.next_key is not _null_key:
-                node_next = self._cache[node.next_key]
-                node_next.prev = node.prev
-            # And remove this node's pointers
-            node.prev = None
-            node.next_key = _null_key
+        if node.prev is not None:
+            node.prev.next_key = node.next_key
+        if node.next_key is not _null_key:
+            node_next = self._cache[node.next_key]
+            node_next.prev = node.prev
+        # And remove this node's pointers
+        node.prev = None
+        node.next_key = _null_key
 
     def _remove_lru(self):
         """Remove one entry from the lru, and handle consequences.
@@ -316,17 +257,8 @@
         self._update_max_size(max_size, after_cleanup_size=after_cleanup_size)
         LRUCache.__init__(self, max_cache=max(int(max_size/512), 1))
 
-    def add(self, key, value, cleanup=None):
-        """Add a new value to the cache.
-
-        Also, if the entry is ever removed from the cache, call
-        cleanup(key, value).
-
-        :param key: The key to store it under
-        :param value: The object to store
-        :param cleanup: None or a function taking (key, value) to indicate
-                        'value' should be cleaned up.
-        """
+    def __setitem__(self, key, value):
+        """Add a new value to the cache"""
         if key is _null_key:
             raise ValueError('cannot use _null_key as a key')
         node = self._cache.get(key, None)
@@ -341,15 +273,12 @@
             if node is not None:
                 # We won't be replacing the old node, so just remove it
                 self._remove_node(node)
-            if cleanup is not None:
-                cleanup(key, value)
             return
         if node is None:
-            node = _LRUNode(key, value, cleanup=cleanup)
+            node = _LRUNode(key, value)
             self._cache[key] = node
         else:
-            self._value_size -= node.size
-        node.size = value_len
+            self._value_size -= self._compute_size(node.value)
         self._value_size += value_len
         self._record_access(node)
 
@@ -368,7 +297,7 @@
             self._remove_lru()
 
     def _remove_node(self, node):
-        self._value_size -= node.size
+        self._value_size -= self._compute_size(node.value)
         LRUCache._remove_node(self, node)
 
     def resize(self, max_size, after_cleanup_size=None):

=== modified file 'bzrlib/tests/test_lru_cache.py'
--- a/bzrlib/tests/test_lru_cache.py	2011-05-13 12:51:05 +0000
+++ b/bzrlib/tests/test_lru_cache.py	2011-10-14 18:42:17 +0000
@@ -18,10 +18,43 @@
 
 from bzrlib import (
     lru_cache,
+    symbol_versioning,
     tests,
     )
 
 
+def walk_lru(lru):
+    """Test helper to walk the LRU list and assert its consistency"""
+    node = lru._most_recently_used
+    if node is not None:
+        if node.prev is not None:
+            raise AssertionError('the _most_recently_used entry is not'
+                                 ' supposed to have a previous entry'
+                                 ' %s' % (node,))
+    while node is not None:
+        if node.next_key is lru_cache._null_key:
+            if node is not lru._least_recently_used:
+                raise AssertionError('only the last node should have'
+                                     ' no next value: %s' % (node,))
+            node_next = None
+        else:
+            node_next = lru._cache[node.next_key]
+            if node_next.prev is not node:
+                raise AssertionError('inconsistency found, node.next.prev'
+                                     ' != node: %s' % (node,))
+        if node.prev is None:
+            if node is not lru._most_recently_used:
+                raise AssertionError('only the _most_recently_used should'
+                                     ' not have a previous node: %s'
+                                     % (node,))
+        else:
+            if node.prev.next_key != node.key:
+                raise AssertionError('inconsistency found, node.prev.next'
+                                     ' != node: %s' % (node,))
+        yield node
+        node = node_next
+
+ 
 class TestLRUCache(tests.TestCase):
     """Test that LRU cache properly keeps track of entries."""
 
@@ -61,11 +94,12 @@
         cache[None]
         cache[1]
         cache[None]
-        self.assertEqual([None, 1], [n.key for n in cache._walk_lru()])
+        self.assertEqual([None, 1], [n.key for n in walk_lru(cache)])
 
     def test_add__null_key(self):
         cache = lru_cache.LRUCache(max_cache=10)
-        self.assertRaises(ValueError, cache.add, lru_cache._null_key, 1)
+        self.assertRaises(ValueError,
+            cache.__setitem__, lru_cache._null_key, 1)
 
     def test_overflow(self):
         """Adding extra entries will pop out old ones."""
@@ -94,80 +128,12 @@
 
         self.assertFalse('foo' in cache)
 
-    def test_cleanup(self):
-        """Test that we can use a cleanup function."""
-        cleanup_called = []
-        def cleanup_func(key, val):
-            cleanup_called.append((key, val))
-
-        cache = lru_cache.LRUCache(max_cache=2)
-
-        cache.add('baz', '1', cleanup=cleanup_func)
-        cache.add('foo', '2', cleanup=cleanup_func)
-        cache.add('biz', '3', cleanup=cleanup_func)
-
-        self.assertEqual([('baz', '1')], cleanup_called)
-
-        # 'foo' is now most recent, so final cleanup will call it last
-        cache['foo']
-        cache.clear()
-        self.assertEqual([('baz', '1'), ('biz', '3'), ('foo', '2')],
-                         cleanup_called)
-
-    def test_cleanup_on_replace(self):
-        """Replacing an object should cleanup the old value."""
-        cleanup_called = []
-        def cleanup_func(key, val):
-            cleanup_called.append((key, val))
-
-        cache = lru_cache.LRUCache(max_cache=2)
-        cache.add(1, 10, cleanup=cleanup_func)
-        cache.add(2, 20, cleanup=cleanup_func)
-        cache.add(2, 25, cleanup=cleanup_func)
-
-        self.assertEqual([(2, 20)], cleanup_called)
-        self.assertEqual(25, cache[2])
-
-        # Even __setitem__ should make sure cleanup() is called
-        cache[2] = 26
-        self.assertEqual([(2, 20), (2, 25)], cleanup_called)
-
-    def test_cleanup_error_maintains_linked_list(self):
-        cleanup_called = []
-        def cleanup_func(key, val):
-            cleanup_called.append((key, val))
-            raise ValueError('failure during cleanup')
-
-        cache = lru_cache.LRUCache(max_cache=10)
-        for i in xrange(10):
-            cache.add(i, i, cleanup=cleanup_func)
-        for i in xrange(10, 20):
-            self.assertRaises(ValueError,
-                cache.add, i, i, cleanup=cleanup_func)
-
-        self.assertEqual([(i, i) for i in xrange(10)], cleanup_called)
-
-        self.assertEqual(range(19, 9, -1), [n.key for n in cache._walk_lru()])
-
-    def test_cleanup_during_replace_still_replaces(self):
-        cleanup_called = []
-        def cleanup_func(key, val):
-            cleanup_called.append((key, val))
-            raise ValueError('failure during cleanup')
-
-        cache = lru_cache.LRUCache(max_cache=10)
-        for i in xrange(10):
-            cache.add(i, i, cleanup=cleanup_func)
-        self.assertRaises(ValueError,
-            cache.add, 1, 20, cleanup=cleanup_func)
-        # We also still update the recent access to this node
-        self.assertEqual([1, 9, 8, 7, 6, 5, 4, 3, 2, 0],
-                         [n.key for n in cache._walk_lru()])
-        self.assertEqual(20, cache[1])
-
-        self.assertEqual([(1, 1)], cleanup_called)
-        self.assertEqual([1, 9, 8, 7, 6, 5, 4, 3, 2, 0],
-                         [n.key for n in cache._walk_lru()])
+    def test_cleanup_function_deprecated(self):
+        """Test that per-node cleanup functions are no longer allowed"""
+        cache = lru_cache.LRUCache()
+        self.assertRaises(ValueError, self.applyDeprecated,
+            symbol_versioning.deprecated_in((2, 5, 0)),
+            cache.add, "key", 1, cleanup=lambda: None)
 
     def test_len(self):
         cache = lru_cache.LRUCache(max_cache=10, after_cleanup_count=10)
@@ -197,21 +163,21 @@
         # We hit the max
         self.assertEqual(10, len(cache))
         self.assertEqual([11, 10, 9, 1, 8, 7, 6, 5, 4, 3],
-                         [n.key for n in cache._walk_lru()])
+                         [n.key for n in walk_lru(cache)])
 
     def test_cleanup_shrinks_to_after_clean_count(self):
         cache = lru_cache.LRUCache(max_cache=5, after_cleanup_count=3)
 
-        cache.add(1, 10)
-        cache.add(2, 20)
-        cache.add(3, 25)
-        cache.add(4, 30)
-        cache.add(5, 35)
+        cache[1] = 10
+        cache[2] = 20
+        cache[3] = 25
+        cache[4] = 30
+        cache[5] = 35
 
         self.assertEqual(5, len(cache))
         # This will bump us over the max, which causes us to shrink down to
         # after_cleanup_cache size
-        cache.add(6, 40)
+        cache[6] = 40
         self.assertEqual(3, len(cache))
 
     def test_after_cleanup_larger_than_max(self):
@@ -227,11 +193,11 @@
         cache = lru_cache.LRUCache(max_cache=5, after_cleanup_count=2)
 
         # Add these in order
-        cache.add(1, 10)
-        cache.add(2, 20)
-        cache.add(3, 25)
-        cache.add(4, 30)
-        cache.add(5, 35)
+        cache[1] = 10
+        cache[2] = 20
+        cache[3] = 25
+        cache[4] = 30
+        cache[5] = 35
 
         self.assertEqual(5, len(cache))
         # Force a compaction
@@ -242,33 +208,33 @@
         cache = lru_cache.LRUCache(max_cache=5)
 
         # Add these in order
-        cache.add(1, 10)
-        cache.add(2, 20)
-        cache.add(3, 25)
-        cache.add(4, 30)
-        cache.add(5, 35)
+        cache[1] = 10
+        cache[2] = 20
+        cache[3] = 25
+        cache[4] = 30
+        cache[5] = 35
 
-        self.assertEqual([5, 4, 3, 2, 1], [n.key for n in cache._walk_lru()])
+        self.assertEqual([5, 4, 3, 2, 1], [n.key for n in walk_lru(cache)])
 
         # Now access some randomly
         cache[2]
         cache[5]
         cache[3]
         cache[2]
-        self.assertEqual([2, 3, 5, 4, 1], [n.key for n in cache._walk_lru()])
+        self.assertEqual([2, 3, 5, 4, 1], [n.key for n in walk_lru(cache)])
 
     def test_get(self):
         cache = lru_cache.LRUCache(max_cache=5)
 
-        cache.add(1, 10)
-        cache.add(2, 20)
+        cache[1] = 10
+        cache[2] = 20
         self.assertEqual(20, cache.get(2))
         self.assertIs(None, cache.get(3))
         obj = object()
         self.assertIs(obj, cache.get(3, obj))
-        self.assertEqual([2, 1], [n.key for n in cache._walk_lru()])
+        self.assertEqual([2, 1], [n.key for n in walk_lru(cache)])
         self.assertEqual(10, cache.get(1))
-        self.assertEqual([1, 2], [n.key for n in cache._walk_lru()])
+        self.assertEqual([1, 2], [n.key for n in walk_lru(cache)])
 
     def test_keys(self):
         cache = lru_cache.LRUCache(max_cache=5, after_cleanup_count=5)
@@ -332,18 +298,19 @@
 
     def test_add__null_key(self):
         cache = lru_cache.LRUSizeCache()
-        self.assertRaises(ValueError, cache.add, lru_cache._null_key, 1)
+        self.assertRaises(ValueError,
+            cache.__setitem__, lru_cache._null_key, 1)
 
     def test_add_tracks_size(self):
         cache = lru_cache.LRUSizeCache()
         self.assertEqual(0, cache._value_size)
-        cache.add('my key', 'my value text')
+        cache['my key'] = 'my value text'
         self.assertEqual(13, cache._value_size)
 
     def test_remove_tracks_size(self):
         cache = lru_cache.LRUSizeCache()
         self.assertEqual(0, cache._value_size)
-        cache.add('my key', 'my value text')
+        cache['my key'] = 'my value text'
         self.assertEqual(13, cache._value_size)
         node = cache._cache['my key']
         cache._remove_node(node)
@@ -353,64 +320,48 @@
         """Adding a large value may not be cached at all."""
         cache = lru_cache.LRUSizeCache(max_size=10, after_cleanup_size=5)
         self.assertEqual(0, cache._value_size)
-        self.assertEqual({}, cache.items())
-        cache.add('test', 'key')
-        self.assertEqual(3, cache._value_size)
-        self.assertEqual({'test': 'key'}, cache.items())
-        cache.add('test2', 'key that is too big')
-        self.assertEqual(3, cache._value_size)
-        self.assertEqual({'test':'key'}, cache.items())
+        self.assertEqual({}, cache.as_dict())
+        cache['test'] = 'key'
+        self.assertEqual(3, cache._value_size)
+        self.assertEqual({'test': 'key'}, cache.as_dict())
+        cache['test2'] = 'key that is too big'
+        self.assertEqual(3, cache._value_size)
+        self.assertEqual({'test':'key'}, cache.as_dict())
         # If we would add a key, only to cleanup and remove all cached entries,
         # then obviously that value should not be stored
-        cache.add('test3', 'bigkey')
-        self.assertEqual(3, cache._value_size)
-        self.assertEqual({'test':'key'}, cache.items())
-
-        cache.add('test4', 'bikey')
-        self.assertEqual(3, cache._value_size)
-        self.assertEqual({'test':'key'}, cache.items())
-
-    def test_no_add_over_size_cleanup(self):
-        """If a large value is not cached, we will call cleanup right away."""
-        cleanup_calls = []
-        def cleanup(key, value):
-            cleanup_calls.append((key, value))
-
-        cache = lru_cache.LRUSizeCache(max_size=10, after_cleanup_size=5)
-        self.assertEqual(0, cache._value_size)
-        self.assertEqual({}, cache.items())
-        cache.add('test', 'key that is too big', cleanup=cleanup)
-        # key was not added
-        self.assertEqual(0, cache._value_size)
-        self.assertEqual({}, cache.items())
-        # and cleanup was called
-        self.assertEqual([('test', 'key that is too big')], cleanup_calls)
+        cache['test3'] = 'bigkey'
+        self.assertEqual(3, cache._value_size)
+        self.assertEqual({'test':'key'}, cache.as_dict())
+
+        cache['test4'] = 'bikey'
+        self.assertEqual(3, cache._value_size)
+        self.assertEqual({'test':'key'}, cache.as_dict())
 
     def test_adding_clears_cache_based_on_size(self):
         """The cache is cleared in LRU order until small enough"""
         cache = lru_cache.LRUSizeCache(max_size=20)
-        cache.add('key1', 'value') # 5 chars
-        cache.add('key2', 'value2') # 6 chars
-        cache.add('key3', 'value23') # 7 chars
+        cache['key1'] = 'value' # 5 chars
+        cache['key2'] = 'value2' # 6 chars
+        cache['key3'] = 'value23' # 7 chars
         self.assertEqual(5+6+7, cache._value_size)
         cache['key2'] # reference key2 so it gets a newer reference time
-        cache.add('key4', 'value234') # 8 chars, over limit
+        cache['key4'] = 'value234' # 8 chars, over limit
         # We have to remove 2 keys to get back under limit
         self.assertEqual(6+8, cache._value_size)
         self.assertEqual({'key2':'value2', 'key4':'value234'},
-                         cache.items())
+                         cache.as_dict())
 
     def test_adding_clears_to_after_cleanup_size(self):
         cache = lru_cache.LRUSizeCache(max_size=20, after_cleanup_size=10)
-        cache.add('key1', 'value') # 5 chars
-        cache.add('key2', 'value2') # 6 chars
-        cache.add('key3', 'value23') # 7 chars
+        cache['key1'] = 'value' # 5 chars
+        cache['key2'] = 'value2' # 6 chars
+        cache['key3'] = 'value23' # 7 chars
         self.assertEqual(5+6+7, cache._value_size)
         cache['key2'] # reference key2 so it gets a newer reference time
-        cache.add('key4', 'value234') # 8 chars, over limit
+        cache['key4'] = 'value234' # 8 chars, over limit
         # We have to remove 3 keys to get back under limit
         self.assertEqual(8, cache._value_size)
-        self.assertEqual({'key4':'value234'}, cache.items())
+        self.assertEqual({'key4':'value234'}, cache.as_dict())
 
     def test_custom_sizes(self):
         def size_of_list(lst):
@@ -418,23 +369,23 @@
         cache = lru_cache.LRUSizeCache(max_size=20, after_cleanup_size=10,
                                        compute_size=size_of_list)
 
-        cache.add('key1', ['val', 'ue']) # 5 chars
-        cache.add('key2', ['val', 'ue2']) # 6 chars
-        cache.add('key3', ['val', 'ue23']) # 7 chars
+        cache['key1'] = ['val', 'ue'] # 5 chars
+        cache['key2'] = ['val', 'ue2'] # 6 chars
+        cache['key3'] = ['val', 'ue23'] # 7 chars
         self.assertEqual(5+6+7, cache._value_size)
         cache['key2'] # reference key2 so it gets a newer reference time
-        cache.add('key4', ['value', '234']) # 8 chars, over limit
+        cache['key4'] = ['value', '234'] # 8 chars, over limit
         # We have to remove 3 keys to get back under limit
         self.assertEqual(8, cache._value_size)
-        self.assertEqual({'key4':['value', '234']}, cache.items())
+        self.assertEqual({'key4':['value', '234']}, cache.as_dict())
 
     def test_cleanup(self):
         cache = lru_cache.LRUSizeCache(max_size=20, after_cleanup_size=10)
 
         # Add these in order
-        cache.add('key1', 'value') # 5 chars
-        cache.add('key2', 'value2') # 6 chars
-        cache.add('key3', 'value23') # 7 chars
+        cache['key1'] = 'value' # 5 chars
+        cache['key2'] = 'value2' # 6 chars
+        cache['key3'] = 'value23' # 7 chars
         self.assertEqual(5+6+7, cache._value_size)
 
         cache.cleanup()

=== modified file 'doc/en/release-notes/bzr-2.5.txt'
--- a/doc/en/release-notes/bzr-2.5.txt	2011-10-25 12:50:34 +0000
+++ b/doc/en/release-notes/bzr-2.5.txt	2011-10-27 15:14:04 +0000
@@ -81,6 +81,9 @@
 
 * ``Branch.revision_history`` is now deprecated. (Jelmer Vernooij, #799519)
 
+* Methods ``add`` and ``items`` of ``LRUCache`` and ``LRUSizeCache`` are
+  deprecated. Use normal dict-style access instead. (Martin Packman)
+
 * New flag ``RepositoryFormat.supports_unreferenced_revisions`` which
   indicates whether revisions can be present in a repository without
   being referenced from e.g. a branch history at the same time.




More information about the bazaar-commits mailing list