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 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.
--- a/mercurial/commands.py Wed Nov 05 10:13:01 2014 +0000
+++ b/mercurial/commands.py Thu Nov 06 14:08:25 2014 -0800
@@ -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
--- a/mercurial/revlog.py Wed Nov 05 10:13:01 2014 +0000
+++ b/mercurial/revlog.py Thu Nov 06 14:08:25 2014 -0800
@@ -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):