changeset 14144:3c3c53d8343a

unbundler: separate delta and header parsing Add header parsing for changelog and manifest (currently no headers might change for next-gen bundle).
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Sat, 30 Apr 2011 19:01:24 +0200
parents da635d3c5620
children 4b7e4b9db8fb
files mercurial/bundlerepo.py mercurial/changegroup.py mercurial/commands.py mercurial/localrepo.py mercurial/revlog.py
diffstat 5 files changed, 39 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/bundlerepo.py	Sat Apr 30 11:03:28 2011 +0200
+++ b/mercurial/bundlerepo.py	Sat Apr 30 19:01:24 2011 +0200
@@ -34,7 +34,7 @@
         n = len(self)
         chain = None
         while 1:
-            chunkdata = bundle.parsechunk(chain)
+            chunkdata = bundle.deltachunk(chain)
             if not chunkdata:
                 break
             node = chunkdata['node']
@@ -197,6 +197,8 @@
 
     @util.propertycache
     def changelog(self):
+        # consume the header if it exists
+        self.bundle.changelogheader()
         c = bundlechangelog(self.sopener, self.bundle)
         self.manstart = self.bundle.tell()
         return c
@@ -204,6 +206,8 @@
     @util.propertycache
     def manifest(self):
         self.bundle.seek(self.manstart)
+        # consume the header if it exists
+        self.bundle.manifestheader()
         m = bundlemanifest(self.sopener, self.bundle, self.changelog.rev)
         self.filestart = self.bundle.tell()
         return m
@@ -225,12 +229,13 @@
         if not self.bundlefilespos:
             self.bundle.seek(self.filestart)
             while 1:
-                chunk = self.bundle.chunk()
-                if not chunk:
+                chunkdata = self.bundle.filelogheader()
+                if not chunkdata:
                     break
-                self.bundlefilespos[chunk] = self.bundle.tell()
+                fname = chunkdata['filename']
+                self.bundlefilespos[fname] = self.bundle.tell()
                 while 1:
-                    c = self.bundle.chunk()
+                    c = self.bundle.deltachunk(None)
                     if not c:
                         break
 
--- a/mercurial/changegroup.py	Sat Apr 30 11:03:28 2011 +0200
+++ b/mercurial/changegroup.py	Sat Apr 30 19:01:24 2011 +0200
@@ -159,10 +159,21 @@
             self.callback()
         return l - 4
 
-    def chunk(self):
-        """return the next chunk from changegroup 'source' as a string"""
+    def changelogheader(self):
+        """v10 does not have a changelog header chunk"""
+        return {}
+
+    def manifestheader(self):
+        """v10 does not have a manifest header chunk"""
+        return {}
+
+    def filelogheader(self):
+        """return the header of the filelogs chunk, v10 only has the filename"""
         l = self.chunklength()
-        return readexactly(self._stream, l)
+        if not l:
+            return {}
+        fname = readexactly(self._stream, l)
+        return dict(filename=fname)
 
     def _deltaheader(self, headertuple, prevnode):
         node, p1, p2, cs = headertuple
@@ -172,7 +183,7 @@
             deltabase = prevnode
         return node, p1, p2, deltabase, cs
 
-    def parsechunk(self, prevnode):
+    def deltachunk(self, prevnode):
         l = self.chunklength()
         if not l:
             return {}
--- a/mercurial/commands.py	Sat Apr 30 11:03:28 2011 +0200
+++ b/mercurial/commands.py	Sat Apr 30 19:01:24 2011 +0200
@@ -1220,7 +1220,7 @@
                 ui.write("\n%s\n" % named)
                 chain = None
                 while 1:
-                    chunkdata = gen.parsechunk(chain)
+                    chunkdata = gen.deltachunk(chain)
                     if not chunkdata:
                         break
                     node = chunkdata['node']
@@ -1234,17 +1234,21 @@
                               hex(cs), hex(deltabase), len(delta)))
                     chain = node
 
+            chunkdata = gen.changelogheader()
             showchunks("changelog")
+            chunkdata = gen.manifestheader()
             showchunks("manifest")
             while 1:
-                fname = gen.chunk()
-                if not fname:
+                chunkdata = gen.filelogheader()
+                if not chunkdata:
                     break
+                fname = chunkdata['filename']
                 showchunks(fname)
         else:
+            chunkdata = gen.changelogheader()
             chain = None
             while 1:
-                chunkdata = gen.parsechunk(chain)
+                chunkdata = gen.deltachunk(chain)
                 if not chunkdata:
                     break
                 node = chunkdata['node']
--- a/mercurial/localrepo.py	Sat Apr 30 11:03:28 2011 +0200
+++ b/mercurial/localrepo.py	Sat Apr 30 19:01:24 2011 +0200
@@ -1712,6 +1712,7 @@
             pr = prog()
             source.callback = pr
 
+            source.changelogheader()
             if (cl.addgroup(source, csmap, trp) is None
                 and not emptyok):
                 raise util.Abort(_("received changelog group is empty"))
@@ -1731,6 +1732,7 @@
             # if the result of the merge of 1 and 2 is the same in 3 and 4,
             # no new manifest will be created and the manifest group will
             # be empty during the pull
+            source.manifestheader()
             self.manifest.addgroup(source, revmap, trp)
             self.ui.progress(_('manifests'), None)
 
@@ -1752,9 +1754,10 @@
             source.callback = None
 
             while 1:
-                f = source.chunk()
-                if not f:
+                chunkdata = source.filelogheader()
+                if not chunkdata:
                     break
+                f = chunkdata["filename"]
                 self.ui.debug("adding %s revisions\n" % f)
                 pr()
                 fl = self.file(f)
--- a/mercurial/revlog.py	Sat Apr 30 11:03:28 2011 +0200
+++ b/mercurial/revlog.py	Sat Apr 30 19:01:24 2011 +0200
@@ -1122,7 +1122,7 @@
             # loop through our set of deltas
             chain = None
             while 1:
-                chunkdata = bundle.parsechunk(chain)
+                chunkdata = bundle.deltachunk(chain)
                 if not chunkdata:
                     break
                 node = chunkdata['node']