[PATCH] bundle2: only emit compressed chunks if they have data

Gregory Szorc gregory.szorc at gmail.com
Sun Oct 16 00:19:11 UTC 2016


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1476576653 25200
#      Sat Oct 15 17:10:53 2016 -0700
# Node ID adac553f5fced14a7393e11c71e642eabbc82073
# Parent  5cb830801855dbb63e98b948e355bc995d295bf3
bundle2: only emit compressed chunks if they have data

This is similar to 58467204cac0. Not all calls into the compressor
return compressed data, as the compressor may buffer compressed
output internally. It is cheaper to check for empty chunks than to
send empty chunks through the generator.

When generating a gzip-v2 bundle of the mozilla-unified repo, this
change results in 50,093 empty chunks not being sent through the
generator (out of 1,902,996 total input chunks).

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -568,17 +568,19 @@ class bundle20(object):
         yield self._magicstring
         param = self._paramchunk()
         outdebug(self.ui, 'bundle parameter: %s' % param)
         yield _pack(_fstreamparamsize, len(param))
         if param:
             yield param
         # starting compression
         for chunk in self._getcorechunk():
-            yield self._compressor.compress(chunk)
+            data = self._compressor.compress(chunk)
+            if data:
+                yield data
         yield self._compressor.flush()
 
     def _paramchunk(self):
         """return a encoded version of all stream parameters"""
         blocks = []
         for par, value in self._params:
             par = urlreq.quote(par)
             if value is not None:
@@ -1319,17 +1321,19 @@ def writebundle(ui, cg, filename, bundle
         if comp not in util.compressors:
             raise error.Abort(_('unknown stream compression type: %s')
                               % comp)
         z = util.compressors[comp]()
         subchunkiter = cg.getchunks()
         def chunkiter():
             yield header
             for chunk in subchunkiter:
-                yield z.compress(chunk)
+                data = z.compress(chunk)
+                if data:
+                    yield data
             yield z.flush()
         chunkiter = chunkiter()
 
     # parse the changegroup data, otherwise we will block
     # in case of sshrepo because we don't know the end of the stream
     return changegroup.writechunks(ui, chunkiter, filename, vfs=vfs)
 
 @parthandler('changegroup', ('version', 'nbchanges', 'treemanifest'))


More information about the Mercurial-devel mailing list