[PATCH 2 of 4] bundle2.unbundlepart: Keep an index of chunks and their locations

Eric Sumner ericsumner at fb.com
Wed Feb 4 13:29:36 CST 2015


# HG changeset patch
# User Eric Sumner <ericsumner at fb.com>
# Date 1421275583 28800
#      Wed Jan 14 14:46:23 2015 -0800
# Node ID 5c1c0b2b4aa5b0bbab1310a01ead10b7f69f8dcd
# Parent  3403436c7237eb359bdf69f1ba438eb4c6a3db12
bundle2.unbundlepart: Keep an index of chunks and their locations

In order to make unbundlepart seekable, we need to keep a record of where the
chunks are so that we can go back to the correct point.

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -827,6 +827,7 @@
         self._payloadstream = None
         self._readheader()
         self._mandatory = None
+        self._chunkindex = [] #(payload, file) position tuples for chunk starts
 
     def _fromheader(self, size):
         """return the next <size> byte from the header"""
@@ -852,7 +853,17 @@
         self.params.update(dict(self.advisoryparams))
         self.mandatorykeys = frozenset(p[0] for p in mandatoryparams)
 
-    def _payloadchunks(self):
+    def _payloadchunks(self, chunknum=0):
+        '''seek to specified chunk and start yielding data'''
+        if len(self._chunkindex) == 0:
+            assert chunknum == 0, 'Must start with chunk 0'
+            self._chunkindex.append((0, super(unbundlepart, self).tell()))
+        else:
+            assert chunknum < len(self._chunkindex), \
+                   'Unknown chunk %d' % chunknum
+            super(unbundlepart, self).seek(self._chunkindex[chunknum][1])
+
+        pos = self._chunkindex[chunknum][0]
         payloadsize = self._unpack(_fpayloadsize)[0]
         self.ui.debug('payload chunk size: %i\n' % payloadsize)
         while payloadsize:
@@ -864,7 +875,13 @@
                 msg = 'negative payload chunk size: %i' %  payloadsize
                 raise error.BundleValueError(msg)
             else:
-                yield self._readexact(payloadsize)
+                result = self._readexact(payloadsize)
+                chunknum += 1
+                pos += payloadsize
+                if chunknum == len(self._chunkindex):
+                    self._chunkindex.append((pos,
+                                             super(unbundlepart, self).tell()))
+                yield result
             payloadsize = self._unpack(_fpayloadsize)[0]
             self.ui.debug('payload chunk size: %i\n' % payloadsize)
 


More information about the Mercurial-devel mailing list