revlog: fix for generaldelta distance calculation
The decision whether or not to store a full snapshot instead of a delta is done
based on the distance value calculated in _addrevision.builddelta(rev).
This calculation traditionally used the fact of deltas only using the previous
revision as base. Generaldelta mechanism is changing this, yet the calculation
still assumes that current-offset minus chainbase-offset equals chain-length.
This appears to be wrong.
This patch corrects the calculation by means of using the chainlength function
if Generaldelta is used.
--- a/mercurial/revlog.py Wed Jul 11 15:05:06 2012 -0700
+++ b/mercurial/revlog.py Wed Jul 11 12:38:42 2012 +0200
@@ -349,6 +349,15 @@
rev = base
base = index[rev][3]
return base
+ def chainlength(self, rev):
+ index = self.index
+ base = index[rev][3]
+ length = index[rev][1]
+ while base != rev:
+ rev = base
+ base = index[rev][3]
+ length = length + index[rev][1]
+ return length
def flags(self, rev):
return self.index[rev][0] & 0xFFFF
def rawsize(self, rev):
@@ -1046,10 +1055,11 @@
chainbase = basecache[1]
else:
chainbase = self.chainbase(rev)
- dist = l + offset - self.start(chainbase)
if self._generaldelta:
+ dist = l + self.chainlength(rev)
base = rev
else:
+ dist = l + offset - self.start(chainbase)
base = chainbase
return dist, l, data, base, chainbase