changeset 14253:c28d5200374c

revlog: support reading generaldelta revlogs Generaldelta is a new revlog global flag. When it's turned on, the base field of each revision entry holds the deltaparent instead of the base revision of the current delta chain. This allows for great potential flexibility when generating deltas, as any revision can serve as deltaparent. Previously, the deltaparent for revision r was hardcoded to be r - 1. The base revision of the delta chain can still be accessed as before, since it is now computed in an iterative fashion, following the deltaparents backwards.
author Sune Foldager <cryo@cyanite.org>
date Sat, 07 May 2011 22:40:17 +0200
parents 19067884c5f5
children d6a762d93b77
files mercurial/revlog.py
diffstat 1 files changed, 12 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/revlog.py	Sat May 07 22:40:14 2011 +0200
+++ b/mercurial/revlog.py	Sat May 07 22:40:17 2011 +0200
@@ -27,10 +27,11 @@
 REVLOGV0 = 0
 REVLOGNG = 1
 REVLOGNGINLINEDATA = (1 << 16)
+REVLOGGENERALDELTA = (1 << 17)
 REVLOG_DEFAULT_FLAGS = REVLOGNGINLINEDATA
 REVLOG_DEFAULT_FORMAT = REVLOGNG
 REVLOG_DEFAULT_VERSION = REVLOG_DEFAULT_FORMAT | REVLOG_DEFAULT_FLAGS
-REVLOGNG_FLAGS = REVLOGNGINLINEDATA
+REVLOGNG_FLAGS = REVLOGNGINLINEDATA | REVLOGGENERALDELTA
 
 # revlog index flags
 REVIDX_KNOWN_FLAGS = 0
@@ -243,6 +244,7 @@
 
         self.version = v
         self._inline = v & REVLOGNGINLINEDATA
+        self._generaldelta = v & REVLOGGENERALDELTA
         flags = v & ~0xFFFF
         fmt = v & 0xFFFF
         if fmt == REVLOGV0 and flags:
@@ -830,8 +832,11 @@
 
     def deltaparent(self, rev):
         """return deltaparent of the given revision"""
-        if self.index[rev][3] == rev:
+        base = self.index[rev][3]
+        if base == rev:
             return nullrev
+        elif self._generaldelta:
+            return base
         else:
             return rev - 1
 
@@ -865,11 +870,15 @@
         # build delta chain
         chain = []
         index = self.index # for performance
+        generaldelta = self._generaldelta
         iterrev = rev
         e = index[iterrev]
         while iterrev != e[3] and iterrev != cachedrev:
             chain.append(iterrev)
-            iterrev -= 1
+            if generaldelta:
+                iterrev = e[3]
+            else:
+                iterrev -= 1
             e = index[iterrev]
         chain.reverse()
         base = iterrev