Rev 2662: * ``bzrlib.pack.ContainerWriter`` now returns an offset, length tuple to in http://people.ubuntu.com/~robertc/baz2.0/pack

Robert Collins robertc at robertcollins.net
Thu Aug 2 03:18:53 BST 2007


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

------------------------------------------------------------
revno: 2662
revision-id: robertc at robertcollins.net-20070802021817-n8a86kevyvk2f9jo
parent: pqm at pqm.ubuntu.com-20070730235409-pfqxlkh2dcs95u70
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pack
timestamp: Thu 2007-08-02 12:18:17 +1000
message:
  * ``bzrlib.pack.ContainerWriter`` now returns an offset, length tuple to
    callers when inserting data, allowing generation of readv style access
    during pack creation, without needing a separate pass across the output
    pack to gather such details. (Robert Collins)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/pack.py                 container.py-20070607160755-tr8zc26q18rn0jnb-1
  bzrlib/tests/test_pack.py      test_container.py-20070607160755-tr8zc26q18rn0jnb-2
=== modified file 'NEWS'
--- a/NEWS	2007-07-30 17:06:48 +0000
+++ b/NEWS	2007-08-02 02:18:17 +0000
@@ -177,6 +177,11 @@
     * Graph now has an is_ancestor method, various bits use it.
       (Aaron Bentley)
 
+    * ``bzrlib.pack.ContainerWriter`` now returns an offset, length tuple to
+      callers when inserting data, allowing generation of readv style access
+      during pack creation, without needing a separate pass across the output
+      pack to gather such details. (Robert Collins)
+
   TESTING:
 
     * Remove selftest ``--clean-output``, ``--numbered-dirs`` and

=== modified file 'bzrlib/pack.py'
--- a/bzrlib/pack.py	2007-07-03 04:12:19 +0000
+++ b/bzrlib/pack.py	2007-08-02 02:18:17 +0000
@@ -66,18 +66,34 @@
         :param write_func: a callable that will be called when this
             ContainerWriter needs to write some bytes.
         """
-        self.write_func = write_func
+        self._write_func = write_func
+        self.current_offset = 0
 
     def begin(self):
         """Begin writing a container."""
         self.write_func(FORMAT_ONE + "\n")
 
+    def write_func(self, bytes):
+        self._write_func(bytes)
+        self.current_offset += len(bytes)
+
     def end(self):
         """Finish writing a container."""
         self.write_func("E")
 
     def add_bytes_record(self, bytes, names):
-        """Add a Bytes record with the given names."""
+        """Add a Bytes record with the given names.
+        
+        :param bytes: The bytes to insert.
+        :param names: The names to give the inserted bytes.
+        :return: An offset, length tuple. The offset is the offset
+            of the record within the container, and the length is the
+            length of data that will need to be read to reconstitute the
+            record. These offset and length can only be used with the pack
+            interface - they might be offset by headers or other such details
+            and thus are only suitable for use by a ContainerReader.
+        """
+        current_offset = self.current_offset
         # Kind marker
         self.write_func("B")
         # Length
@@ -92,6 +108,8 @@
         self.write_func("\n")
         # Finally, the contents.
         self.write_func(bytes)
+        # return a memo of where we wrote data to allow random access.
+        return current_offset, self.current_offset - current_offset
 
 
 class BaseReader(object):

=== modified file 'bzrlib/tests/test_pack.py'
--- a/bzrlib/tests/test_pack.py	2007-07-03 04:05:08 +0000
+++ b/bzrlib/tests/test_pack.py	2007-08-02 02:18:17 +0000
@@ -54,7 +54,8 @@
         output = StringIO()
         writer = pack.ContainerWriter(output.write)
         writer.begin()
-        writer.add_bytes_record('abc', names=[])
+        offset, length = writer.add_bytes_record('abc', names=[])
+        self.assertEqual((42, 7), (offset, length))
         self.assertEqual('Bazaar pack format 1 (introduced in 0.18)\nB3\n\nabc',
                          output.getvalue())
 
@@ -63,7 +64,8 @@
         output = StringIO()
         writer = pack.ContainerWriter(output.write)
         writer.begin()
-        writer.add_bytes_record('abc', names=['name1'])
+        offset, length = writer.add_bytes_record('abc', names=['name1'])
+        self.assertEqual((42, 13), (offset, length))
         self.assertEqual(
             'Bazaar pack format 1 (introduced in 0.18)\n'
             'B3\nname1\n\nabc',
@@ -74,12 +76,26 @@
         output = StringIO()
         writer = pack.ContainerWriter(output.write)
         writer.begin()
-        writer.add_bytes_record('abc', names=['name1', 'name2'])
+        offset, length = writer.add_bytes_record('abc', names=['name1', 'name2'])
+        self.assertEqual((42, 19), (offset, length))
         self.assertEqual(
             'Bazaar pack format 1 (introduced in 0.18)\n'
             'B3\nname1\nname2\n\nabc',
             output.getvalue())
 
+    def test_add_second_bytes_record_gets_higher_offset(self):
+        output = StringIO()
+        writer = pack.ContainerWriter(output.write)
+        writer.begin()
+        writer.add_bytes_record('abc', names=[])
+        offset, length = writer.add_bytes_record('abc', names=[])
+        self.assertEqual((49, 7), (offset, length))
+        self.assertEqual(
+            'Bazaar pack format 1 (introduced in 0.18)\n'
+            'B3\n\nabc'
+            'B3\n\nabc',
+            output.getvalue())
+
     def test_add_bytes_record_invalid_name(self):
         """Adding a Bytes record with a name with whitespace in it raises
         InvalidRecordError.



More information about the bazaar-commits mailing list