Patchwork [06,of,10,v2] bundle-ng: move bundle generation to changegroup.py

login
register
mail settings
Submitter Benoit Boissinot
Date May 10, 2013, 9:59 p.m.
Message ID <01c43ff10f79c59867ca.1368223194@pouchy.lan>
Download mbox | patch
Permalink /patch/1610/
State Accepted
Commit e9c5b1c246dc07096561f4dd0dcbfe3c17bb8f45
Headers show

Comments

Benoit Boissinot - May 10, 2013, 9:59 p.m.
# HG changeset patch
# User Benoit Boissinot <benoit.boissinot@ens-lyon.org>
# Date 1360508600 -3600
#      Sun Feb 10 16:03:20 2013 +0100
# Node ID 01c43ff10f79c59867ca5ced111904764cd58a94
# Parent  2240b419486f25226253e9401c4ebc16e6df1f96
bundle-ng: move bundle generation to changegroup.py

Patch

diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py
--- a/mercurial/changegroup.py
+++ b/mercurial/changegroup.py
@@ -291,7 +291,7 @@ 
 
         yield self.close()
 
-    def generate(self, clnodes, getmfnodes, getfiles, getfilenodes, source):
+    def generate(self, commonrevs, clnodes, fastpathlinkrev, source):
         '''yield a sequence of changegroup chunks (strings)'''
         repo = self._repo
         cl = self._changelog
@@ -300,6 +300,69 @@ 
         progress = repo.ui.progress
         count = self.count
         _bundling = _('bundling')
+        _changesets = _('changesets')
+        _manifests = _('manifests')
+        _files = _('files')
+
+        mfs = {} # needed manifests
+        fnodes = {} # needed file nodes
+        changedfiles = set()
+        fstate = ['', {}]
+
+        # filter any nodes that claim to be part of the known set
+        def prune(revlog, missing):
+            rr, rl = revlog.rev, revlog.linkrev
+            return [n for n in missing
+                    if rl(rr(n)) not in commonrevs]
+
+        def lookup(revlog, x):
+            if revlog == cl:
+                c = cl.read(x)
+                changedfiles.update(c[3])
+                mfs.setdefault(c[0], x)
+                count[0] += 1
+                progress(_bundling, count[0],
+                         unit=_changesets, total=count[1])
+                return x
+            elif revlog == mf:
+                clnode = mfs[x]
+                if not fastpathlinkrev:
+                    mdata = mf.readfast(x)
+                    for f, n in mdata.iteritems():
+                        if f in changedfiles:
+                            fnodes[f].setdefault(n, clnode)
+                count[0] += 1
+                progress(_bundling, count[0],
+                         unit=_manifests, total=count[1])
+                return clnode
+            else:
+                progress(_bundling, count[0], item=fstate[0],
+                         unit=_files, total=count[1])
+                return fstate[1][x]
+
+        self.start(lookup)
+
+        def getmfnodes():
+            for f in changedfiles:
+                fnodes[f] = {}
+            count[:] = [0, len(mfs)]
+            return prune(mf, mfs)
+        def getfiles():
+            mfs.clear()
+            return changedfiles
+        def getfilenodes(fname, filerevlog):
+            if fastpathlinkrev:
+                ln, llr = filerevlog.node, filerevlog.linkrev
+                def genfilenodes():
+                    for r in filerevlog:
+                        linkrev = llr(r)
+                        if linkrev not in commonrevs:
+                            yield filerevlog.node(r), cl.node(linkrev)
+                fnodes[fname] = dict(genfilenodes())
+            fstate[0] = fname
+            fstate[1] = fnodes.pop(fname, {})
+            return prune(filerevlog, fstate[1])
+
 
         count[:] = [0, len(clnodes)]
         for chunk in self.group(clnodes, cl, reorder=reorder):
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -2035,13 +2035,6 @@ 
         commonrevs = outgoing.common
         csets = outgoing.missing
         heads = outgoing.missingheads
-        cl = bundler._changelog
-        mf = bundler._manifest
-        mfs = {} # needed manifests
-        fnodes = {} # needed file nodes
-        changedfiles = set()
-        fstate = ['', {}]
-
         # We go through the fast path if we get told to, or if all (unfiltered
         # heads have been requested (since we then know there all linkrevs will
         # be pulled by the client).
@@ -2051,70 +2044,7 @@ 
 
         self.hook('preoutgoing', throw=True, source=source)
         self.changegroupinfo(csets, source)
-
-        # filter any nodes that claim to be part of the known set
-        def prune(revlog, missing):
-            rr, rl = revlog.rev, revlog.linkrev
-            return [n for n in missing
-                    if rl(rr(n)) not in commonrevs]
-
-        progress = self.ui.progress
-        _bundling = _('bundling')
-        _changesets = _('changesets')
-        _manifests = _('manifests')
-        _files = _('files')
-
-        def lookup(revlog, x):
-            count = bundler.count
-            if revlog == cl:
-                c = cl.read(x)
-                changedfiles.update(c[3])
-                mfs.setdefault(c[0], x)
-                count[0] += 1
-                progress(_bundling, count[0],
-                         unit=_changesets, total=count[1])
-                return x
-            elif revlog == mf:
-                clnode = mfs[x]
-                if not fastpathlinkrev:
-                    mdata = mf.readfast(x)
-                    for f, n in mdata.iteritems():
-                        if f in changedfiles:
-                            fnodes[f].setdefault(n, clnode)
-                count[0] += 1
-                progress(_bundling, count[0],
-                         unit=_manifests, total=count[1])
-                return clnode
-            else:
-                progress(_bundling, count[0], item=fstate[0],
-                         unit=_files, total=count[1])
-                return fstate[1][x]
-
-        bundler.start(lookup)
-
-        def getmfnodes():
-            for f in changedfiles:
-                fnodes[f] = {}
-            bundler.count[:] = [0, len(mfs)]
-            return prune(mf, mfs)
-        def getfiles():
-            mfs.clear()
-            return changedfiles
-        def getfilenodes(fname, filerevlog):
-            if fastpathlinkrev:
-                ln, llr = filerevlog.node, filerevlog.linkrev
-                def genfilenodes():
-                    for r in filerevlog:
-                        linkrev = llr(r)
-                        if linkrev not in commonrevs:
-                            yield filerevlog.node(r), cl.node(linkrev)
-                fnodes[fname] = dict(genfilenodes())
-            fstate[0] = fname
-            fstate[1] = fnodes.pop(fname, {})
-            return prune(filerevlog, fstate[1])
-
-        gengroup = bundler.generate(csets, getmfnodes, getfiles, getfilenodes,
-                                    source)
+        gengroup = bundler.generate(commonrevs, csets, fastpathlinkrev, source)
         return changegroup.unbundle10(util.chunkbuffer(gengroup), 'UN')
 
     def changegroup(self, basenodes, source):