Patchwork [3,of,7,bundle2] phases: move binary encoding into a reusable function

login
register
mail settings
Submitter Boris Feld
Date Sept. 28, 2017, 5:08 a.m.
Message ID <856f40d4b1a1ac8f77c3.1506575318@FB>
Download mbox | patch
Permalink /patch/24196/
State Accepted
Headers show

Comments

Boris Feld - Sept. 28, 2017, 5:08 a.m.
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1505851291 -7200
#      Tue Sep 19 22:01:31 2017 +0200
# Node ID 856f40d4b1a1ac8f77c314719eb399ea043e5923
# Parent  1efdcfffd51b31fad818b2c772a2a8883da3de2b
# EXP-Topic b2.phases
phases: move binary encoding into a reusable function

We want to use binary phases for pushing and pulling. We extract the encoding
function out of the bundle2 module first.

Patch

diff -r 1efdcfffd51b -r 856f40d4b1a1 mercurial/bundle2.py
--- a/mercurial/bundle2.py	Tue Sep 19 22:08:09 2017 +0200
+++ b/mercurial/bundle2.py	Tue Sep 19 22:01:31 2017 +0200
@@ -179,8 +179,6 @@ 
 _fpayloadsize = '>i'
 _fpartparamcount = '>BB'
 
-_fphasesentry = struct.Struct('>i20s')
-
 preferedchunksize = 4096
 
 _parttypeforbidden = re.compile('[^a-zA-Z0-9_:-]')
@@ -1480,11 +1478,8 @@ 
 
     if opts.get('phases', False):
         headsbyphase = phases.subsetphaseheads(repo, outgoing.missing)
-        phasedata = []
-        for phase in phases.allphases:
-            for head in headsbyphase[phase]:
-                phasedata.append(_fphasesentry.pack(phase, head))
-        bundler.newpart('phase-heads', data=''.join(phasedata))
+        phasedata = phases.binaryencode(headsbyphase)
+        bundler.newpart('phase-heads', data=phasedata)
 
 def addparttagsfnodescache(repo, bundler, outgoing):
     # we include the tags fnode cache for the bundle changeset
@@ -1843,14 +1838,14 @@ 
 
 def _readphaseheads(inpart):
     headsbyphase = [[] for i in phases.allphases]
-    entrysize = _fphasesentry.size
+    entrysize = phases._fphasesentry.size
     while True:
         entry = inpart.read(entrysize)
         if len(entry) < entrysize:
             if entry:
                 raise error.Abort(_('bad phase-heads bundle part'))
             break
-        phase, node = _fphasesentry.unpack(entry)
+        phase, node = phases._fphasesentry.unpack(entry)
         headsbyphase[phase].append(node)
     return headsbyphase
 
diff -r 1efdcfffd51b -r 856f40d4b1a1 mercurial/phases.py
--- a/mercurial/phases.py	Tue Sep 19 22:08:09 2017 +0200
+++ b/mercurial/phases.py	Tue Sep 19 22:01:31 2017 +0200
@@ -103,6 +103,7 @@ 
 from __future__ import absolute_import
 
 import errno
+import struct
 
 from .i18n import _
 from .node import (
@@ -119,6 +120,8 @@ 
     util,
 )
 
+_fphasesentry = struct.Struct('>i20s')
+
 allphases = public, draft, secret = range(3)
 trackedphases = allphases[1:]
 phasenames = ['public', 'draft', 'secret']
@@ -154,6 +157,18 @@ 
         dirty = True
     return roots, dirty
 
+def binaryencode(phasemapping):
+    """encode a 'phase -> nodes' mapping into a binary stream
+
+    Since phases are integer the mapping is actually a python list:
+    [[PUBLIC_HEADS], [DRAFTS_HEADS], [SECRET_HEADS]]
+    """
+    binarydata = []
+    for phase, nodes in enumerate(phasemapping):
+        for head in nodes:
+            binarydata.append(_fphasesentry.pack(phase, head))
+    return ''.join(binarydata)
+
 def _trackphasechange(data, rev, old, new):
     """add a phase move the <data> dictionnary