[PATCH 4 of 4] revlog: support writing generaldelta revlogs
Sune Foldager
cryo at cyanite.org
Thu May 5 11:27:59 CDT 2011
# HG changeset patch
# User Sune Foldager <cryo at cyanite.org>
# Date 1304611540 -7200
# Node ID 51e850f8e2901a032e5a13f0ea1ea140570ae8b4
# Parent ff44313cbdf6f92626f2bb8cc1e0b790be52975b
revlog: support writing generaldelta revlogs
When adding revisions, and building a delta chain, deltas are computed against
the previous revision as well as the first parent. The smaller one is then
stored in the revlog. This is similar to the now removed parentdelta feature.
diff -r ff44313cbdf6 -r 51e850f8e290 mercurial/commands.py
--- a/mercurial/commands.py Thu May 05 18:05:36 2011 +0200
+++ b/mercurial/commands.py Thu May 05 18:05:40 2011 +0200
@@ -1550,28 +1550,38 @@
if not r:
r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
+ generaldelta = r.version & revlog.REVLOGGENERALDELTA
+ if generaldelta:
+ basehdr = ' delta'
+ else:
+ basehdr = ' base'
+
if format == 0:
- ui.write(" rev offset length base linkrev"
+ ui.write(" rev offset length " + basehdr + " linkrev"
" nodeid p1 p2\n")
elif format == 1:
ui.write(" rev flag offset length"
- " size base link p1 p2 nodeid\n")
+ " size " + basehdr + " link p1 p2 nodeid\n")
for i in r:
node = r.node(i)
+ if generaldelta:
+ base = r.deltaparent(i)
+ else:
+ base = r.chainbase(i)
if format == 0:
try:
pp = r.parents(node)
except:
pp = [nullid, nullid]
ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
- i, r.start(i), r.length(i), r.chainbase(i), r.linkrev(i),
+ i, r.start(i), r.length(i), base, r.linkrev(i),
short(node), short(pp[0]), short(pp[1])))
elif format == 1:
pr = r.parentrevs(i)
ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
- r.chainbase(i), r.linkrev(i), pr[0], pr[1], short(node)))
+ base, r.linkrev(i), pr[0], pr[1], short(node)))
def debugindexdot(ui, repo, file_):
"""dump an index DAG as a graphviz dot file"""
diff -r ff44313cbdf6 -r 51e850f8e290 mercurial/localrepo.py
--- a/mercurial/localrepo.py Thu May 05 18:05:36 2011 +0200
+++ b/mercurial/localrepo.py Thu May 05 18:05:40 2011 +0200
@@ -21,7 +21,7 @@
class localrepository(repo.repository):
capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey',
'known', 'getbundle'))
- supportedformats = set(('revlogv1',))
+ supportedformats = set(('revlogv1', 'generaldelta'))
supported = supportedformats | set(('store', 'fncache', 'shared',
'dotencode'))
@@ -61,6 +61,8 @@
'\0\0\0\2' # represents revlogv2
' dummy changelog to prevent using the old repo layout'
)
+ if self.ui.configbool('format', 'generaldelta', False):
+ requirements.append("generaldelta")
else:
raise error.RepoError(_("repository %s not found") % path)
elif create:
@@ -115,6 +117,8 @@
def _applyrequirements(self, requirements):
self.requirements = requirements
self.sopener.options = {}
+ if 'generaldelta' in requirements:
+ self.sopener.options['generaldelta'] = 1
def _writerequirements(self):
reqfile = self.opener("requires", "w")
diff -r ff44313cbdf6 -r 51e850f8e290 mercurial/revlog.py
--- a/mercurial/revlog.py Thu May 05 18:05:36 2011 +0200
+++ b/mercurial/revlog.py Thu May 05 18:05:40 2011 +0200
@@ -227,10 +227,13 @@
self._nodepos = None
v = REVLOG_DEFAULT_VERSION
- if hasattr(opener, 'options') and 'defversion' in opener.options:
- v = opener.options['defversion']
- if v & REVLOGNG:
- v |= REVLOGNGINLINEDATA
+ if hasattr(opener, 'options'):
+ if 'defversion' in opener.options:
+ v = opener.options['defversion']
+ if v & REVLOGNG:
+ v |= REVLOGNGINLINEDATA
+ if v & REVLOGNG and 'generaldelta' in opener.options:
+ v |= REVLOGGENERALDELTA
if shallowroot:
v |= REVLOGSHALLOW
@@ -1006,8 +1009,12 @@
delta = mdiff.textdiff(ptext, t)
data = compress(delta)
l = len(data[1]) + len(data[0])
- base = self.chainbase(rev)
- dist = l + offset - self.start(base)
+ chainbase = self.chainbase(rev)
+ dist = l + offset - self.start(chainbase)
+ if self._generaldelta:
+ base = rev
+ else:
+ base = chainbase
return dist, l, data, base
curr = len(self)
@@ -1021,6 +1028,10 @@
# should we try to build a delta?
if prev != nullrev:
d = builddelta(prev)
+ if self._generaldelta and prev != p1r:
+ d2 = builddelta(p1r)
+ if d2 < d:
+ d = d2
dist, l, data, base = d
# full versions are inserted when the needed deltas
More information about the Mercurial-devel
mailing list