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.
--- 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)
+ )
--- 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%)