Mercurial > hg
changeset 24035:7eb26415bef6
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.
author | Eric Sumner <ericsumner@fb.com> |
---|---|
date | Wed, 14 Jan 2015 14:46:23 -0800 |
parents | 9881a1437799 |
children | c7601086338a |
files | mercurial/bundle2.py |
diffstat | 1 files changed, 19 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- 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 <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)