unbundler: separate delta and header parsing
Add header parsing for changelog and manifest (currently no headers might
change for next-gen bundle).
--- 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']