def debugrevlog()

in eden/scm/edenscm/mercurial/commands/debug.py [0:0]


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 range(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.FLAG_INLINE_DATA:
        flags.append("inline")
    if v & revlog.FLAG_GENERALDELTA:
        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 = []
    chainbases = []
    chainspans = []

    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 range(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)
            chainbases.append(r.start(rev))
            chainspans.append(size)
            numfull += 1
            addsize(size, fullsize)
        else:
            chainlengths.append(chainlengths[delta] + 1)
            baseaddr = chainbases[delta]
            revaddr = r.start(rev)
            chainbases.append(baseaddr)
            chainspans.append((revaddr - baseaddr) + size)
            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.
        segment = r._getsegmentforrevs(rev, rev)[1]
        if segment:
            chunktype = bytes(segment[0:1]).decode("utf8")
        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)
    maxchainspan = max(chainspans)
    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(_x("format : %d\n") % format)
    ui.write(_x("flags  : %s\n") % ", ".join(flags))

    ui.write("\n")
    fmt = pcfmtstr(totalsize)
    fmt2 = dfmtstr(totalsize)
    ui.write(_x("revisions     : ") + fmt2 % numrevs)
    ui.write(_x("    merges    : ") + fmt % pcfmt(nummerges, numrevs))
    ui.write(_x("    normal    : ") + fmt % pcfmt(numrevs - nummerges, numrevs))
    ui.write(_x("revisions     : ") + fmt2 % numrevs)
    ui.write(_x("    full      : ") + fmt % pcfmt(numfull, numrevs))
    ui.write(_x("    deltas    : ") + fmt % pcfmt(numdeltas, numrevs))
    ui.write(_x("revision size : ") + fmt2 % totalsize)
    ui.write(_x("    full      : ") + fmt % pcfmt(fulltotal, totalsize))
    ui.write(_x("    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[0].encode("utf8")),
                chunktype[0],
            )
        else:
            return "    0x%s      : " % hex(chunktype[0].encode("utf8"))

    ui.write("\n")
    ui.write(_x("chunks        : ") + fmt2 % numrevs)
    for chunktype in sorted(chunktypecounts):
        ui.write(fmtchunktype(chunktype))
        ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
    ui.write(_x("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, maxchainlen, maxchainspan, compratio))
    ui.write(_x("avg chain length  : ") + fmt % avgchainlen)
    ui.write(_x("max chain length  : ") + fmt % maxchainlen)
    ui.write(_x("max chain reach   : ") + fmt % maxchainspan)
    ui.write(_x("compression ratio : ") + fmt % compratio)

    if format > 0:
        ui.write("\n")
        ui.write(
            _x("uncompressed data size (min/max/avg) : %d / %d / %d\n")
            % tuple(datasize)
        )
    ui.write(
        _x("full revision size (min/max/avg)     : %d / %d / %d\n") % tuple(fullsize)
    )
    ui.write(
        _x("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(_x("deltas against prev  : ") + fmt % pcfmt(numprev, numdeltas))
        if numprev > 0:
            ui.write(_x("    where prev = p1  : ") + fmt2 % pcfmt(nump1prev, numprev))
            ui.write(_x("    where prev = p2  : ") + fmt2 % pcfmt(nump2prev, numprev))
            ui.write(_x("    other            : ") + fmt2 % pcfmt(numoprev, numprev))
        if gdelta:
            ui.write(_x("deltas against p1    : ") + fmt % pcfmt(nump1, numdeltas))
            ui.write(_x("deltas against p2    : ") + fmt % pcfmt(nump2, numdeltas))
            ui.write(_x("deltas against other : ") + fmt % pcfmt(numother, numdeltas))