Patchwork [6,of,9] bundle2: use bundlespec parameters to influence compression (API)

login
register
mail settings
Submitter Gregory Szorc
Date April 1, 2017, 10:31 p.m.
Message ID <2a93bd961ed35579fe3d.1491085917@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/19900/
State Changes Requested
Headers show

Comments

Gregory Szorc - April 1, 2017, 10:31 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1491083707 25200
#      Sat Apr 01 14:55:07 2017 -0700
# Node ID 2a93bd961ed35579fe3d3772ea6f0d305c8d8ea2
# Parent  62e377f673f3d9e10701d373b82f995085b54363
bundle2: use bundlespec parameters to influence compression (API)

The "compopts" argument was added at the end of the previous cycle
to facilitate an experimental config option (76104a4899ad). Now
that we've formalized the use of bundlespec parameters to control
the compression engine and have a mechanism to convert those parameters
to compression engine options, we can replace this argument with the
bundlespec parameters themselves and derive the options within the
function.

This completes a documented and extensible end-user facing feature
to influence compression behavior for bundle generation.

Patch

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -513,14 +513,18 @@  class bundle20(object):
         self._compengine = util.compengines.forbundletype('UN')
         self._compopts = None
 
-    def setcompression(self, alg, compopts=None):
+    def setcompression(self, alg, specparams=None):
         """setup core part compression to <alg>"""
         if alg in (None, 'UN'):
             return
         assert not any(n.lower() == 'compression' for n, v in self._params)
         self.addparam('Compression', alg)
-        self._compengine = util.compengines.forbundletype(alg)
-        self._compopts = compopts
+        engine = util.compengines.forbundletype(alg)
+        self._compengine = engine
+        self._compopts = engine.parsebundlespecparams(specparams or {})[1]
+        self.ui.debug('using compression engine %s\n' % self._compengine.name())
+        for k, v in sorted(self._compopts.items()):
+            self.ui.debug('engine option: %s=%s\n' % (k, v))
 
     @property
     def nbparts(self):
@@ -1297,7 +1301,7 @@  def obsmarkersversion(caps):
     return [int(c[1:]) for c in obscaps if c.startswith('V')]
 
 def writebundle(ui, cg, filename, bundletype, vfs=None, compression=None,
-                compopts=None):
+                specparams=None):
     """Write a bundle file and return its filename.
 
     Existing files will not be overwritten.
@@ -1305,10 +1309,9 @@  def writebundle(ui, cg, filename, bundle
     bz2 compression can be turned off.
     The bundle file will be deleted in case of errors.
     """
-
     if bundletype == "HG20":
         bundle = bundle20(ui)
-        bundle.setcompression(compression, compopts)
+        bundle.setcompression(compression, specparams)
         part = bundle.newpart('changegroup', data=cg.getchunks())
         part.addparam('version', cg.version)
         if 'clcount' in cg.extras:
@@ -1326,6 +1329,7 @@  def writebundle(ui, cg, filename, bundle
             raise error.Abort(_('unknown stream compression type: %s')
                               % comp)
         compengine = util.compengines.forbundletype(comp)
+        compopts = compengine.parsebundlespecparams(specparams or {})[1]
         def chunkiter():
             yield header
             for chunk in compengine.compressstream(cg.getchunks(), compopts):
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1380,17 +1380,8 @@  def bundle(ui, repo, fname, dest=None, *
         assert cgversion == '02'
         bversion = 'HG20'
 
-    # TODO compression options should be derived from bundlespec parsing.
-    # This is a temporary hack to allow adjusting bundle compression
-    # level without a) formalizing the bundlespec changes to declare it
-    # b) introducing a command flag.
-    compopts = {}
-    complevel = ui.configint('experimental', 'bundlecomplevel')
-    if complevel is not None:
-        compopts['level'] = complevel
-
     bundle2.writebundle(ui, cg, fname, bversion, compression=bcompression,
-                        compopts=compopts)
+                        specparams=params)
 
 @command('cat',
     [('o', 'output', '',
diff --git a/tests/test-bundle-type.t b/tests/test-bundle-type.t
--- a/tests/test-bundle-type.t
+++ b/tests/test-bundle-type.t
@@ -176,8 +176,14 @@  Compression level can be adjusted for bu
   $ f --size gzip-v2.hg
   gzip-v2.hg: size=427
 
-  $ hg --config experimental.bundlecomplevel=1 bundle -a -t gzip-v2 gzip-v2-level1.hg
+  $ hg --debug bundle -a -t 'gzip-v2;compressionlevel=1' gzip-v2-level1.hg
   1 changesets found
+  list of changesets:
+  61a3701c305e0c6b668d00231999e049c4282a5c
+  using compression engine zlib
+  engine option: level=1
+  bundle2-output-bundle: "HG20", (1 params) 1 parts total
+  bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
   $ f --size gzip-v2-level1.hg
   gzip-v2-level1.hg: size=435
 
@@ -221,6 +227,17 @@  zstd-v1 always fails
   (see 'hg help bundlespec' for supported values for --type)
   [255]
 
+compressionlevel parameter is parsed and used
+
+  $ hg -R nogd --debug bundle -a -t 'zstd-v2;compressionlevel=10' zstd-l10
+  1 changesets found
+  list of changesets:
+  c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
+  using compression engine zstd
+  engine option: level=10
+  bundle2-output-bundle: "HG20", (1 params) 1 parts total
+  bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
+
 #else
 
 zstd is a valid engine but isn't available
diff --git a/tests/test-bundle.t b/tests/test-bundle.t
--- a/tests/test-bundle.t
+++ b/tests/test-bundle.t
@@ -751,6 +751,7 @@  bundle single branch
   list of changesets:
   1a38c1b849e8b70c756d2d80b0b9a3ac0b7ea11a
   057f4db07f61970e1c11e83be79e9d08adc4dc31
+  using compression engine bz2
   bundle2-output-bundle: "HG20", (1 params) 1 parts total
   bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
   bundling: 1/2 changesets (50.00%)
diff --git a/tests/test-rebase-conflicts.t b/tests/test-rebase-conflicts.t
--- a/tests/test-rebase-conflicts.t
+++ b/tests/test-rebase-conflicts.t
@@ -280,6 +280,7 @@  Check that the right ancestors is used w
   list of changesets:
   e31216eec445e44352c5f01588856059466a24c9
   2f2496ddf49d69b5ef23ad8cf9fb2e0e4faf0ac2
+  using compression engine bz2
   bundle2-output-bundle: "HG20", (1 params) 1 parts total
   bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
   saved backup bundle to $TESTTMP/issue4041/.hg/strip-backup/e31216eec445-15f7a814-backup.hg (glob)
diff --git a/tests/test-strip.t b/tests/test-strip.t
--- a/tests/test-strip.t
+++ b/tests/test-strip.t
@@ -838,6 +838,7 @@  check strip behavior
   list of changesets:
   6625a516847449b6f0fa3737b9ba56e9f0f3032c
   d8db9d1372214336d2b5570f20ee468d2c72fa8b
+  using compression engine bz2
   bundle2-output-bundle: "HG20", (1 params) 1 parts total
   bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
   saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/6625a5168474-345bb43d-backup.hg (glob)