comparison mercurial/bundle2.py @ 30351:f81002f736d7

bundle2: use new compression engine API for compression Now that we have a new API to define compression engines, let's put it to use! The new code stores a reference to the compression engine instead of a low-level compressor object. This will allow us to more easily transition to different APIs on the compression engine interface once we implement them. As part of this, we change the registration in bundletypes to use 'UN' instead of None. Previously, util.compressors had the no-op compressor registered under both the 'UN' and None keys. Since we're switching to a new API, I don't see the point in carrying this dual registration forward.
author Gregory Szorc <gregory.szorc@gmail.com>
date Mon, 07 Nov 2016 18:35:43 -0800
parents 9626022feaa4
children d045b4091197
comparison
equal deleted inserted replaced
30350:358cda0af6ee 30351:f81002f736d7
483 ca = "%s=%s" % (ca, ','.join(vals)) 483 ca = "%s=%s" % (ca, ','.join(vals))
484 chunks.append(ca) 484 chunks.append(ca)
485 return '\n'.join(chunks) 485 return '\n'.join(chunks)
486 486
487 bundletypes = { 487 bundletypes = {
488 "": ("", None), # only when using unbundle on ssh and old http servers 488 "": ("", 'UN'), # only when using unbundle on ssh and old http servers
489 # since the unification ssh accepts a header but there 489 # since the unification ssh accepts a header but there
490 # is no capability signaling it. 490 # is no capability signaling it.
491 "HG20": (), # special-cased below 491 "HG20": (), # special-cased below
492 "HG10UN": ("HG10UN", None), 492 "HG10UN": ("HG10UN", 'UN'),
493 "HG10BZ": ("HG10", 'BZ'), 493 "HG10BZ": ("HG10", 'BZ'),
494 "HG10GZ": ("HG10GZ", 'GZ'), 494 "HG10GZ": ("HG10GZ", 'GZ'),
495 } 495 }
496 496
497 # hgweb uses this list to communicate its preferred type 497 # hgweb uses this list to communicate its preferred type
509 def __init__(self, ui, capabilities=()): 509 def __init__(self, ui, capabilities=()):
510 self.ui = ui 510 self.ui = ui
511 self._params = [] 511 self._params = []
512 self._parts = [] 512 self._parts = []
513 self.capabilities = dict(capabilities) 513 self.capabilities = dict(capabilities)
514 self._compressor = util.compressors[None]() 514 self._compengine = util.compengines.forbundletype('UN')
515 515
516 def setcompression(self, alg): 516 def setcompression(self, alg):
517 """setup core part compression to <alg>""" 517 """setup core part compression to <alg>"""
518 if alg is None: 518 if alg is None:
519 return 519 return
520 assert not any(n.lower() == 'Compression' for n, v in self._params) 520 assert not any(n.lower() == 'Compression' for n, v in self._params)
521 self.addparam('Compression', alg) 521 self.addparam('Compression', alg)
522 self._compressor = util.compressors[alg]() 522 self._compengine = util.compengines.forbundletype(alg)
523 523
524 @property 524 @property
525 def nbparts(self): 525 def nbparts(self):
526 """total number of parts added to the bundler""" 526 """total number of parts added to the bundler"""
527 return len(self._parts) 527 return len(self._parts)
570 outdebug(self.ui, 'bundle parameter: %s' % param) 570 outdebug(self.ui, 'bundle parameter: %s' % param)
571 yield _pack(_fstreamparamsize, len(param)) 571 yield _pack(_fstreamparamsize, len(param))
572 if param: 572 if param:
573 yield param 573 yield param
574 # starting compression 574 # starting compression
575 compressor = self._compengine.compressorobj()
575 for chunk in self._getcorechunk(): 576 for chunk in self._getcorechunk():
576 data = self._compressor.compress(chunk) 577 data = compressor.compress(chunk)
577 if data: 578 if data:
578 yield data 579 yield data
579 yield self._compressor.flush() 580 yield compressor.flush()
580 581
581 def _paramchunk(self): 582 def _paramchunk(self):
582 """return a encoded version of all stream parameters""" 583 """return a encoded version of all stream parameters"""
583 blocks = [] 584 blocks = []
584 for par, value in self._params: 585 for par, value in self._params:
1316 assert compression is None 1317 assert compression is None
1317 if cg.version != '01': 1318 if cg.version != '01':
1318 raise error.Abort(_('old bundle types only supports v1 ' 1319 raise error.Abort(_('old bundle types only supports v1 '
1319 'changegroups')) 1320 'changegroups'))
1320 header, comp = bundletypes[bundletype] 1321 header, comp = bundletypes[bundletype]
1321 if comp not in util.compressors: 1322 if comp not in util.compengines.supportedbundletypes:
1322 raise error.Abort(_('unknown stream compression type: %s') 1323 raise error.Abort(_('unknown stream compression type: %s')
1323 % comp) 1324 % comp)
1324 z = util.compressors[comp]() 1325 compengine = util.compengines.forbundletype(comp)
1326 compressor = compengine.compressorobj()
1325 subchunkiter = cg.getchunks() 1327 subchunkiter = cg.getchunks()
1326 def chunkiter(): 1328 def chunkiter():
1327 yield header 1329 yield header
1328 for chunk in subchunkiter: 1330 for chunk in subchunkiter:
1329 data = z.compress(chunk) 1331 data = compressor.compress(chunk)
1330 if data: 1332 if data:
1331 yield data 1333 yield data
1332 yield z.flush() 1334 yield compressor.flush()
1333 chunkiter = chunkiter() 1335 chunkiter = chunkiter()
1334 1336
1335 # parse the changegroup data, otherwise we will block 1337 # parse the changegroup data, otherwise we will block
1336 # in case of sshrepo because we don't know the end of the stream 1338 # in case of sshrepo because we don't know the end of the stream
1337 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs) 1339 return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)