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 |