revlog: fix for generaldelta distance calculation
authorFriedrich Kastner-Masilko <kastner_masilko@at.festo.com>
Wed, 11 Jul 2012 12:38:42 +0200
changeset 17134 e7167007c083
parent 17133 9937484e8634
child 17135 06733dfe1a43
child 17136 de8173d0c326
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.
mercurial/revlog.py
--- 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