changegroup: introduce bundler objects
authorMatt Mackall <mpm@selenic.com>
Thu, 31 Mar 2011 15:24:06 -0500
changeset 13831 d69c9510d648
parent 13830 2dc6e09f2a7d
child 13832 9358fdeaa532
changegroup: introduce bundler objects This makes the bundler pluggable at lower levels.
mercurial/changegroup.py
mercurial/localrepo.py
mercurial/revlog.py
--- a/mercurial/changegroup.py	Thu Mar 31 14:25:26 2011 -0500
+++ b/mercurial/changegroup.py	Thu Mar 31 15:24:06 2011 -0500
@@ -194,3 +194,18 @@
     if version != '10':
         raise util.Abort(_('%s: unknown bundle version %s') % (fname, version))
     return unbundle10(fh, alg)
+
+class bundle10(object):
+    def __init__(self, lookup):
+        self._lookup = lookup
+    def close(self):
+        return closechunk()
+    def fileheader(self, fname):
+        return chunkheader(len(fname)) + fname
+    def revchunk(self, revlog, node='', p1='', p2='', prefix='', data=''):
+        linknode = self._lookup(revlog, node)
+        meta = node + p1 + p2 + linknode + prefix
+        l = len(meta) + len(data)
+        yield chunkheader(l)
+        yield meta
+        yield data
--- a/mercurial/localrepo.py	Thu Mar 31 14:25:26 2011 -0500
+++ b/mercurial/localrepo.py	Thu Mar 31 15:24:06 2011 -0500
@@ -1521,19 +1521,19 @@
                     unit=_('files'), total=len(changedfiles))
                 return fstate[1][x]
 
-        # Now that we have all theses utility functions to help out and
-        # logically divide up the task, generate the group.
+        bundler = changegroup.bundle10(lookup)
+
         def gengroup():
             # Create a changenode group generator that will call our functions
             # back to lookup the owning changenode and collect information.
-            for chunk in cl.group(csets, lookup):
+            for chunk in cl.group(csets, bundler):
                 yield chunk
             self.ui.progress(_('bundling'), None)
 
             # Create a generator for the manifestnodes that calls our lookup
             # and data collection functions back.
             count[0] = 0
-            for chunk in mf.group(prune(mf, mfs), lookup):
+            for chunk in mf.group(prune(mf, mfs), bundler):
                 yield chunk
             self.ui.progress(_('bundling'), None)
 
@@ -1550,17 +1550,16 @@
                 first = True
 
                 for chunk in filerevlog.group(prune(filerevlog, fstate[1]),
-                                              lookup):
+                                              bundler):
                     if first:
-                        if chunk == changegroup.closechunk():
+                        if chunk == bundler.close():
                             break
                         count[0] += 1
-                        yield changegroup.chunkheader(len(fname))
-                        yield fname
+                        yield bundler.fileheader(fname)
                         first = False
                     yield chunk
             # Signal that no more groups are left.
-            yield changegroup.closechunk()
+            yield bundler.close()
             self.ui.progress(_('bundling'), None)
 
             if csets:
@@ -1618,16 +1617,18 @@
                     total=len(changedfiles), unit=_('files'))
                 return cl.node(revlog.linkrev(revlog.rev(x)))
 
+        bundler = changegroup.bundle10(lookup)
+
         def gengroup():
             '''yield a sequence of changegroup chunks (strings)'''
             # construct a list of all changed files
 
-            for chunk in cl.group(nodes, lookup):
+            for chunk in cl.group(nodes, bundler):
                 yield chunk
             self.ui.progress(_('bundling'), None)
 
             count[0] = 0
-            for chunk in mf.group(gennodelst(mf), lookup):
+            for chunk in mf.group(gennodelst(mf), bundler):
                 yield chunk
             self.ui.progress(_('bundling'), None)
 
@@ -1638,16 +1639,15 @@
                     raise util.Abort(_("empty or missing revlog for %s") % fname)
                 fstate[0] = fname
                 first = True
-                for chunk in filerevlog.group(gennodelst(filerevlog), lookup):
+                for chunk in filerevlog.group(gennodelst(filerevlog), bundler):
                     if first:
-                        if chunk == changegroup.closechunk():
+                        if chunk == bundler.close():
                             break
                         count[0] += 1
-                        yield changegroup.chunkheader(len(fname))
-                        yield fname
+                        yield bundler.fileheader(fname)
                         first = False
                     yield chunk
-            yield changegroup.closechunk()
+            yield bundler.close()
             self.ui.progress(_('bundling'), None)
 
             if nodes:
--- a/mercurial/revlog.py	Thu Mar 31 14:25:26 2011 -0500
+++ b/mercurial/revlog.py	Thu Mar 31 15:24:06 2011 -0500
@@ -1058,7 +1058,7 @@
             self._cache = (node, curr, text)
         return node
 
-    def group(self, nodelist, lookup):
+    def group(self, nodelist, bundler):
         """Calculate a delta group, yielding a sequence of changegroup chunks
         (strings).
 
@@ -1074,7 +1074,7 @@
 
         # if we don't have any revisions touched by these changesets, bail
         if not revs:
-            yield changegroup.closechunk()
+            yield bundler.close()
             return
 
         # add the parent of the first rev
@@ -1085,19 +1085,18 @@
         for r in xrange(len(revs) - 1):
             a, b = revs[r], revs[r + 1]
             nb = self.node(b)
+            p1, p2 = self.parents(nb)
+            prefix = ''
 
-            p = self.parents(nb)
-            meta = nb + p[0] + p[1] + lookup(self, nb)
             if a == nullrev:
                 d = self.revision(nb)
-                meta += mdiff.trivialdiffheader(len(d))
+                prefix = mdiff.trivialdiffheader(len(d))
             else:
                 d = self.revdiff(a, b)
-            yield changegroup.chunkheader(len(meta) + len(d))
-            yield meta
-            yield d
+            for c in bundler.revchunk(self, nb, p1, p2, prefix, d):
+                yield c
 
-        yield changegroup.closechunk()
+        yield bundler.close()
 
     def addgroup(self, bundle, linkmapper, transaction):
         """