Mercurial > hg > mercurial-source
changeset 14152: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 +++ b/mercurial/bundlerepo.py @@ -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 +++ b/mercurial/changegroup.py @@ -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 +++ b/mercurial/commands.py @@ -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 +++ b/mercurial/localrepo.py @@ -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)