comparison mercurial/revlog.py @ 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 d6907a5674a2
comparison
equal deleted inserted replaced
14252:19067884c5f5 14253:c28d5200374c
25 25
26 # revlog header flags 26 # revlog header flags
27 REVLOGV0 = 0 27 REVLOGV0 = 0
28 REVLOGNG = 1 28 REVLOGNG = 1
29 REVLOGNGINLINEDATA = (1 << 16) 29 REVLOGNGINLINEDATA = (1 << 16)
30 REVLOGGENERALDELTA = (1 << 17)
30 REVLOG_DEFAULT_FLAGS = REVLOGNGINLINEDATA 31 REVLOG_DEFAULT_FLAGS = REVLOGNGINLINEDATA
31 REVLOG_DEFAULT_FORMAT = REVLOGNG 32 REVLOG_DEFAULT_FORMAT = REVLOGNG
32 REVLOG_DEFAULT_VERSION = REVLOG_DEFAULT_FORMAT | REVLOG_DEFAULT_FLAGS 33 REVLOG_DEFAULT_VERSION = REVLOG_DEFAULT_FORMAT | REVLOG_DEFAULT_FLAGS
33 REVLOGNG_FLAGS = REVLOGNGINLINEDATA 34 REVLOGNG_FLAGS = REVLOGNGINLINEDATA | REVLOGGENERALDELTA
34 35
35 # revlog index flags 36 # revlog index flags
36 REVIDX_KNOWN_FLAGS = 0 37 REVIDX_KNOWN_FLAGS = 0
37 38
38 # max size of revlog with inline data 39 # max size of revlog with inline data
241 if inst.errno != errno.ENOENT: 242 if inst.errno != errno.ENOENT:
242 raise 243 raise
243 244
244 self.version = v 245 self.version = v
245 self._inline = v & REVLOGNGINLINEDATA 246 self._inline = v & REVLOGNGINLINEDATA
247 self._generaldelta = v & REVLOGGENERALDELTA
246 flags = v & ~0xFFFF 248 flags = v & ~0xFFFF
247 fmt = v & 0xFFFF 249 fmt = v & 0xFFFF
248 if fmt == REVLOGV0 and flags: 250 if fmt == REVLOGV0 and flags:
249 raise RevlogError(_("index %s unknown flags %#04x for format v0") 251 raise RevlogError(_("index %s unknown flags %#04x for format v0")
250 % (self.indexfile, flags >> 16)) 252 % (self.indexfile, flags >> 16))
828 def _chunkclear(self): 830 def _chunkclear(self):
829 self._chunkcache = (0, '') 831 self._chunkcache = (0, '')
830 832
831 def deltaparent(self, rev): 833 def deltaparent(self, rev):
832 """return deltaparent of the given revision""" 834 """return deltaparent of the given revision"""
833 if self.index[rev][3] == rev: 835 base = self.index[rev][3]
836 if base == rev:
834 return nullrev 837 return nullrev
838 elif self._generaldelta:
839 return base
835 else: 840 else:
836 return rev - 1 841 return rev - 1
837 842
838 def revdiff(self, rev1, rev2): 843 def revdiff(self, rev1, rev2):
839 """return or calculate a delta between two revisions""" 844 """return or calculate a delta between two revisions"""
863 (self.flags(rev) & ~REVIDX_KNOWN_FLAGS)) 868 (self.flags(rev) & ~REVIDX_KNOWN_FLAGS))
864 869
865 # build delta chain 870 # build delta chain
866 chain = [] 871 chain = []
867 index = self.index # for performance 872 index = self.index # for performance
873 generaldelta = self._generaldelta
868 iterrev = rev 874 iterrev = rev
869 e = index[iterrev] 875 e = index[iterrev]
870 while iterrev != e[3] and iterrev != cachedrev: 876 while iterrev != e[3] and iterrev != cachedrev:
871 chain.append(iterrev) 877 chain.append(iterrev)
872 iterrev -= 1 878 if generaldelta:
879 iterrev = e[3]
880 else:
881 iterrev -= 1
873 e = index[iterrev] 882 e = index[iterrev]
874 chain.reverse() 883 chain.reverse()
875 base = iterrev 884 base = iterrev
876 885
877 if iterrev == cachedrev: 886 if iterrev == cachedrev: