revlog: support writing generaldelta revlogs
With generaldelta switched on, deltas are always computed against the first
parent when adding revisions. This is done regardless of what revision the
incoming bundle, if any, is deltaed against.
The exact delta building strategy is subject to change, but this will not
affect compatibility.
Generaldelta is switched off by default.
--- a/mercurial/localrepo.py Sun May 08 21:24:30 2011 +0200
+++ b/mercurial/localrepo.py Sun May 08 21:32:33 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")
--- a/mercurial/revlog.py Sun May 08 21:24:30 2011 +0200
+++ b/mercurial/revlog.py Sun May 08 21:32:33 2011 +0200
@@ -226,10 +226,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
i = ''
try:
@@ -1003,10 +1006,14 @@
l = len(data[1]) + len(data[0])
basecache = self._basecache
if basecache and basecache[0] == rev:
- base = basecache[1]
+ chainbase = basecache[1]
else:
- 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)
@@ -1019,7 +1026,10 @@
# should we try to build a delta?
if prev != nullrev:
- d = builddelta(prev)
+ if self._generaldelta:
+ d = builddelta(p1r)
+ else:
+ d = builddelta(prev)
dist, l, data, base = d
# full versions are inserted when the needed deltas