Rev 2630: Implement get_ancestry/get_ancestry_with_ghosts for KnitGraphIndex. in http://people.ubuntu.com/~robertc/baz2.0/repository

Robert Collins robertc at robertcollins.net
Fri Jul 13 18:10:06 BST 2007


At http://people.ubuntu.com/~robertc/baz2.0/repository

------------------------------------------------------------
revno: 2630
revision-id: robertc at robertcollins.net-20070713171003-7ivoysxi2sdabzcq
parent: robertc at robertcollins.net-20070713164209-1p6ng85f0ca9r4b4
committer: Robert Collins <robertc at robertcollins.net>
branch nick: repository
timestamp: Sat 2007-07-14 03:10:03 +1000
message:
  Implement get_ancestry/get_ancestry_with_ghosts for KnitGraphIndex.
modified:
  bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
  bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
=== modified file 'bzrlib/knit.py'
--- a/bzrlib/knit.py	2007-07-13 15:46:54 +0000
+++ b/bzrlib/knit.py	2007-07-13 17:10:03 +0000
@@ -1329,6 +1329,55 @@
         """
         self._graph_index = graph_index
 
+    def get_ancestry(self, versions, topo_sorted=True):
+        """See VersionedFile.get_ancestry."""
+        # XXX: This will do len(history) index calls - perhaps
+        # it should be altered to be a index core feature?
+        # get a graph of all the mentioned versions:
+        graph = {}
+        pending = set(versions)
+        while pending:
+            # get all pending nodes
+            this_iteration = pending
+            new_nodes = self._graph_index.iter_entries(this_iteration)
+            pending = set()
+            for (key, node_refs, value) in new_nodes:
+                graph[key] = node_refs[0]
+                # queue parents 
+                pending.update(graph[key])
+            missing_versions = this_iteration.difference(graph)
+            if missing_versions:
+                raise RevisionNotPresent(missing_versions.pop(), self)
+            # dont examine known nodes
+            pending.difference_update(graph)
+        if not topo_sorted:
+            return graph.keys()
+        return topo_sort(graph.items())
+
+    def get_ancestry_with_ghosts(self, versions):
+        """See VersionedFile.get_ancestry."""
+        # XXX: This will do len(history) index calls - perhaps
+        # it should be altered to be a index core feature?
+        # get a graph of all the mentioned versions:
+        graph = {}
+        pending = set(versions)
+        while pending:
+            # get all pending nodes
+            this_iteration = pending
+            new_nodes = self._graph_index.iter_entries(this_iteration)
+            pending = set()
+            for (key, node_refs, value) in new_nodes:
+                graph[key] = node_refs[0]
+                # queue parents 
+                pending.update(graph[key])
+            missing_versions = this_iteration.difference(graph)
+            for missing_version in missing_versions:
+                # add a key, no parents
+                graph[missing_version] = []
+            # dont examine known nodes
+            pending.difference_update(graph)
+        return topo_sort(graph.items())
+
     def get_graph(self):
         """Return a list of the node:parents lists from this knit index."""
         return [(key, refs[0]) for (key, refs, value) in 

=== modified file 'bzrlib/tests/test_knit.py'
--- a/bzrlib/tests/test_knit.py	2007-07-13 15:46:54 +0000
+++ b/bzrlib/tests/test_knit.py	2007-07-13 17:10:03 +0000
@@ -1541,7 +1541,7 @@
         trans.put_file(name, stream)
         return GraphIndex(trans, name)
 
-    def test_get_graph(self):
+    def two_graph_index(self):
         # build a complex graph across several indices.
         index1 = self.make_g_index('1', 1, [
             ('tip', (['parent'], ), ''),
@@ -1550,10 +1550,73 @@
             ('parent', (['tail', 'ghost'], ), ''),
             ('separate', ([], ), '')])
         combined_index = CombinedGraphIndex([index1, index2])
-        index = KnitGraphIndex(combined_index)
+        return KnitGraphIndex(combined_index)
+
+    def two_graph_index_no_ghosts(self):
+        # build a complex graph across several indices.
+        index1 = self.make_g_index('1', 1, [
+            ('tip', (['parent'], ), ''),
+            ('tail', ([], ), '')])
+        index2 = self.make_g_index('2', 1, [
+            ('parent', (['tail'], ), ''),
+            ('separate', ([], ), '')])
+        combined_index = CombinedGraphIndex([index1, index2])
+        return KnitGraphIndex(combined_index)
+
+    def test_get_graph(self):
+        index = self.two_graph_index()
         self.assertEqual(set([
             ('tip', ('parent', )),
             ('tail', ()),
             ('parent', ('tail', 'ghost')),
             ('separate', ()),
             ]), set(index.get_graph()))
+
+    def test_get_ancestry(self):
+        index = self.two_graph_index_no_ghosts()
+        self.assertEqual([], index.get_ancestry([]))
+        self.assertEqual(['separate'], index.get_ancestry(['separate']))
+        self.assertEqual(['tail'], index.get_ancestry(['tail']))
+        self.assertEqual(['tail', 'parent'], index.get_ancestry(['parent']))
+        self.assertEqual(['tail', 'parent', 'tip'], index.get_ancestry(['tip']))
+        self.assertTrue(index.get_ancestry(['tip', 'separate']) in
+            (['tail', 'parent', 'tip', 'separate'],
+             ['separate', 'tail', 'parent', 'tip'],
+            ))
+        # and without topo_sort
+        self.assertEqual(set(['separate']),
+            set(index.get_ancestry(['separate'], topo_sorted=False)))
+        self.assertEqual(set(['tail']),
+            set(index.get_ancestry(['tail'], topo_sorted=False)))
+        self.assertEqual(set(['tail', 'parent']),
+            set(index.get_ancestry(['parent'], topo_sorted=False)))
+        self.assertEqual(set(['tail', 'parent', 'tip']),
+            set(index.get_ancestry(['tip'], topo_sorted=False)))
+        self.assertEqual(set(['separate', 'tail', 'parent', 'tip']),
+            set(index.get_ancestry(['tip', 'separate'])))
+        # with ghosts it blows up early
+        index = self.two_graph_index()
+        self.assertEqual([], index.get_ancestry([]))
+        self.assertEqual(['separate'], index.get_ancestry(['separate']))
+        self.assertEqual(['tail'], index.get_ancestry(['tail']))
+        self.assertRaises(errors.RevisionNotPresent, index.get_ancestry, ['parent'])
+
+    def test_get_ancestry_with_ghosts(self):
+        index = self.two_graph_index()
+        self.assertEqual([], index.get_ancestry_with_ghosts([]))
+        self.assertEqual(['separate'], index.get_ancestry_with_ghosts(['separate']))
+        self.assertEqual(['tail'], index.get_ancestry_with_ghosts(['tail']))
+        self.assertTrue(index.get_ancestry_with_ghosts(['parent']) in
+            (['tail', 'ghost', 'parent'],
+             ['ghost', 'tail', 'parent'],
+            ))
+        self.assertTrue(index.get_ancestry_with_ghosts(['tip']) in
+            (['tail', 'ghost', 'parent', 'tip'],
+             ['ghost', 'tail', 'parent', 'tip'],
+            ))
+        self.assertTrue(index.get_ancestry_with_ghosts(['tip', 'separate']) in
+            (['tail', 'ghost', 'parent', 'tip', 'separate'],
+             ['ghost', 'tail', 'parent', 'tip', 'separate'],
+             ['separate', 'tail', 'ghost', 'parent', 'tip'],
+             ['separate', 'ghost', 'tail', 'parent', 'tip'],
+            ))




More information about the bazaar-commits mailing list