# HG changeset patch # User Sune Foldager # Date 1304800817 -7200 # Node ID c28d5200374c32006b97fdc37649dcaebfd0c18b # Parent 19067884c5f5964139e81371200b2da9c24c5740 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. diff -r 19067884c5f5 -r c28d5200374c mercurial/revlog.py --- 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