Patchwork [1,of,2] debugrevlog: fix computing chain length in debugrevlog -d

login
register
mail settings
Submitter Mateusz Kwapich
Date Nov. 10, 2014, 7:27 p.m.
Message ID <79ae6c4132b5c582ea7d.1415647660@devrs014.prn2.facebook.com>
Download mbox | patch
Permalink /patch/6668/
State Accepted
Headers show

Comments

Mateusz Kwapich - Nov. 10, 2014, 7:27 p.m.
# HG changeset patch
# User Mateusz Kwapich <mitrandir@fb.com>
# Date 1415311705 28800
#      Thu Nov 06 14:08:25 2014 -0800
# Node ID 79ae6c4132b5c582ea7dbd1aa4af8e2bcd2f5973
# Parent  2d54aa5397cdb1c697673ba10b7618d5ac25c69e
debugrevlog: fix computing chain length in debugrevlog -d

The chain length was computed correctly only when generaldelta
feature was enabled. Now it's fixed.


When the generaldelta is disabled the base revision in revlog index is not
the revision we have delta against - it's always previous revision.

Instead of incorrect chainbaseandlen in command.py we are now using two
single-responsibility functions in revlog.py:
 - chainbase(rev)
 - chainlen(rev)
Only chainlen(rev) was missing so it was written to mimic the way the
chain of deltas is actually found during file reconstruction.

Patch

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2653,22 +2653,13 @@ 
                  " rawsize totalsize compression heads chainlen\n")
         ts = 0
         heads = set()
-        rindex = r.index
-
-        def chainbaseandlen(rev):
-            clen = 0
-            base = rindex[rev][3]
-            while base != rev:
-                clen += 1
-                rev = base
-                base = rindex[rev][3]
-            return base, clen
 
         for rev in xrange(numrevs):
             dbase = r.deltaparent(rev)
             if dbase == -1:
                 dbase = rev
-            cbase, clen = chainbaseandlen(rev)
+            cbase = r.chainbase(rev)
+            clen = r.chainlen(rev)
             p1, p2 = r.parentrevs(rev)
             rs = r.rawsize(rev)
             ts = ts + rs
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -350,6 +350,20 @@ 
             rev = base
             base = index[rev][3]
         return base
+    def chainlen(self, rev):
+        index = self.index
+        generaldelta = self._generaldelta
+        iterrev = rev
+        e = index[iterrev]
+        clen = 0
+        while iterrev != e[3]:
+            clen += 1
+            if generaldelta:
+                iterrev = e[3]
+            else:
+                iterrev -= 1
+            e = index[iterrev]
+        return clen
     def flags(self, rev):
         return self.index[rev][0] & 0xFFFF
     def rawsize(self, rev):