changeset 14270:d6907a5674a2

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.
author Sune Foldager <cryo@cyanite.org>
date Sun, 08 May 2011 21:32:33 +0200
parents 66257848c154
children 01472f8f5429
files mercurial/localrepo.py mercurial/revlog.py
diffstat 2 files changed, 23 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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