Rev 3874: Add a VFDecorator that can yield records in a specified order in http://bzr.arbash-meinel.com/branches/bzr/1.10-dev/304841-not-present-chain
John Arbash Meinel
john at arbash-meinel.com
Wed Dec 3 21:05:14 GMT 2008
At http://bzr.arbash-meinel.com/branches/bzr/1.10-dev/304841-not-present-chain
------------------------------------------------------------
revno: 3874
revision-id: john at arbash-meinel.com-20081203210501-fejpuwpvfkvwogxd
parent: pqm at pqm.ubuntu.com-20081202062535-khqslu9vyrvzr7om
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 304841-not-present-chain
timestamp: Wed 2008-12-03 15:05:01 -0600
message:
Add a VFDecorator that can yield records in a specified order
-------------- next part --------------
=== modified file 'bzrlib/tests/test_versionedfile.py'
--- a/bzrlib/tests/test_versionedfile.py 2008-07-17 09:13:16 +0000
+++ b/bzrlib/tests/test_versionedfile.py 2008-12-03 21:05:01 +0000
@@ -2218,3 +2218,58 @@
record = it.next()
self.assertEquals("absent", record.storage_kind)
+
+class TestOrderingVersionedFilesDecorator(TestCaseWithMemoryTransport):
+
+ def get_ordering_vf(self, key_priority):
+ builder = self.make_branch_builder('test')
+ builder.start_series()
+ builder.build_snapshot('A', None, [
+ ('add', ('', 'TREE_ROOT', 'directory', None))])
+ builder.build_snapshot('B', ['A'], [])
+ builder.build_snapshot('C', ['B'], [])
+ builder.build_snapshot('D', ['C'], [])
+ builder.finish_series()
+ b = builder.get_branch()
+ b.lock_read()
+ self.addCleanup(b.unlock)
+ vf = b.repository.inventories
+ return versionedfile.OrderingVersionedFilesDecorator(vf, key_priority)
+
+ def test_get_empty(self):
+ vf = self.get_ordering_vf({})
+ self.assertEqual([], vf.calls)
+
+ def test_get_record_stream_topological(self):
+ vf = self.get_ordering_vf({('A',): 3, ('B',): 2, ('C',): 4, ('D',): 1})
+ request_keys = [('B',), ('C',), ('D',), ('A',)]
+ keys = [r.key for r in vf.get_record_stream(request_keys,
+ 'topological', False)]
+ # We should have gotten the keys in topological order
+ self.assertEqual([('A',), ('B',), ('C',), ('D',)], keys)
+ # And recorded that the request was made
+ self.assertEqual([('get_record_stream', request_keys, 'topological',
+ False)], vf.calls)
+
+ def test_get_record_stream_ordered(self):
+ vf = self.get_ordering_vf({('A',): 3, ('B',): 2, ('C',): 4, ('D',): 1})
+ request_keys = [('B',), ('C',), ('D',), ('A',)]
+ keys = [r.key for r in vf.get_record_stream(request_keys,
+ 'unordered', False)]
+ # They should be returned based on their priority
+ self.assertEqual([('D',), ('B',), ('A',), ('C',)], keys)
+ # And the request recorded
+ self.assertEqual([('get_record_stream', request_keys, 'unordered',
+ False)], vf.calls)
+
+ def test_get_record_stream_implicit_order(self):
+ vf = self.get_ordering_vf({('B',): 2, ('D',): 1})
+ request_keys = [('B',), ('C',), ('D',), ('A',)]
+ keys = [r.key for r in vf.get_record_stream(request_keys,
+ 'unordered', False)]
+ # A and C are not in the map, so they get sorted to the front. A comes
+ # before C alphabetically, so it comes back first
+ self.assertEqual([('A',), ('C',), ('D',), ('B',)], keys)
+ # And the request recorded
+ self.assertEqual([('get_record_stream', request_keys, 'unordered',
+ False)], vf.calls)
=== modified file 'bzrlib/versionedfile.py'
--- a/bzrlib/versionedfile.py 2008-11-21 20:20:52 +0000
+++ b/bzrlib/versionedfile.py 2008-12-03 21:05:01 +0000
@@ -521,7 +521,7 @@
"""
def __init__(self, backing_vf):
- """Create a RecordingVersionedFileDsecorator decorating backing_vf.
+ """Create a RecordingVersionedFilesDecorator decorating backing_vf.
:param backing_vf: The versioned file to answer all methods.
"""
@@ -562,6 +562,44 @@
return self._backing_vf.keys()
+class OrderingVersionedFilesDecorator(RecordingVersionedFilesDecorator):
+ """A VF that records calls, and returns keys in specific order.
+
+ :ivar calls: A list of the calls made; can be reset at any time by
+ assigning [] to it.
+ """
+
+ def __init__(self, backing_vf, key_priority):
+ """Create a RecordingVersionedFilesDecorator decorating backing_vf.
+
+ :param backing_vf: The versioned file to answer all methods.
+ :param key_priority: A dictionary defining what order keys should be
+ returned from an 'unordered' get_record_stream request.
+ Keys with lower priority are returned first, keys not present in
+ the map get an implicit priority of 0, and are returned in
+ lexicographical order.
+ """
+ RecordingVersionedFilesDecorator.__init__(self, backing_vf)
+ self._key_priority = key_priority
+
+ def get_record_stream(self, keys, sort_order, include_delta_closure):
+ self.calls.append(("get_record_stream", list(keys), sort_order,
+ include_delta_closure))
+ if sort_order == 'unordered':
+ def sort_key(key):
+ return (self._key_priority.get(key, 0), key)
+ # Use a defined order by asking for the keys one-by-one from the
+ # backing_vf
+ for key in sorted(keys, key=sort_key):
+ for record in self._backing_vf.get_record_stream([key],
+ 'unordered', include_delta_closure):
+ yield record
+ else:
+ for record in self._backing_vf.get_record_stream(keys, sort_order,
+ include_delta_closure):
+ yield record
+
+
class KeyMapper(object):
"""KeyMappers map between keys and underlying partitioned storage."""
More information about the bazaar-commits
mailing list