comparison mercurial/bundle2.py @ 20995:e995d104c87f

bundle2: add an integer id to part For sending response to a pushed bundle, we need to link reply parts to request part. We introduce a part id for this purpose. This is a 32 bit unique integer stored in the header.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Tue, 01 Apr 2014 00:07:17 -0700
parents b24ee5076b94
children ed3c5e18a047
comparison
equal deleted inserted replaced
20994:40800668e019 20995:e995d104c87f
84 The binary format of the header is has follow 84 The binary format of the header is has follow
85 85
86 :typesize: (one byte) 86 :typesize: (one byte)
87 87
88 :typename: alphanumerical part name 88 :typename: alphanumerical part name
89
90 :partid: A 32bits integer (unique in the bundle) that can be used to refer
91 to this part.
89 92
90 :parameters: 93 :parameters:
91 94
92 Part's parameter may have arbitraty content, the binary structure is:: 95 Part's parameter may have arbitraty content, the binary structure is::
93 96
152 _magicstring = 'HG20' 155 _magicstring = 'HG20'
153 156
154 _fstreamparamsize = '>H' 157 _fstreamparamsize = '>H'
155 _fpartheadersize = '>H' 158 _fpartheadersize = '>H'
156 _fparttypesize = '>B' 159 _fparttypesize = '>B'
160 _fpartid = '>I'
157 _fpayloadsize = '>I' 161 _fpayloadsize = '>I'
158 _fpartparamcount = '>BB' 162 _fpartparamcount = '>BB'
159 163
160 def _makefpartparamsizes(nbparams): 164 def _makefpartparamsizes(nbparams):
161 """return a struct format to read part parameter sizes 165 """return a struct format to read part parameter sizes
317 321
318 def addpart(self, part): 322 def addpart(self, part):
319 """add a new part to the bundle2 container 323 """add a new part to the bundle2 container
320 324
321 Parts contains the actuall applicative payload.""" 325 Parts contains the actuall applicative payload."""
326 assert part.id is None
327 part.id = len(self._parts) # very cheap counter
322 self._parts.append(part) 328 self._parts.append(part)
323 329
324 def getchunks(self): 330 def getchunks(self):
325 self.ui.debug('start emission of %s stream\n' % _magicstring) 331 self.ui.debug('start emission of %s stream\n' % _magicstring)
326 yield _magicstring 332 yield _magicstring
447 return _unpack(format, data) 453 return _unpack(format, data)
448 454
449 typesize = unpackheader(_fparttypesize)[0] 455 typesize = unpackheader(_fparttypesize)[0]
450 parttype = fromheader(typesize) 456 parttype = fromheader(typesize)
451 self.ui.debug('part type: "%s"\n' % parttype) 457 self.ui.debug('part type: "%s"\n' % parttype)
458 partid = unpackheader(_fpartid)[0]
459 self.ui.debug('part id: "%s"\n' % partid)
452 ## reading parameters 460 ## reading parameters
453 # param count 461 # param count
454 mancount, advcount = unpackheader(_fpartparamcount) 462 mancount, advcount = unpackheader(_fpartparamcount)
455 self.ui.debug('part parameters: %i\n' % (mancount + advcount)) 463 self.ui.debug('part parameters: %i\n' % (mancount + advcount))
456 # param size 464 # param size
476 payload.append(self._readexact(payloadsize)) 484 payload.append(self._readexact(payloadsize))
477 payloadsize = self._unpack(_fpayloadsize)[0] 485 payloadsize = self._unpack(_fpayloadsize)[0]
478 self.ui.debug('payload chunk size: %i\n' % payloadsize) 486 self.ui.debug('payload chunk size: %i\n' % payloadsize)
479 payload = ''.join(payload) 487 payload = ''.join(payload)
480 current = part(parttype, manparams, advparams, data=payload) 488 current = part(parttype, manparams, advparams, data=payload)
489 current.id = partid
481 return current 490 return current
482 491
483 492
484 class part(object): 493 class part(object):
485 """A bundle2 part contains application level payload 494 """A bundle2 part contains application level payload
488 handler. 497 handler.
489 """ 498 """
490 499
491 def __init__(self, parttype, mandatoryparams=(), advisoryparams=(), 500 def __init__(self, parttype, mandatoryparams=(), advisoryparams=(),
492 data=''): 501 data=''):
502 self.id = None
493 self.type = parttype 503 self.type = parttype
494 self.data = data 504 self.data = data
495 self.mandatoryparams = mandatoryparams 505 self.mandatoryparams = mandatoryparams
496 self.advisoryparams = advisoryparams 506 self.advisoryparams = advisoryparams
497 507
498 def getchunks(self): 508 def getchunks(self):
499 #### header 509 #### header
500 ## parttype 510 ## parttype
501 header = [_pack(_fparttypesize, len(self.type)), 511 header = [_pack(_fparttypesize, len(self.type)),
502 self.type, 512 self.type, _pack(_fpartid, self.id),
503 ] 513 ]
504 ## parameters 514 ## parameters
505 # count 515 # count
506 manpar = self.mandatoryparams 516 manpar = self.mandatoryparams
507 advpar = self.advisoryparams 517 advpar = self.advisoryparams