Mercurial > hg
comparison mercurial/debugcommands.py @ 49660:bd3b6f363fb9
debug-revlog: move the code in revlogutils module
We have a module dedicated to debug code, let us use it.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Mon, 07 Nov 2022 14:24:52 -0500 |
parents | 7c0a383849a8 |
children | 4302db0f54c8 |
comparison
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 |