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