Rev 2643: Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile. in http://people.ubuntu.com/~robertc/baz2.0/repository

Robert Collins robertc at robertcollins.net
Sat Jul 14 00:17:04 BST 2007


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

------------------------------------------------------------
revno: 2643
revision-id: robertc at robertcollins.net-20070713231702-0frzavpyutb51qqb
parent: robertc at robertcollins.net-20070713203605-i1tiuy07vb29oa3y
committer: Robert Collins <robertc at robertcollins.net>
branch nick: repository
timestamp: Sat 2007-07-14 09:17:02 +1000
message:
  Add add_version(s) to KnitGraphIndex, completing the required api for KnitVersionedFile.
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 20:36:05 +0000
+++ b/bzrlib/knit.py	2007-07-13 23:17:02 +0000
@@ -1329,6 +1329,14 @@
         self._graph_index = graph_index
         self._deltas = deltas
 
+    def _get_entries(self, version_ids):
+        """Get the entries for version_ids."""
+        return self._graph_index.iter_entries(version_ids)
+
+    def _present_keys(self, version_ids):
+        return set([
+            node[0] for node in self._get_entries(version_ids)])
+
     def get_ancestry(self, versions, topo_sorted=True):
         """See VersionedFile.get_ancestry."""
         # XXX: This will do len(history) index calls - perhaps
@@ -1339,7 +1347,7 @@
         while pending:
             # get all pending nodes
             this_iteration = pending
-            new_nodes = self._graph_index.iter_entries(this_iteration)
+            new_nodes = self._get_entries(this_iteration)
             pending = set()
             for (key, node_refs, value) in new_nodes:
                 graph[key] = node_refs[0]
@@ -1364,7 +1372,7 @@
         while pending:
             # get all pending nodes
             this_iteration = pending
-            new_nodes = self._graph_index.iter_entries(this_iteration)
+            new_nodes = self._get_entries(this_iteration)
             pending = set()
             for (key, node_refs, value) in new_nodes:
                 graph[key] = node_refs[0]
@@ -1394,7 +1402,7 @@
     
     def has_version(self, version_id):
         """True if the version is in the index."""
-        return len(list(self._graph_index.iter_entries([version_id]))) == 1
+        return len(list(self._get_entries([version_id]))) == 1
 
     def get_position(self, version_id):
         """Return data position and size of specified version."""
@@ -1415,7 +1423,7 @@
             return 'fulltext'
 
     def _get_node(self, version_id):
