mercurial/debugcommands.py
changeset 49660 bd3b6f363fb9
parent 49659 7c0a383849a8
child 49676 4302db0f54c8
equal deleted inserted replaced
49659:7c0a383849a8 49660:bd3b6f363fb9
    19 import random
    19 import random
    20 import re
    20 import re
    21 import socket
    21 import socket
    22 import ssl
    22 import ssl
    23 import stat
    23 import stat
    24 import string
       
    25 import subprocess
    24 import subprocess
    26 import sys
    25 import sys
    27 import time
    26 import time
    28 
    27 
    29 from .i18n import _
    28 from .i18n import _
  3239     opts = pycompat.byteskwargs(opts)
  3238     opts = pycompat.byteskwargs(opts)
  3240     r = cmdutil.openrevlog(repo, b'debugrevlog', file_, opts)
  3239     r = cmdutil.openrevlog(repo, b'debugrevlog', file_, opts)
  3241 
  3240 
  3242     if opts.get(b"dump"):
  3241     if opts.get(b"dump"):
  3243         revlog_debug.dump(ui, r)
  3242         revlog_debug.dump(ui, r)
  3244         return 0
       
  3245 
       
  3246     format = r._format_version
       
  3247     v = r._format_flags
       
  3248     flags = []
       
  3249     gdelta = False
       
  3250     if v & revlog.FLAG_INLINE_DATA:
       
  3251         flags.append(b'inline')
       
  3252     if v & revlog.FLAG_GENERALDELTA:
       
  3253         gdelta = True
       
  3254         flags.append(b'generaldelta')
       
  3255     if not flags:
       
  3256         flags = [b'(none)']
       
  3257 
       
  3258     ### tracks merge vs single parent
       
  3259     nummerges = 0
       
  3260 
       
  3261     ### tracks ways the "delta" are build
       
  3262     # nodelta
       
  3263     numempty = 0
       
  3264     numemptytext = 0
       
  3265     numemptydelta = 0
       
  3266     # full file content
       
  3267     numfull = 0
       
  3268     # intermediate snapshot against a prior snapshot
       
  3269     numsemi = 0
       
  3270     # snapshot count per depth
       
  3271     numsnapdepth = collections.defaultdict(lambda: 0)
       
  3272     # delta against previous revision
       
  3273     numprev = 0
       
  3274     # delta against first or second parent (not prev)
       
  3275     nump1 = 0
       
  3276     nump2 = 0
       
  3277     # delta against neither prev nor parents
       
  3278     numother = 0
       
  3279     # delta against prev that are also first or second parent
       
  3280     # (details of `numprev`)
       
  3281     nump1prev = 0
       
  3282     nump2prev = 0
       
  3283 
       
  3284     # data about delta chain of each revs
       
  3285     chainlengths = []
       
  3286     chainbases = []
       
  3287     chainspans = []
       
  3288 
       
  3289     # data about each revision
       
  3290     datasize = [None, 0, 0]
       
  3291     fullsize = [None, 0, 0]
       
  3292     semisize = [None, 0, 0]
       
  3293     # snapshot count per depth
       
  3294     snapsizedepth = collections.defaultdict(lambda: [None, 0, 0])
       
  3295     deltasize = [None, 0, 0]
       
  3296     chunktypecounts = {}
       
  3297     chunktypesizes = {}
       
  3298 
       
  3299     def addsize(size, l):
       
  3300         if l[0] is None or size < l[0]:
       
  3301             l[0] = size
       
  3302         if size > l[1]:
       
  3303             l[1] = size
       
  3304         l[2] += size
       
  3305 
       
  3306     numrevs = len(r)
       
  3307     for rev in range(numrevs):
       
  3308         p1, p2 = r.parentrevs(rev)
       
  3309         delta = r.deltaparent(rev)
       
  3310         if format > 0:
       
  3311             addsize(r.rawsize(rev), datasize)
       
  3312         if p2 != nullrev:
       
  3313             nummerges += 1
       
  3314         size = r.length(rev)
       
  3315         if delta == nullrev:
       
  3316             chainlengths.append(0)
       
  3317             chainbases.append(r.start(rev))
       
  3318             chainspans.append(size)
       
  3319             if size == 0:
       
  3320                 numempty += 1
       
  3321                 numemptytext += 1
       
  3322             else:
       
  3323                 numfull += 1
       
  3324                 numsnapdepth[0] += 1
       
  3325                 addsize(size, fullsize)
       
  3326                 addsize(size, snapsizedepth[0])
       
  3327         else:
       
  3328             chainlengths.append(chainlengths[delta] + 1)
       
  3329             baseaddr = chainbases[delta]
       
  3330             revaddr = r.start(rev)
       
  3331             chainbases.append(baseaddr)
       
  3332             chainspans.append((revaddr - baseaddr) + size)
       
  3333             if size == 0:
       
  3334                 numempty += 1
       
  3335                 numemptydelta += 1
       
  3336             elif r.issnapshot(rev):
       
  3337                 addsize(size, semisize)
       
  3338                 numsemi += 1
       
  3339                 depth = r.snapshotdepth(rev)
       
  3340                 numsnapdepth[depth] += 1
       
  3341                 addsize(size, snapsizedepth[depth])
       
  3342             else:
       
  3343                 addsize(size, deltasize)
       
  3344                 if delta == rev - 1:
       
  3345                     numprev += 1
       
  3346                     if delta == p1:
       
  3347                         nump1prev += 1
       
  3348                     elif delta == p2:
       
  3349                         nump2prev += 1
       
  3350                 elif delta == p1:
       
  3351                     nump1 += 1
       
  3352                 elif delta == p2:
       
  3353                     nump2 += 1
       
  3354                 elif delta != nullrev:
       
  3355                     numother += 1
       
  3356 
       
  3357         # Obtain data on the raw chunks in the revlog.
       
  3358         if util.safehasattr(r, b'_getsegmentforrevs'):
       
  3359             segment = r._getsegmentforrevs(rev, rev)[1]
       
  3360         else:
       
  3361             segment = r._revlog._getsegmentforrevs(rev, rev)[1]
       
  3362         if segment:
       
  3363             chunktype = bytes(segment[0:1])
       
  3364         else:
       
  3365             chunktype = b'empty'
       
  3366 
       
  3367         if chunktype not in chunktypecounts:
       
  3368             chunktypecounts[chunktype] = 0
       
  3369             chunktypesizes[chunktype] = 0
       
  3370 
       
  3371         chunktypecounts[chunktype] += 1
       
  3372         chunktypesizes[chunktype] += size
       
  3373 
       
  3374     # Adjust size min value for empty cases
       
  3375     for size in (datasize, fullsize, semisize, deltasize):
       
  3376         if size[0] is None:
       
  3377             size[0] = 0
       
  3378 
       
  3379     numdeltas = numrevs - numfull - numempty - numsemi
       
  3380     numoprev = numprev - nump1prev - nump2prev
       
  3381     totalrawsize = datasize[2]
       
  3382     datasize[2] /= numrevs
       
  3383     fulltotal = fullsize[2]
       
  3384     if numfull == 0:
       
  3385         fullsize[2] = 0
       
  3386     else:
  3243     else:
  3387         fullsize[2] /= numfull
  3244         revlog_debug.debug_revlog(ui, r)
  3388     semitotal = semisize[2]
  3245     return 0
  3389     snaptotal = {}
       
  3390     if numsemi > 0:
       
  3391         semisize[2] /= numsemi
       
  3392     for depth in snapsizedepth:
       
  3393         snaptotal[depth] = snapsizedepth[depth][2]
       
  3394         snapsizedepth[depth][2] /= numsnapdepth[depth]
       
  3395 
       
  3396     deltatotal = deltasize[2]
       
  3397     if numdeltas > 0:
       
  3398         deltasize[2] /= numdeltas
       
  3399     totalsize = fulltotal + semitotal + deltatotal
       
  3400     avgchainlen = sum(chainlengths) / numrevs
       
  3401     maxchainlen = max(chainlengths)
       
  3402     maxchainspan = max(chainspans)
       
  3403     compratio = 1
       
  3404     if totalsize:
       
  3405         compratio = totalrawsize / totalsize
       
  3406 
       
  3407     basedfmtstr = b'%%%dd\n'
       
  3408     basepcfmtstr = b'%%%dd %s(%%5.2f%%%%)\n'
       
  3409 
       
  3410     def dfmtstr(max):
       
  3411         return basedfmtstr % len(str(max))
       
  3412 
       
  3413     def pcfmtstr(max, padding=0):
       
  3414         return basepcfmtstr % (len(str(max)), b' ' * padding)
       
  3415 
       
  3416     def pcfmt(value, total):
       
  3417         if total:
       
  3418             return (value, 100 * float(value) / total)
       
  3419         else:
       
  3420             return value, 100.0
       
  3421 
       
  3422     ui.writenoi18n(b'format : %d\n' % format)
       
  3423     ui.writenoi18n(b'flags  : %s\n' % b', '.join(flags))
       
  3424 
       
  3425     ui.write(b'\n')
       
  3426     fmt = pcfmtstr(totalsize)
       
  3427     fmt2 = dfmtstr(totalsize)
       
  3428     ui.writenoi18n(b'revisions     : ' + fmt2 % numrevs)
       
  3429     ui.writenoi18n(b'    merges    : ' + fmt % pcfmt(nummerges, numrevs))
       
  3430     ui.writenoi18n(
       
  3431         b'    normal    : ' + fmt % pcfmt(numrevs - nummerges, numrevs)
       
  3432     )
       
  3433     ui.writenoi18n(b'revisions     : ' + fmt2 % numrevs)
       
  3434     ui.writenoi18n(b'    empty     : ' + fmt % pcfmt(numempty, numrevs))
       
  3435     ui.writenoi18n(
       
  3436         b'                   text  : '
       
  3437         + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)
       
  3438     )
       
  3439     ui.writenoi18n(
       
  3440         b'                   delta : '
       
  3441         + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)
       
  3442     )
       
  3443     ui.writenoi18n(
       
  3444         b'    snapshot  : ' + fmt % pcfmt(numfull + numsemi, numrevs)
       
  3445     )
       
  3446     for depth in sorted(numsnapdepth):
       
  3447         ui.write(
       
  3448             (b'      lvl-%-3d :       ' % depth)
       
  3449             + fmt % pcfmt(numsnapdepth[depth], numrevs)
       
  3450         )
       
  3451     ui.writenoi18n(b'    deltas    : ' + fmt % pcfmt(numdeltas, numrevs))
       
  3452     ui.writenoi18n(b'revision size : ' + fmt2 % totalsize)
       
  3453     ui.writenoi18n(
       
  3454         b'    snapshot  : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)
       
  3455     )
       
  3456     for depth in sorted(numsnapdepth):
       
  3457         ui.write(
       
  3458             (b'      lvl-%-3d :       ' % depth)
       
  3459             + fmt % pcfmt(snaptotal[depth], totalsize)
       
  3460         )
       
  3461     ui.writenoi18n(b'    deltas    : ' + fmt % pcfmt(deltatotal, totalsize))
       
  3462 
       
  3463     def fmtchunktype(chunktype):
       
  3464         if chunktype == b'empty':
       
  3465             return b'    %s     : ' % chunktype
       
  3466         elif chunktype in pycompat.bytestr(string.ascii_letters):
       
  3467             return b'    0x%s (%s)  : ' % (hex(chunktype), chunktype)
       
  3468         else:
       
  3469             return b'    0x%s      : ' % hex(chunktype)
       
  3470 
       
  3471     ui.write(b'\n')
       
  3472     ui.writenoi18n(b'chunks        : ' + fmt2 % numrevs)
       
  3473     for chunktype in sorted(chunktypecounts):
       
  3474         ui.write(fmtchunktype(chunktype))
       
  3475         ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
       
  3476     ui.writenoi18n(b'chunks size   : ' + fmt2 % totalsize)
       
  3477     for chunktype in sorted(chunktypecounts):
       
  3478         ui.write(fmtchunktype(chunktype))
       
  3479         ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
       
  3480 
       
  3481     ui.write(b'\n')
       
  3482     fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
       
  3483     ui.writenoi18n(b'avg chain length  : ' + fmt % avgchainlen)
       
  3484     ui.writenoi18n(b'max chain length  : ' + fmt % maxchainlen)
       
  3485     ui.writenoi18n(b'max chain reach   : ' + fmt % maxchainspan)
       
  3486     ui.writenoi18n(b'compression ratio : ' + fmt % compratio)
       
  3487 
       
  3488     if format > 0:
       
  3489         ui.write(b'\n')
       
  3490         ui.writenoi18n(
       
  3491             b'uncompressed data size (min/max/avg) : %d / %d / %d\n'
       
  3492             % tuple(datasize)
       
  3493         )
       
  3494     ui.writenoi18n(
       
  3495         b'full revision size (min/max/avg)     : %d / %d / %d\n'
       
  3496         % tuple(fullsize)
       
  3497     )
       
  3498     ui.writenoi18n(
       
  3499         b'inter-snapshot size (min/max/avg)    : %d / %d / %d\n'
       
  3500         % tuple(semisize)
       
  3501     )
       
  3502     for depth in sorted(snapsizedepth):
       
  3503         if depth == 0:
       
  3504             continue
       
  3505         ui.writenoi18n(
       
  3506             b'    level-%-3d (min/max/avg)          : %d / %d / %d\n'
       
  3507             % ((depth,) + tuple(snapsizedepth[depth]))
       
  3508         )
       
  3509     ui.writenoi18n(
       
  3510         b'delta size (min/max/avg)             : %d / %d / %d\n'
       
  3511         % tuple(deltasize)
       
  3512     )
       
  3513 
       
  3514     if numdeltas > 0:
       
  3515         ui.write(b'\n')
       
  3516         fmt = pcfmtstr(numdeltas)
       
  3517         fmt2 = pcfmtstr(numdeltas, 4)
       
  3518         ui.writenoi18n(
       
  3519             b'deltas against prev  : ' + fmt % pcfmt(numprev, numdeltas)
       
  3520         )
       
  3521         if numprev > 0:
       
  3522             ui.writenoi18n(
       
  3523                 b'    where prev = p1  : ' + fmt2 % pcfmt(nump1prev, numprev)
       
  3524             )
       
  3525             ui.writenoi18n(
       
  3526                 b'    where prev = p2  : ' + fmt2 % pcfmt(nump2prev, numprev)
       
  3527             )
       
  3528             ui.writenoi18n(
       
  3529                 b'    other            : ' + fmt2 % pcfmt(numoprev, numprev)
       
  3530             )
       
  3531         if gdelta:
       
  3532             ui.writenoi18n(
       
  3533                 b'deltas against p1    : ' + fmt % pcfmt(nump1, numdeltas)
       
  3534             )
       
  3535             ui.writenoi18n(
       
  3536                 b'deltas against p2    : ' + fmt % pcfmt(nump2, numdeltas)
       
  3537             )
       
  3538             ui.writenoi18n(
       
  3539                 b'deltas against other : ' + fmt % pcfmt(numother, numdeltas)
       
  3540             )
       
  3541 
  3246 
  3542 
  3247 
  3543 @command(
  3248 @command(
  3544     b'debugrevlogindex',
  3249     b'debugrevlogindex',
  3545     cmdutil.debugrevlogopts
  3250     cmdutil.debugrevlogopts