Use the new KnownGraph.add_node() functionality.
authorJohn Arbash Meinel <john@arbash-meinel.com>
Mon, 30 Nov 2009 19:00:44 +0000 (13:00 -0600)
committerJohn Arbash Meinel <john@arbash-meinel.com>
Mon, 30 Nov 2009 19:00:44 +0000 (13:00 -0600)
This changes the file_id heads lookups to use a KnownGraph over all revision-ids
which should be a lot better than using a regular Graph instance.
Initial testing w/ xserver doesn't show much, since it seems to be purely
linear for quite a bit of x history.

Oddly enough the heads result seems to give a different number of file texts
which is worrying.

revision_store.py

index 0488b0e6f0d15962ff7ace00f7c0fdb24884b4a9..c40ac0faccb57fb42401a8daed10a694ff64f45e 100644 (file)
 
 import cStringIO
 
-from bzrlib import errors, inventory, knit, lru_cache, osutils, trace
-from bzrlib import revision as _mod_revision
+from bzrlib import (
+    errors,
+    graph as _mod_graph,
+    inventory,
+    knit,
+    lru_cache,
+    osutils,
+    revision as _mod_revision,
+    trace,
+    )
 
 
 class _TreeShim(object):
@@ -150,6 +158,8 @@ class AbstractRevisionStore(object):
         :param repository: the target repository
         """
         self.repo = repo
+        self._graph = None
+        self._use_known_graph = True
         self._supports_chks = getattr(repo._format, 'supports_chks', False)
 
     def expects_rich_root(self):
@@ -346,6 +356,22 @@ class AbstractRevisionStore(object):
             parents=rev.parent_ids, config=None, timestamp=rev.timestamp,
             timezone=rev.timezone, committer=rev.committer,
             revprops=rev.properties, revision_id=rev.revision_id)
+        if self._graph is None and self._use_known_graph:
+            if (getattr(_mod_graph, 'GraphThunkIdsToKeys', None) is None
+                or getattr(_mod_graph.KnownGraph, 'add_node', None) is None):
+                self._use_known_graph = False
+            else:
+                self._graph = self.repo.revisions.get_known_graph_ancestry(
+                    [(r,) for r in rev.parent_ids])
+        if self._graph is not None:
+            def thunked_heads(file_id, revision_ids):
+                # self._graph thinks in terms of keys, not ids, so translate
+                # them
+                if len(revision_ids) < 2:
+                    return set(revision_ids)
+                return set([h[0] for h in
+                            self._graph.heads([(r,) for r in revision_ids])])
+            builder._heads = thunked_heads
 
         if rev.parent_ids:
             basis_rev_id = rev.parent_ids[0]
@@ -370,6 +396,10 @@ class AbstractRevisionStore(object):
         rev.inv_sha1 = builder.inv_sha1
         builder.repository.add_revision(builder._new_revision_id, rev,
             builder.new_inventory, builder._config)
+        if self._graph is not None:
+            # TODO: Use StaticTuple and .intern() for these things
+            self._graph.add_node((builder._new_revision_id,),
+                                 [(p,) for p in rev.parent_ids])
 
         if signature is not None:
             raise AssertionError('signatures not guaranteed yet')