-        return list(self._graph_index.iter_entries([version_id]))[0]
+        return list(self._get_entries([version_id]))[0]
 
     def get_options(self, version_id):
         """Return a string represention options.
@@ -1437,10 +1445,6 @@
         present_parents = self._present_keys(parents)
         return [key for key in parents if key in present_parents]
 
-    def _present_keys(self, version_ids):
-        return set([
-            node[0] for node in self._graph_index.iter_entries(version_ids)])
-
     def get_parents_with_ghosts(self, version_id):
         """Return parents of specified version with ghosts."""
         return self._get_node(version_id)[1][0]
@@ -1453,6 +1457,53 @@
         if missing:
             raise RevisionNotPresent(missing.pop, self)
 
+    def add_version(self, version_id, options, pos, size, parents):
+        """Add a version record to the index."""
+        return self.add_versions(((version_id, options, pos, size, parents),))
+
+    def add_versions(self, versions):
+        """Add multiple versions to the index.
+        
+        This function does not insert data into the Immutable GraphIndex
+        backing the KnitGraphIndex, instead it prepares data for insertion by
+        the caller and checks that it is safe to insert.
+
+        :param versions: a list of tuples:
+                         (version_id, options, pos, size, parents).
+        :return: A list of (key, node_refs, value) tuples for insertion
+            into a GraphIndex.
+        """
+        # we hope there are no repositories with inconsistent parentage
+        # anymore.
+        # check for dups
+
+        keys = {}
+        for (version_id, options, pos, size, parents) in versions:
+            if 'no-eol' in options:
+                value = 'N'
+            else:
+                value = ' '
+            value += "%d %d" % (pos, size)
+            if self._deltas:
+                if 'line-delta' in options:
+                    node_refs = (tuple(parents), (parents[0],))
+                else:
+                    node_refs = (tuple(parents), ())
+            else:
+                if 'line-delta' in options:
+                    raise KnitCorrupt(self, "attempt to add line-delta in non-delta knit")
+                node_refs = (tuple(parents), )
+            keys[version_id] = (node_refs, value)
+        present_nodes = self._get_entries(keys)
+        for (key, node_refs, value) in present_nodes:
+            if (node_refs, value) != keys[key]:
+                raise KnitCorrupt(self, "inconsistent details in add_versions")
+            del keys[key]
+        result = []
+        for key, (node_refs, value) in keys.iteritems():
+            result.append((key, node_refs, value))
+        return result
+        
 
 class _KnitData(_KnitComponentFile):
     """Contents of the knit data file"""

=== modified file 'bzrlib/tests/test_knit.py'
--- a/bzrlib/tests/test_knit.py	2007-07-13 20:36:05 +0000
+++ b/bzrlib/tests/test_knit.py	2007-07-13 23:17:02 +0000
@@ -1671,6 +1671,96 @@
             ['tail', 'ghost'])
         index.check_versions_present(['tail', 'separate'])
 
+    def test_add_version_smoke(self):
+        index = self.two_graph_index()
+        self.assertEqual([('new', (('separate',),), 'N50 60')],
+            index.add_version('new', 'fulltext,no-eol', 50, 60, ['separate']))
+
+    def test_add_version_delta_not_delta_index(self):
+        index = self.two_graph_index()
+        self.assertRaises(errors.KnitCorrupt, index.add_version,
+            'new', 'no-eol,line-delta', 0, 100, ['parent'])
+
+    def test_add_version_same_dup(self):
+        index = self.two_graph_index()
+        # options can be spelt two different ways
+        self.assertEqual([], list(index.add_version(
+            'tip', 'fulltext,no-eol', 0, 100, ['parent'])))
+        self.assertEqual([], list(index.add_version(
+            'tip', 'no-eol,fulltext', 0, 100, ['parent'])))
+        
+    def test_add_version_different_dup(self):
+        index = self.two_graph_index(deltas=True)
+        # change options
+        self.assertRaises(errors.KnitCorrupt, index.add_version,
+            'tip', 'no-eol,line-delta', 0, 100, ['parent'])
+        self.assertRaises(errors.KnitCorrupt, index.add_version,
+            'tip', 'line-delta,no-eol', 0, 100, ['parent'])
+        self.assertRaises(errors.KnitCorrupt, index.add_version,
+            'tip', 'fulltext', 0, 100, ['parent'])
+        # position/length
+        self.assertRaises(errors.KnitCorrupt, index.add_version,
+            'tip', 'fulltext,no-eol', 50, 100, ['parent'])
+        self.assertRaises(errors.KnitCorrupt, index.add_version,
+            'tip', 'fulltext,no-eol', 0, 1000, ['parent'])
+        # parents
+        self.assertRaises(errors.KnitCorrupt, index.add_version,
+            'tip', 'fulltext,no-eol', 0, 100, [])
+        
+    def test_add_versions_nodeltas(self):
+        index = self.two_graph_index()
+        self.assertEqual([('new', (('separate',),), 'N50 60'),
+            ('new2', (('new',),), ' 0 6')],
+            sorted(index.add_versions([
+                ('new', 'fulltext,no-eol', 50, 60, ['separate']),
+                ('new2', 'fulltext', 0, 6, ['new']),
+                ])))
+
+    def test_add_versions_deltas(self):
+        index = self.two_graph_index(deltas=True)
+        self.assertEqual([('new', (('separate',), ()), 'N50 60'),
+            ('new2', (('new',), ('new',), ), ' 0 6')],
+            sorted(index.add_versions([
+                ('new', 'fulltext,no-eol', 50, 60, ['separate']),
+                ('new2', 'line-delta', 0, 6, ['new']),
+                ])))
+
+    def test_add_versions_delta_not_delta_index(self):
+        index = self.two_graph_index()
+        self.assertRaises(errors.KnitCorrupt, index.add_versions,
+            [('new', 'no-eol,line-delta', 0, 100, ['parent'])])
+
+    def test_add_versions_same_dup(self):
+        index = self.two_graph_index()
+        # options can be spelt two different ways
+        self.assertEqual([], list(index.add_versions([(
+            'tip', 'fulltext,no-eol', 0, 100, ['parent'])])))
+        self.assertEqual([], list(index.add_versions([(
+            'tip', 'no-eol,fulltext', 0, 100, ['parent'])])))
+        
+    def test_add_versions_different_dup(self):
+        index = self.two_graph_index(deltas=True)
+        # change options
+        self.assertRaises(errors.KnitCorrupt, index.add_versions,
+            [('tip', 'no-eol,line-delta', 0, 100, ['parent'])])
+        self.assertRaises(errors.KnitCorrupt, index.add_versions,
+            [('tip', 'line-delta,no-eol', 0, 100, ['parent'])])
+        self.assertRaises(errors.KnitCorrupt, index.add_versions,
+            [('tip', 'fulltext', 0, 100, ['parent'])])
+        # position/length
+        self.assertRaises(errors.KnitCorrupt, index.add_versions,
+            [('tip', 'fulltext,no-eol', 50, 100, ['parent'])])
+        self.assertRaises(errors.KnitCorrupt, index.add_versions,
+            [('tip', 'fulltext,no-eol', 0, 1000, ['parent'])])
+        # parents
+        self.assertRaises(errors.KnitCorrupt, index.add_versions,
+            [('tip', 'fulltext,no-eol', 0, 100, [])])
+        # change options in the second record
+        self.assertRaises(errors.KnitCorrupt, index.add_versions,
+            [('tip', 'fulltext,no-eol', 0, 100, ['parent']),
+             ('tip', 'no-eol,line-delta', 0, 100, ['parent'])])
+        
+
 ## --- mutating tests for later ---
 #
 #  def test_add_version




More information about the bazaar-commits mailing list