[PATCH 3 of 4] revlog: support reading generaldelta revlogs

Sune Foldager cryo at cyanite.org
Thu May 5 11:27:58 CDT 2011


# HG changeset patch
# User Sune Foldager <cryo at cyanite.org>
# Date 1304611536 -7200
# Node ID ff44313cbdf6f92626f2bb8cc1e0b790be52975b
# Parent  e94b057be38fc9362d4ea3f50d22d0470502b617
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 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.

diff -r e94b057be38f -r ff44313cbdf6 mercurial/revlog.py
--- a/mercurial/revlog.py	Thu May 05 18:05:30 2011 +0200
+++ b/mercurial/revlog.py	Thu May 05 18:05:36 2011 +0200
@@ -28,10 +28,11 @@
 REVLOGNG = 1
 REVLOGNGINLINEDATA = (1 << 16)
 REVLOGSHALLOW = (1 << 17)
+REVLOGGENERALDELTA = (1 << 18)
 REVLOG_DEFAULT_FLAGS = REVLOGNGINLINEDATA
 REVLOG_DEFAULT_FORMAT = REVLOGNG
 REVLOG_DEFAULT_VERSION = REVLOG_DEFAULT_FORMAT | REVLOG_DEFAULT_FLAGS
-REVLOGNG_FLAGS = REVLOGNGINLINEDATA | REVLOGSHALLOW
+REVLOGNG_FLAGS = REVLOGNGINLINEDATA | REVLOGSHALLOW | REVLOGGENERALDELTA
 
 # revlog index flags
 REVIDX_KNOWN_FLAGS = 0
@@ -248,6 +249,7 @@
         self.version = v
         self._inline = v & REVLOGNGINLINEDATA
         self._shallow = v & REVLOGSHALLOW
+        self._generaldelta = v & REVLOGGENERALDELTA
         flags = v & ~0xFFFF
         fmt = v & 0xFFFF
         if fmt == REVLOGV0 and flags:
@@ -835,8 +837,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
 
@@ -870,11 +875,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


More information about the Mercurial-devel mailing list