Mercurial > public > mercurial-scm > hg
diff mercurial/bundle2.py @ 20876:ddd56f3eb786
bundle2: support for bundling and unbundling payload
We add the ability to bundle and unbundle a payload in parts. The payload is the
actual binary data of the part. It is used to convey all the applicative data.
For now we stick to very simple implementation with all the data fit in single
chunk. This open the door to some bundle2 testing usage. This will be improved before
bundle2 get used for real. We need to be able to stream the payload in multiple
part to exchange any changegroup efficiently. This simple version will do for
now.
Bundling and unbundling are done in the same changeset because the test for
parts is less modular. However, the result is not too complex.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Wed, 19 Mar 2014 23:36:15 -0700 |
parents | 9a75d2559cff |
children | 9e9e3a4e9261 |
line wrap: on
line diff
--- a/mercurial/bundle2.py Tue Apr 01 17:59:06 2014 -0500 +++ b/mercurial/bundle2.py Wed Mar 19 23:36:15 2014 -0700 @@ -89,8 +89,13 @@ :payload: - The current payload is a 32bit integer with a value of 0. This is - considered an "empty" payload. + payload is a series of `<chunksize><chunkdata>`. + + `chunksize` is a 32 bits integer, `chunkdata` are plain bytes (as much as + `chunksize` says)` The payload part is concluded by a zero size chunk. + + The current implementation always produces either zero or one chunk. + This is an implementation limitation that will ultimatly be lifted. """ import util @@ -109,6 +114,7 @@ _fstreamparamsize = '>H' _fpartheadersize = '>H' _fparttypesize = '>B' +_fpayloadsize = '>I' class bundle20(object): """represent an outgoing bundle2 container @@ -257,12 +263,18 @@ typesize = _unpack(_fparttypesize, fromheader(1))[0] parttype = fromheader(typesize) self.ui.debug('part type: "%s"\n' % parttype) - current = part(parttype) assert fromheader(2) == '\0\0' # no option for now del self._offset # clean up layer, nobody saw anything. self.ui.debug('part parameters: 0\n') - assert self._readexact(4) == '\0\0\0\0' #empty payload - self.ui.debug('payload chunk size: 0\n') + payload = [] + payloadsize = self._unpack(_fpayloadsize)[0] + self.ui.debug('payload chunk size: %i\n' % payloadsize) + while payloadsize: + payload.append(self._readexact(payloadsize)) + payloadsize = self._unpack(_fpayloadsize)[0] + self.ui.debug('payload chunk size: %i\n' % payloadsize) + payload = ''.join(payload) + current = part(parttype, data=payload) return current @@ -286,7 +298,12 @@ headerchunk = ''.join(header) yield _pack(_fpartheadersize, len(headerchunk)) yield headerchunk - # force empty part for now - yield '\0\0\0\0' + # we only support fixed size data now. + # This will be improved in the future. + if len(self.data): + yield _pack(_fpayloadsize, len(self.data)) + yield self.data + # end of payload + yield _pack(_fpayloadsize, 0)