Rev 3759: Test unmapping with one child left but multiple keys. in http://people.ubuntu.com/~robertc/baz2.0/repository
Robert Collins
robertc at robertcollins.net
Wed Nov 12 00:39:04 GMT 2008
At http://people.ubuntu.com/~robertc/baz2.0/repository
------------------------------------------------------------
revno: 3759
revision-id: robertc at robertcollins.net-20081112003855-ay7xhc5xhgx3bwt4
parent: robertc at robertcollins.net-20081111100253-hx2ndctrnwilr62i
parent: andrew.bennetts at canonical.com-20081111070622-14i0n8g8meqo4yl8
committer: Robert Collins <robertc at robertcollins.net>
branch nick: repository
timestamp: Wed 2008-11-12 11:38:55 +1100
message:
Test unmapping with one child left but multiple keys.
modified:
bzrlib/chk_map.py chk_map.py-20081001014447-ue6kkuhofvdecvxa-1
bzrlib/inventory.py inventory.py-20050309040759-6648b84ca2005b37
bzrlib/tests/test_chk_map.py test_chk_map.py-20081001014447-ue6kkuhofvdecvxa-2
------------------------------------------------------------
revno: 3756.1.6
revision-id: andrew.bennetts at canonical.com-20081111070622-14i0n8g8meqo4yl8
parent: andrew.bennetts at canonical.com-20081111043629-ojx8u4wob9kwuatt
committer: Andrew Bennetts <andrew.bennetts at canonical.com>
branch nick: chk
timestamp: Tue 2008-11-11 17:06:22 +1000
message:
Make fetch much much faster. Adds CHKMap.copy_to(other_store)
modified:
bzrlib/chk_map.py chk_map.py-20081001014447-ue6kkuhofvdecvxa-1
bzrlib/inventory.py inventory.py-20050309040759-6648b84ca2005b37
bzrlib/tests/test_chk_map.py test_chk_map.py-20081001014447-ue6kkuhofvdecvxa-2
=== modified file 'bzrlib/chk_map.py'
--- a/bzrlib/chk_map.py 2008-11-11 06:02:49 +0000
+++ b/bzrlib/chk_map.py 2008-11-12 00:38:55 +0000
@@ -74,6 +74,20 @@
self.map(new, value)
return self._save()
+ def copy_to(self, store):
+ """Copy all of the refs from this map into store."""
+ root_key = self.key()
+ if root_key in store.get_parent_map([root_key]):
+ # Target already has the content, return
+ return
+ self._ensure_root()
+ keys = self._root_node.refs()
+ present_keys = store.get_parent_map(keys)
+ missing_keys = [key for key in keys if key not in present_keys]
+ missing_keys.append(root_key)
+ store.insert_record_stream(self._store.get_record_stream(
+ missing_keys, 'unordered', False))
+
def _ensure_root(self):
"""Ensure that the root node is an object not a key."""
if type(self._root_node) == tuple:
@@ -634,26 +648,10 @@
else:
# Stash the returned node
self._items[serialised_key] = unmapped
- if len(self) == 1:
+ if len(self._items) == 1:
# this node is no longer needed:
return self._items.values()[0]
return self
- prefix, node_details = child.map(store, key, value)
- if len(node_details) == 1:
- # child may have shrunk, or might be the same.
- self._len = self._len - old_len + len(child)
- self._items[serialised_key] = child
- return self.unique_serialised_prefix(), [("", self)]
- # child has overflown - create a new intermediate node.
- # XXX: This is where we might want to try and expand our depth
- # to refer to more bytes of every child (which would give us
- # multiple pointers to child nodes, but less intermediate nodes)
- child = self._new_child(serialised_key, InternalNode)
- for split, node in node_details:
- child.add_node(split, node)
- self._len = self._len - old_len + len(child)
- return self.unique_serialised_prefix(), [("", self)]
-
class RootNode(Node):
=== modified file 'bzrlib/inventory.py'
--- a/bzrlib/inventory.py 2008-10-22 06:40:59 +0000
+++ b/bzrlib/inventory.py 2008-11-11 07:06:22 +0000
@@ -1441,12 +1441,18 @@
result = CHKInventory()
result.revision_id = inventory.revision_id
result.root_id = inventory.root.file_id
- result.id_to_entry = chk_map.CHKMap(chk_store, None)
- delta = []
- for path, entry in inventory.iter_entries():
- delta.append((None, entry.file_id, result._entry_to_bytes(entry)))
- result.id_to_entry.apply_delta(delta)
- result.id_to_entry._save()
+ if isinstance(inventory, CHKInventory):
+ inventory.id_to_entry.copy_to(chk_store)
+ result.id_to_entry = chk_map.CHKMap(chk_store,
+ inventory.id_to_entry.key())
+ else:
+ result.id_to_entry = chk_map.CHKMap(chk_store, None)
+ delta = []
+ for path, entry in inventory.iter_entries():
+ delta.append((None, entry.file_id,
+ result._entry_to_bytes(entry)))
+ result.id_to_entry.apply_delta(delta)
+ result.id_to_entry._save()
return result
def __getitem__(self, file_id):
=== modified file 'bzrlib/tests/test_chk_map.py'
--- a/bzrlib/tests/test_chk_map.py 2008-11-11 06:02:49 +0000
+++ b/bzrlib/tests/test_chk_map.py 2008-11-12 00:38:55 +0000
@@ -212,6 +212,56 @@
self.assertEqual([key], leaf_node.serialise(chkmap._store))
+class TestCaseWithTwoStores(TestCaseWithTransport):
+
+ def _make_chk_bytes(self, path):
+ repo = self.make_repository(path, format="development3")
+ repo.lock_write()
+ self.addCleanup(repo.unlock)
+ repo.start_write_group()
+ self.addCleanup(repo.abort_write_group)
+ return repo.chk_bytes
+
+ def make_chk_bytes(self):
+ chk_bytes1 = self._make_chk_bytes('a')
+ chk_bytes2 = self._make_chk_bytes('b')
+ return chk_bytes1, chk_bytes2
+
+
+class TestChkMapCopyTo(TestCaseWithTwoStores):
+
+ def disable_insert(self, store):
+ def add_lines_fail(*args, **kwargs):
+ self.fail('We should not need to add any content')
+ def insert_record_stream_fail(*args, **kwargs):
+ self.fail('We should not need to insert any content')
+ store.add_lines = add_lines_fail
+ store.insert_record_stream = insert_record_stream_fail
+
+ def test_to_self(self):
+ chk_bytes1, chk_bytes2 = self.make_chk_bytes()
+ root_key = CHKMap.from_dict(chk_bytes1, {'key': 'value'})
+ chkmap = CHKMap(chk_bytes1, root_key)
+ self.disable_insert(chk_bytes1)
+
+ def test_simple(self):
+ chk_bytes1, chk_bytes2 = self.make_chk_bytes()
+ root_key = CHKMap.from_dict(chk_bytes1, {'key': 'value'})
+ chkmap = CHKMap(chk_bytes1, root_key)
+ chkmap.copy_to(chk_bytes2)
+ newmap = CHKMap(chk_bytes2, root_key)
+ self.assertEqual(chkmap.key(), newmap.key())
+ self.assertEqual({'key': 'value'}, dict(newmap.iteritems()))
+
+ def test_target_has_root(self):
+ chk_bytes1, chk_bytes2 = self.make_chk_bytes()
+ root_key = CHKMap.from_dict(chk_bytes1, {'key': 'value'})
+ chkmap = CHKMap(chk_bytes1, root_key)
+ CHKMap.from_dict(chk_bytes2, {'key': 'value'})
+ self.disable_insert(chk_bytes2)
+ chkmap.copy_to(chk_bytes2)
+
+
class TestRootNode(TestCaseWithTransport):
def test__current_size(self):
@@ -749,6 +799,20 @@
self.assertEqual([keys[-1]], keys)
self.assertEqual(('sha1:d3f06fc03d8f50845894d8d04cc5a3f47e62948d',), keys[-1])
+ def test_unmap_k1_from_k1_k22_k23_gives_k22_k23_tree_new(self):
+ chkmap = self._get_map(
+ {('k1',):'foo', ('k22',):'bar', ('k23',): 'quux'}, maximum_size=10)
+ # Check we have the expected tree.
+ self.assertEqual(('sha1:d68cd97c95e847d3dc58c05537aa5fdcdf2cf5da',),
+ chkmap._root_node)
+ chkmap._ensure_root()
+ node = chkmap._root_node
+ k2_ptr = node._items['k2']
+ # unmapping k21 should give us a root, with k22 and k23 as direct
+ # children, and should not have needed to page in the subtree.
+ result = node.unmap(chkmap._store, ('k1',))
+ self.assertEqual(k2_ptr, result)
+
def test_unmap_second_last_shrinks_to_other_branch(self):
# unmapping the second last child of an internal node downgrades it to
# a leaf node.
More information about the bazaar-commits
mailing list