# HG changeset patch # User Pierre-Yves David # Date 1667849932 18000 # Node ID 511106bcb16ca0e1ca496fb2e966a76b892a3a0a # Parent bd3b6f363fb9daef356e384aec7efada40e6b47b debug-revlog: details about non-ancestors delta-bases Deltas against a base that is not an ancestor of the revision that owns this delta are notable. For example, they introduce complexity during the bundling process as the base might not exist on the unbundling side. We detect them in `hg debugrevlog` and print information about them. diff -r bd3b6f363fb9 -r 511106bcb16c mercurial/revlogutils/debug.py --- a/mercurial/revlogutils/debug.py Mon Nov 07 14:24:52 2022 -0500 +++ b/mercurial/revlogutils/debug.py Mon Nov 07 14:38:52 2022 -0500 @@ -302,13 +302,19 @@ numsemi = 0 # snapshot count per depth numsnapdepth = collections.defaultdict(lambda: 0) + # number of snapshots with a non-ancestor delta + numsnapdepth_nad = collections.defaultdict(lambda: 0) # delta against previous revision numprev = 0 + # delta against prev, where prev is a non-ancestor + numprev_nad = 0 # delta against first or second parent (not prev) nump1 = 0 nump2 = 0 # delta against neither prev nor parents numother = 0 + # delta against other that is a non-ancestor + numother_nad = 0 # delta against prev that are also first or second parent # (details of `numprev`) nump1prev = 0 @@ -358,6 +364,9 @@ addsize(size, fullsize) addsize(size, snapsizedepth[0]) else: + nad = ( + delta != p1 and delta != p2 and not r.isancestorrev(delta, rev) + ) chainlengths.append(chainlengths[delta] + 1) baseaddr = chainbases[delta] revaddr = r.start(rev) @@ -371,6 +380,8 @@ numsemi += 1 depth = r.snapshotdepth(rev) numsnapdepth[depth] += 1 + if nad: + numsnapdepth_nad[depth] += 1 addsize(size, snapsizedepth[depth]) else: addsize(size, deltasize) @@ -380,12 +391,15 @@ nump1prev += 1 elif delta == p2: nump2prev += 1 + elif nad: + numprev_nad += 1 elif delta == p1: nump1 += 1 elif delta == p2: nump2 += 1 elif delta != nodemod.nullrev: numother += 1 + numother_nad += 1 # Obtain data on the raw chunks in the revlog. if util.safehasattr(r, '_getsegmentforrevs'): @@ -410,7 +424,8 @@ size[0] = 0 numdeltas = numrevs - numfull - numempty - numsemi - numoprev = numprev - nump1prev - nump2prev + numoprev = numprev - nump1prev - nump2prev - numprev_nad + num_other_ancestors = numother - numother_nad totalrawsize = datasize[2] datasize[2] /= numrevs fulltotal = fullsize[2] @@ -477,10 +492,17 @@ b' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs) ) for depth in sorted(numsnapdepth): - ui.write( - (b' lvl-%-3d : ' % depth) - + fmt % pcfmt(numsnapdepth[depth], numrevs) - ) + base = b' lvl-%-3d : ' % depth + count = fmt % pcfmt(numsnapdepth[depth], numrevs) + pieces = [base, count] + if numsnapdepth_nad[depth]: + pieces[-1] = count = count[:-1] # drop the final '\n' + more = b' non-ancestor-bases: ' + anc_count = fmt + anc_count %= pcfmt(numsnapdepth_nad[depth], numsnapdepth[depth]) + pieces.append(more) + pieces.append(anc_count) + ui.write(b''.join(pieces)) ui.writenoi18n(b' deltas : ' + fmt % pcfmt(numdeltas, numrevs)) ui.writenoi18n(b'revision size : ' + fmt2 % totalsize) ui.writenoi18n( @@ -561,7 +583,10 @@ b' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev) ) ui.writenoi18n( - b' other : ' + fmt2 % pcfmt(numoprev, numprev) + b' other-ancestor : ' + fmt2 % pcfmt(numoprev, numprev) + ) + ui.writenoi18n( + b' unrelated : ' + fmt2 % pcfmt(numoprev, numprev) ) if gdelta: ui.writenoi18n( @@ -571,5 +596,10 @@ b'deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas) ) ui.writenoi18n( - b'deltas against other : ' + fmt % pcfmt(numother, numdeltas) + b'deltas against ancs : ' + + fmt % pcfmt(num_other_ancestors, numdeltas) ) + ui.writenoi18n( + b'deltas against other : ' + + fmt % pcfmt(numother_nad, numdeltas) + ) diff -r bd3b6f363fb9 -r 511106bcb16c tests/test-sparse-revlog.t --- a/tests/test-sparse-revlog.t Mon Nov 07 14:24:52 2022 -0500 +++ b/tests/test-sparse-revlog.t Mon Nov 07 14:38:52 2022 -0500 @@ -105,11 +105,11 @@ delta : 0 (100.00%) snapshot : 383 ( 7.66%) lvl-0 : 3 ( 0.06%) - lvl-1 : 18 ( 0.36%) - lvl-2 : 62 ( 1.24%) - lvl-3 : 108 ( 2.16%) - lvl-4 : 191 ( 3.82%) - lvl-5 : 1 ( 0.02%) + lvl-1 : 18 ( 0.36%) non-ancestor-bases: 9 (50.00%) + lvl-2 : 62 ( 1.24%) non-ancestor-bases: 58 (93.55%) + lvl-3 : 108 ( 2.16%) non-ancestor-bases: 108 (100.00%) + lvl-4 : 191 ( 3.82%) non-ancestor-bases: 180 (94.24%) + lvl-5 : 1 ( 0.02%) non-ancestor-bases: 1 (100.00%) deltas : 4618 (92.34%) revision size : 58616973 snapshot : 9247844 (15.78%) @@ -144,9 +144,11 @@ deltas against prev : 3906 (84.58%) where prev = p1 : 3906 (100.00%) where prev = p2 : 0 ( 0.00%) - other : 0 ( 0.00%) + other-ancestor : 0 ( 0.00%) + unrelated : 0 ( 0.00%) deltas against p1 : 649 (14.05%) deltas against p2 : 63 ( 1.36%) + deltas against ancs : 0 ( 0.00%) deltas against other : 0 ( 0.00%)