Rev 3179: Create new smart server verb Repository.get_parent_map. in http://people.ubuntu.com/~robertc/baz2.0/remote.graph
Robert Collins
robertc at robertcollins.net
Mon Jan 14 04:46:14 GMT 2008
At http://people.ubuntu.com/~robertc/baz2.0/remote.graph
------------------------------------------------------------
revno: 3179
revision-id:robertc at robertcollins.net-20080114044608-bmse3mmsnp1663rf
parent: robertc at robertcollins.net-20080111071215-n51r2omrs3e7216m
committer: Robert Collins <robertc at robertcollins.net>
branch nick: remote.graph
timestamp: Mon 2008-01-14 15:46:08 +1100
message:
Create new smart server verb Repository.get_parent_map.
modified:
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/smart/repository.py repository.py-20061128022038-vr5wy5bubyb8xttk-1
bzrlib/smart/request.py request.py-20061108095550-gunadhxmzkdjfeek-1
bzrlib/tests/test_remote.py test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
bzrlib/tests/test_smart.py test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py 2008-01-11 05:56:47 +0000
+++ b/bzrlib/remote.py 2008-01-14 04:46:08 +0000
@@ -743,9 +743,42 @@
ancestry = self._parents_map
missing_revisions = set(key for key in keys if key not in ancestry)
if missing_revisions:
- self._parents_map.update(self.get_revision_graph())
+ self._parents_map.update(self._get_parent_map(missing_revisions))
return dict((k, ancestry[k]) for k in keys if k in ancestry)
+ def _get_parent_map(self, keys):
+ """Helper for get_parent_map that performs the RPC."""
+ keys = set(keys)
+ if NULL_REVISION in keys:
+ keys.discard(NULL_REVISION)
+ found_parents = {NULL_REVISION:()}
+ if not keys:
+ return found_parents
+ else:
+ found_parents = {}
+ path = self.bzrdir._path_for_remote_call(self._client)
+ for key in keys:
+ assert type(key) is str
+ response = self._client.call_expecting_body(
+ 'Repository.get_parent_map', path, *keys)
+ if response[0][0] not in ['ok']:
+ raise errors.UnexpectedSmartServerResponse(response[0])
+ if response[0][0] == 'ok':
+ coded = response[1].read_body_bytes()
+ if coded == '':
+ # no revisions found
+ return {}
+ lines = coded.split('\n')
+ revision_graph = {}
+ for line in lines:
+ d = tuple(line.split())
+ if len(d) > 1:
+ revision_graph[d[0]] = d[1:]
+ else:
+ # No parents - so give the Graph result (NULL_REVISION,).
+ revision_graph[d[0]] = (NULL_REVISION,)
+ return revision_graph
+
@needs_read_lock
def get_signature_text(self, revision_id):
self._ensure_real()
=== modified file 'bzrlib/smart/repository.py'
--- a/bzrlib/smart/repository.py 2008-01-02 08:09:32 +0000
+++ b/bzrlib/smart/repository.py 2008-01-14 04:46:08 +0000
@@ -30,6 +30,7 @@
SmartServerRequest,
SuccessfulSmartServerResponse,
)
+from bzrlib import revision as _mod_revision
class SmartServerRepositoryRequest(SmartServerRequest):
@@ -51,6 +52,63 @@
return self.do_repository_request(repository, *args)
+class SmartServerRepositoryGetParentMap(SmartServerRepositoryRequest):
+
+ def do_repository_request(self, repository, *revision_ids):
+ repository.lock_read()
+ try:
+ return self._do_repository_request(repository, revision_ids)
+ finally:
+ repository.unlock()
+
+ def _do_repository_request(self, repository, revision_ids):
+ """Get parent details for some revisions.
+
+ All the parents for revision_ids are returned. Additionally up to 64KB
+ of additional parent data found by performing a breadth first search
+ from revision_ids is returned.
+
+ :param repository: The repository to query in.
+ :param revision_id:s The utf8 encoded revision_id to answer.
+ :return: A smart server response where the body contains an utf8
+ encoded flattened list of the revision graph, (the same format as
+ Repository.get_revision_graph).
+ """
+ lines = []
+ repo_graph = repository.get_graph()
+ result = {}
+ queried_revs = set()
+ size_so_far = 0
+ next_revs = revision_ids
+ first_loop_done = False
+ while next_revs:
+ queried_revs.update(next_revs)
+ parent_map = repo_graph.get_parent_map(next_revs)
+ next_revs = set()
+ for revision_id, parents in parent_map.iteritems():
+ # adjust for the wire
+ if parents == (_mod_revision.NULL_REVISION,):
+ parents = ()
+ # add parents to the result
+ result[revision_id] = parents
+ # prepare the next query
+ next_revs.update(parents)
+ size_so_far += 2 + len(revision_id) + sum(map(len, parents))
+ # get all the directly asked for parents, and then flesh out to
+ # 64K or so.
+ if first_loop_done and size_so_far > 65000:
+ next_revs = set()
+ break
+ # don't query things we've already queried
+ next_revs.difference_update(queried_revs)
+ first_loop_done = True
+
+ for revision, parents in result.items():
+ lines.append(' '.join((revision, ) + tuple(parents)))
+
+ return SuccessfulSmartServerResponse(('ok', ), '\n'.join(lines))
+
+
class SmartServerRepositoryGetRevisionGraph(SmartServerRepositoryRequest):
def do_repository_request(self, repository, revision_id):
=== modified file 'bzrlib/smart/request.py'
--- a/bzrlib/smart/request.py 2008-01-02 07:58:37 +0000
+++ b/bzrlib/smart/request.py 2008-01-14 04:46:08 +0000
@@ -318,6 +318,9 @@
request_handlers.register_lazy('Repository.gather_stats',
'bzrlib.smart.repository',
'SmartServerRepositoryGatherStats')
+request_handlers.register_lazy('Repository.get_parent_map',
+ 'bzrlib.smart.repository',
+ 'SmartServerRepositoryGetParentMap')
request_handlers.register_lazy(
'Repository.stream_knit_data_for_revisions',
'bzrlib.smart.repository',
=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py 2008-01-11 05:56:47 +0000
+++ b/bzrlib/tests/test_remote.py 2008-01-14 04:46:08 +0000
@@ -578,22 +578,22 @@
repo.lock_read()
repo.unlock()
parents = graph.get_parent_map([r1])
- self.assertEqual({r1: ()}, parents)
+ self.assertEqual({r1: (NULL_REVISION,)}, parents)
self.assertEqual(
- [('call_expecting_body', 'Repository.get_revision_graph',
- ('///quack/', ''))],
+ [('call_expecting_body', 'Repository.get_parent_map',
+ ('///quack/', r2))],
client._calls)
repo.unlock()
# now we call again, and it should use the second response.
repo.lock_read()
graph = repo.get_graph()
- parents = graph.get_parent_map([r2])
- self.assertEqual({r2: (r1,)}, parents)
+ parents = graph.get_parent_map([r1])
+ self.assertEqual({r1: (NULL_REVISION,)}, parents)
self.assertEqual(
- [('call_expecting_body', 'Repository.get_revision_graph',
- ('///quack/', '')),
- ('call_expecting_body', 'Repository.get_revision_graph',
- ('///quack/', ''))
+ [('call_expecting_body', 'Repository.get_parent_map',
+ ('///quack/', r2)),
+ ('call_expecting_body', 'Repository.get_parent_map',
+ ('///quack/', r1))
],
client._calls)
repo.unlock()
=== modified file 'bzrlib/tests/test_smart.py'
--- a/bzrlib/tests/test_smart.py 2008-01-02 07:58:37 +0000
+++ b/bzrlib/tests/test_smart.py 2008-01-14 04:46:08 +0000
@@ -919,6 +919,9 @@
smart.request.request_handlers.get('Repository.gather_stats'),
smart.repository.SmartServerRepositoryGatherStats)
self.assertEqual(
+ smart.request.request_handlers.get('Repository.get_parent_map'),
+ smart.repository.SmartServerRepositoryGetParentMap)
+ self.assertEqual(
smart.request.request_handlers.get(
'Repository.get_revision_graph'),
smart.repository.SmartServerRepositoryGetRevisionGraph)
More information about the bazaar-commits
mailing list