[PATCH] wireproto: use base64 instead of hex for known/getbundle

Peter Arrenbrecht peter.arrenbrecht at gmail.com
Sun May 1 05:35:55 CDT 2011


# HG changeset patch
# User Peter Arrenbrecht <peter.arrenbrecht at gmail.com>
# Date 1304246106 -7200
wireproto: use base64 instead of hex for known/getbundle

Saves a couple of bytes per node id being sent across the
wire. Introduces node.to/fromb64 and wireproto.en/decodelistb64.

diff --git a/mercurial/node.py b/mercurial/node.py
--- a/mercurial/node.py
+++ b/mercurial/node.py
@@ -5,7 +5,7 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-import binascii
+import binascii, base64
 
 nullrev = -1
 nullid = "\0" * 20
@@ -14,5 +14,8 @@
 hex = binascii.hexlify
 bin = binascii.unhexlify
 
+tob64 = base64.encodestring
+fromb64 = base64.decodestring
+
 def short(node):
     return hex(node[:6])
diff --git a/mercurial/wireproto.py b/mercurial/wireproto.py
--- a/mercurial/wireproto.py
+++ b/mercurial/wireproto.py
@@ -7,7 +7,7 @@
 
 import urllib, tempfile, os, sys
 from i18n import _
-from node import bin, hex
+from node import bin, hex, tob64, fromb64
 import changegroup as changegroupmod
 import repo, error, encoding, util, store
 import pushkey as pushkeymod
@@ -22,6 +22,14 @@
 def encodelist(l, sep=' '):
     return sep.join(map(hex, l))
 
+def decodelistb64(l, sep=' '):
+    if l:
+        return map(fromb64, l.split(sep))
+    return []
+
+def encodelistb64(l, sep=' '):
+    return sep.join(map(tob64, l))
+
 # client side
 
 class wirerepository(repo.repository):
@@ -41,7 +49,7 @@
             self._abort(error.ResponseError(_("unexpected response:"), d))
 
     def known(self, nodes):
-        n = encodelist(nodes)
+        n = encodelistb64(nodes)
         d = self._call("known", nodes=n)
         try:
             return [bool(int(f)) for f in d]
@@ -127,9 +135,9 @@
         self.requirecap('getbundle', _('look up remote changes'))
         opts = {}
         if heads is not None:
-            opts['heads'] = encodelist(heads)
+            opts['heads'] = encodelistb64(heads)
         if common is not None:
-            opts['common'] = encodelist(common)
+            opts['common'] = encodelistb64(common)
         f = self._callstream("getbundle", **opts)
         return changegroupmod.unbundle10(self._decompress(f), 'UN')
 
@@ -254,7 +262,7 @@
 def getbundle(repo, proto, others):
     opts = options('getbundle', ['heads', 'common'], others)
     for k, v in opts.iteritems():
-        opts[k] = decodelist(v)
+        opts[k] = decodelistb64(v)
     cg = repo.getbundle('serve', **opts)
     return streamres(proto.groupchunks(cg))
 
@@ -288,7 +296,7 @@
     return "%s %s\n" % (success, r)
 
 def known(repo, proto, nodes):
-    return ''.join(b and "1" or "0" for b in repo.known(decodelist(nodes)))
+    return ''.join(b and "1" or "0" for b in repo.known(decodelistb64(nodes)))
 
 def pushkey(repo, proto, namespace, key, old, new):
     # compatibility with pre-1.8 clients which were accidentally
diff --git a/tests/test-getbundle.t b/tests/test-getbundle.t
--- a/tests/test-getbundle.t
+++ b/tests/test-getbundle.t
@@ -247,7 +247,7 @@
   * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
   * - - [*] "GET /?cmd=getbundle HTTP/1.1" 200 - (glob)
   * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
-  * - - [*] "GET /?cmd=getbundle&common=c1818a9f5977dd4139a48f93f5425c67d44a9368+ea919464b16e003894c48b6cb68df3cd9411b544&heads=6b57ee934bb2996050540f84cdfc8dcad1e7267d+2114148793524fd045998f71a45b0aaf139f752b HTTP/1.1" 200 - (glob)
+  * - - [*] "GET /?cmd=getbundle&common=wYGKn1l33UE5pI%2BT9UJcZ9RKk2g%3D%0A+6pGUZLFuADiUxItsto3zzZQRtUQ%3D%0A&heads=a1fuk0uymWBQVA%2BEzfyNytHnJn0%3D%0A+IRQUh5NST9BFmY9xpFsKrxOfdSs%3D%0A HTTP/1.1" 200 - (glob)
 
   $ cat error.log
 
diff --git a/tests/test-http-proxy.t b/tests/test-http-proxy.t
--- a/tests/test-http-proxy.t
+++ b/tests/test-http-proxy.t
@@ -103,18 +103,18 @@
   * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle&common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 HTTP/1.1" - - (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle&common=AAAAAAAAAAAAAAAAAAAAAAAAAAA%3D%0A&heads=gxgOeEXeQgobtGiW%2FV%2FgUpT41ik%3D%0A HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle&common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 HTTP/1.1" - - (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle&common=AAAAAAAAAAAAAAAAAAAAAAAAAAA%3D%0A&heads=gxgOeEXeQgobtGiW%2FV%2FgUpT41ik%3D%0A HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle&common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 HTTP/1.1" - - (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle&common=AAAAAAAAAAAAAAAAAAAAAAAAAAA%3D%0A&heads=gxgOeEXeQgobtGiW%2FV%2FgUpT41ik%3D%0A HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
-  * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle&common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 HTTP/1.1" - - (glob)
+  * - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle&common=AAAAAAAAAAAAAAAAAAAAAAAAAAA%3D%0A&heads=gxgOeEXeQgobtGiW%2FV%2FgUpT41ik%3D%0A HTTP/1.1" - - (glob)
   * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
 


More information about the Mercurial-devel mailing list