# HG changeset patch # User Eric Sumner # Date 1421275583 28800 # Node ID 7eb26415bef6fa40fa5772ac0212a9a6cd175812 # Parent 9881a1437799cbef382670ff6900c948c8992257 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 -r 9881a1437799 -r 7eb26415bef6 mercurial/bundle2.py --- a/mercurial/bundle2.py Wed Jan 14 14:32:22 2015 -0800 +++ b/mercurial/bundle2.py Wed Jan 14 14:46:23 2015 -0800 @@ -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 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)