Rev 3361: Test inserting a stream that overlaps the current content of a knit does not error. in http://people.ubuntu.com/~robertc/baz2.0/versioned_files

Robert Collins robertc at robertcollins.net
Thu Apr 24 05:27:52 BST 2008


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

------------------------------------------------------------
revno: 3361
revision-id: robertc at robertcollins.net-20080424042745-zouzpwd67ftfk0wn
parent: robertc at robertcollins.net-20080424021533-9nny6ki3w6cqvuxd
committer: Robert Collins <robertc at robertcollins.net>
branch nick: data_stream_revamp
timestamp: Thu 2008-04-24 14:27:45 +1000
message:
  Test inserting a stream that overlaps the current content of a knit does not error.
modified:
  bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
  bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
  bzrlib/weave.py                knit.py-20050627021749-759c29984154256b
=== modified file 'bzrlib/knit.py'
--- a/bzrlib/knit.py	2008-04-24 02:15:33 +0000
+++ b/bzrlib/knit.py	2008-04-24 04:27:45 +0000
@@ -1067,16 +1067,18 @@
                 adapters[adapter_key] = adapter
                 return adapter
         if self.factory.annotated:
+            # self is annotated, we need annotated knits to use directly.
             annotated = "annotated-"
-            fallback_conversions = []
+            convertibles = []
         else:
+            # self is not annotated, but we can strip annotations cheaply.
             annotated = ""
-            # We can strip annotations cheaply (but we can't add them cheaply)
-            fallback_conversions = set(["knit-delta-gz", "knit-ft-gz"])
+            convertibles = set(["knit-annotated-delta-gz",
+                "knit-annotated-ft-gz"])
         native_types = set()
         native_types.add("knit-%sdelta-gz" % annotated)
         native_types.add("knit-%sft-gz" % annotated)
-        knit_types = native_types.union(fallback_conversions)
+        knit_types = native_types.union(convertibles)
         adapters = {}
         for record in stream:
             # adapt to non-tuple interface
@@ -1096,7 +1098,14 @@
                 options = [record._build_details[0]]
                 if record._build_details[1]:
                     options.append('no-eol')
-                # Just blat it across
+                # Just blat it across.
+                # Note: This does end up adding data on duplicate keys. As
+                # modern repositories use atomic insertions this should not
+                # lead to excessive growth in the event of interrupted fetches.
+                # 'knit' repositories may suffer excessive growth, but as a
+                # deprecated format this is tolerable. It can be fixed if
+                # needed by in the kndx index support raising on a duplicate
+                # add with identical parents and options.
                 self._add_raw_records(
                     [(record.key[0], options, parents, len(bytes))],
                     bytes)
@@ -1108,7 +1117,10 @@
                 adapter = get_adapter(adapter_key)
                 lines = split_lines(adapter.get_bytes(
                     record, record.get_bytes_as(record.storage_kind)))
-                self.add_lines(record.key[0], parents, lines)
+                try:
+                    self.add_lines(record.key[0], parents, lines)
+                except errors.RevisionAlreadyPresent:
+                    pass
 
     def versions(self):
         """See VersionedFile.versions."""

=== modified file 'bzrlib/tests/test_versionedfile.py'
--- a/bzrlib/tests/test_versionedfile.py	2008-04-23 05:17:05 +0000
+++ b/bzrlib/tests/test_versionedfile.py	2008-04-24 04:27:45 +0000
@@ -53,7 +53,7 @@
 from bzrlib.weavefile import read_weave, write_weave
 
 
-def get_diamond_vf(f, trailing_eol=True):
+def get_diamond_vf(f, trailing_eol=True, left_only=False):
     """Get a diamond graph to exercise deltas and merges.
     
     :param trailing_eol: If True end the last line with \n.
@@ -73,10 +73,11 @@
     f.add_lines('origin', [], ['origin' + last_char])
     f.add_lines('base', ['origin'], ['base' + last_char])
     f.add_lines('left', ['base'], ['base\n', 'left' + last_char])
-    f.add_lines('right', ['base'],
-        ['base\n', 'right' + last_char])
-    f.add_lines('merged', ['left', 'right'],
-        ['base\n', 'left\n', 'right\n', 'merged' + last_char])
+    if not left_only:
+        f.add_lines('right', ['base'],
+            ['base\n', 'right' + last_char])
+        f.add_lines('merged', ['left', 'right'],
+            ['base\n', 'left\n', 'right\n', 'merged' + last_char])
     return f, parents
 
 
@@ -284,6 +285,19 @@
         f.insert_record_stream(stream)
         self.assertIdenticalVersionedFile(f, source)
 
+    def test_insert_record_stream_existing_keys(self):
+        """Inserting keys already in a file should not error."""
+        f = self.get_file()
+        source = make_file_knit('source', get_transport(self.get_url('.')),
+            create=True, factory=KnitPlainFactory())
+        get_diamond_vf(source)
+        # insert some keys into f.
+        get_diamond_vf(f, left_only=True)
+        stream = source.get_record_stream(source.versions(), 'topological',
+            False)
+        f.insert_record_stream(stream)
+        self.assertIdenticalVersionedFile(f, source)
+
     def test_adds_with_parent_texts(self):
         f = self.get_file()
         parent_texts = {}
@@ -975,8 +989,8 @@
 
 class TestKnit(TestCaseWithMemoryTransport, VersionedFileTestMixIn):
 
-    def get_file(self, name='foo'):
-        return self.get_factory()(name, get_transport(self.get_url('.')),
+    def get_file(self, name='foo', create=True):
+        return make_file_knit(name, get_transport(self.get_url('.')),
             delta=True, create=True, get_scope=self.get_transaction)
 
     def get_factory(self):
@@ -989,9 +1003,7 @@
         return knit
 
     def reopen_file(self, name='foo', create=False):
-        return self.get_factory()(name, get_transport(self.get_url('.')),
-            delta=True,
-            create=create)
+        return self.get_file(name, create)
 
     def test_detection(self):
         knit = self.get_file()
@@ -1005,8 +1017,10 @@
 class TestPlaintextKnit(TestKnit):
     """Test a knit with no cached annotations"""
 
-    def get_factory(self):
-        return make_file_knit
+    def get_file(self, name='foo', create=True):
+        return make_file_knit(name, get_transport(self.get_url('.')),
+            delta=True, create=create, get_scope=self.get_transaction,
+            factory=_mod_knit.KnitPlainFactory())
 
 
 class TestPlanMergeVersionedFile(TestCaseWithMemoryTransport):

=== modified file 'bzrlib/weave.py'
--- a/bzrlib/weave.py	2008-04-23 05:17:05 +0000
+++ b/bzrlib/weave.py	2008-04-24 04:27:45 +0000
@@ -349,7 +349,10 @@
                     adapters[adapter_key] = adapter
                 lines = split_lines(adapter.get_bytes(
                     record, record.get_bytes_as(record.storage_kind)))
-                self.add_lines(record.key[0], parents, lines)
+                try:
+                    self.add_lines(record.key[0], parents, lines)
+                except RevisionAlreadyPresent:
+                    pass
 
     def _check_repeated_add(self, name, parents, text, sha1):
         """Check that a duplicated add is OK.




More information about the bazaar-commits mailing list