--- a/mercurial/debugcommands.py Thu Feb 02 10:01:54 2017 +0100
+++ b/mercurial/debugcommands.py Thu Feb 02 10:02:40 2017 +0100
@@ -12,6 +12,7 @@
import os
import random
import socket
+import string
import sys
import tempfile
import time
@@ -22,6 +23,7 @@
hex,
nullhex,
nullid,
+ nullrev,
short,
)
from . import (
@@ -1517,6 +1519,226 @@
else:
ui.write(_("%s not renamed\n") % rel)
+@command('debugrevlog', commands.debugrevlogopts +
+ [('d', 'dump', False, _('dump index data'))],
+ _('-c|-m|FILE'),
+ optionalrepo=True)
+def debugrevlog(ui, repo, file_=None, **opts):
+ """show data and statistics about a revlog"""
+ r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
+
+ if opts.get("dump"):
+ numrevs = len(r)
+ ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
+ " rawsize totalsize compression heads chainlen\n"))
+ ts = 0
+ heads = set()
+
+ for rev in xrange(numrevs):
+ dbase = r.deltaparent(rev)
+ if dbase == -1:
+ dbase = rev
+ cbase = r.chainbase(rev)
+ clen = r.chainlen(rev)
+ p1, p2 = r.parentrevs(rev)
+ rs = r.rawsize(rev)
+ ts = ts + rs
+ heads -= set(r.parentrevs(rev))
+ heads.add(rev)
+ try:
+ compression = ts / r.end(rev)
+ except ZeroDivisionError:
+ compression = 0
+ ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
+ "%11d %5d %8d\n" %
+ (rev, p1, p2, r.start(rev), r.end(rev),
+ r.start(dbase), r.start(cbase),
+ r.start(p1), r.start(p2),
+ rs, ts, compression, len(heads), clen))
+ return 0
+
+ v = r.version
+ format = v & 0xFFFF
+ flags = []
+ gdelta = False
+ if v & revlog.REVLOGNGINLINEDATA:
+ flags.append('inline')
+ if v & revlog.REVLOGGENERALDELTA:
+ gdelta = True
+ flags.append('generaldelta')
+ if not flags:
+ flags = ['(none)']
+
+ nummerges = 0
+ numfull = 0
+ numprev = 0
+ nump1 = 0
+ nump2 = 0
+ numother = 0
+ nump1prev = 0
+ nump2prev = 0
+ chainlengths = []
+
+ datasize = [None, 0, 0]
+ fullsize = [None, 0, 0]
+ deltasize = [None, 0, 0]
+ chunktypecounts = {}
+ chunktypesizes = {}
+
+ def addsize(size, l):
+ if l[0] is None or size < l[0]:
+ l[0] = size
+ if size > l[1]:
+ l[1] = size
+ l[2] += size
+
+ numrevs = len(r)
+ for rev in xrange(numrevs):
+ p1, p2 = r.parentrevs(rev)
+ delta = r.deltaparent(rev)
+ if format > 0:
+ addsize(r.rawsize(rev), datasize)
+ if p2 != nullrev:
+ nummerges += 1
+ size = r.length(rev)
+ if delta == nullrev:
+ chainlengths.append(0)
+ numfull += 1
+ addsize(size, fullsize)
+ else:
+ chainlengths.append(chainlengths[delta] + 1)
+ addsize(size, deltasize)
+ if delta == rev - 1:
+ numprev += 1
+ if delta == p1:
+ nump1prev += 1
+ elif delta == p2:
+ nump2prev += 1
+ elif delta == p1:
+ nump1 += 1
+ elif delta == p2:
+ nump2 += 1
+ elif delta != nullrev:
+ numother += 1
+
+ # Obtain data on the raw chunks in the revlog.
+ chunk = r._chunkraw(rev, rev)[1]
+ if chunk:
+ chunktype = chunk[0]
+ else:
+ chunktype = 'empty'
+
+ if chunktype not in chunktypecounts:
+ chunktypecounts[chunktype] = 0
+ chunktypesizes[chunktype] = 0
+
+ chunktypecounts[chunktype] += 1
+ chunktypesizes[chunktype] += size
+
+ # Adjust size min value for empty cases
+ for size in (datasize, fullsize, deltasize):
+ if size[0] is None:
+ size[0] = 0
+
+ numdeltas = numrevs - numfull
+ numoprev = numprev - nump1prev - nump2prev
+ totalrawsize = datasize[2]
+ datasize[2] /= numrevs
+ fulltotal = fullsize[2]
+ fullsize[2] /= numfull
+ deltatotal = deltasize[2]
+ if numrevs - numfull > 0:
+ deltasize[2] /= numrevs - numfull
+ totalsize = fulltotal + deltatotal
+ avgchainlen = sum(chainlengths) / numrevs
+ maxchainlen = max(chainlengths)
+ compratio = 1
+ if totalsize:
+ compratio = totalrawsize / totalsize
+
+ basedfmtstr = '%%%dd\n'
+ basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
+
+ def dfmtstr(max):
+ return basedfmtstr % len(str(max))
+ def pcfmtstr(max, padding=0):
+ return basepcfmtstr % (len(str(max)), ' ' * padding)
+
+ def pcfmt(value, total):
+ if total:
+ return (value, 100 * float(value) / total)
+ else:
+ return value, 100.0
+
+ ui.write(('format : %d\n') % format)
+ ui.write(('flags : %s\n') % ', '.join(flags))
+
+ ui.write('\n')
+ fmt = pcfmtstr(totalsize)
+ fmt2 = dfmtstr(totalsize)
+ ui.write(('revisions : ') + fmt2 % numrevs)
+ ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
+ ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
+ ui.write(('revisions : ') + fmt2 % numrevs)
+ ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
+ ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
+ ui.write(('revision size : ') + fmt2 % totalsize)
+ ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
+ ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
+
+ def fmtchunktype(chunktype):
+ if chunktype == 'empty':
+ return ' %s : ' % chunktype
+ elif chunktype in string.ascii_letters:
+ return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
+ else:
+ return ' 0x%s : ' % hex(chunktype)
+
+ ui.write('\n')
+ ui.write(('chunks : ') + fmt2 % numrevs)
+ for chunktype in sorted(chunktypecounts):
+ ui.write(fmtchunktype(chunktype))
+ ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
+ ui.write(('chunks size : ') + fmt2 % totalsize)
+ for chunktype in sorted(chunktypecounts):
+ ui.write(fmtchunktype(chunktype))
+ ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
+
+ ui.write('\n')
+ fmt = dfmtstr(max(avgchainlen, compratio))
+ ui.write(('avg chain length : ') + fmt % avgchainlen)
+ ui.write(('max chain length : ') + fmt % maxchainlen)
+ ui.write(('compression ratio : ') + fmt % compratio)
+
+ if format > 0:
+ ui.write('\n')
+ ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
+ % tuple(datasize))
+ ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
+ % tuple(fullsize))
+ ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
+ % tuple(deltasize))
+
+ if numdeltas > 0:
+ ui.write('\n')
+ fmt = pcfmtstr(numdeltas)
+ fmt2 = pcfmtstr(numdeltas, 4)
+ ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
+ if numprev > 0:
+ ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
+ numprev))
+ ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
+ numprev))
+ ui.write((' other : ') + fmt2 % pcfmt(numoprev,
+ numprev))
+ if gdelta:
+ ui.write(('deltas against p1 : ')
+ + fmt % pcfmt(nump1, numdeltas))
+ ui.write(('deltas against p2 : ')
+ + fmt % pcfmt(nump2, numdeltas))
+ ui.write(('deltas against other : ') + fmt % pcfmt(numother,
+ numdeltas))
+
@command('debugupgraderepo', [
('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
('', 'run', False, _('performs an upgrade')),