delta: ignore base whose chains already don't match expectations
If we know the existing chain does not match our criteria, there is no point
to build a delta to append. This is especially useful when dealing with a full
text much smaller than its parent. In that case, the parent chain is probably
already too large.
example affected manifest write
before: 1.421005s
after: 0.815520s (-42%)
--- a/mercurial/revlogutils/deltas.py Mon Dec 17 10:42:19 2018 +0100
+++ b/mercurial/revlogutils/deltas.py Mon Dec 17 10:46:37 2018 +0100
@@ -655,6 +655,17 @@
# no delta for rawtext-changing revs (see "candelta" for why)
if revlog.flags(rev) & REVIDX_RAWTEXT_CHANGING_FLAGS:
continue
+ # If we reach here, we are about to build and test a delta.
+ # The delta building process will compute the chaininfo in all
+ # case, since that computation is cached, it is fine to access it
+ # here too.
+ chainlen, chainsize = revlog._chaininfo(rev)
+ # if chain will be too long, skip base
+ if revlog._maxchainlen and chainlen >= revlog._maxchainlen:
+ continue
+ # if chain already have too much data, skip base
+ if deltas_limit < chainsize:
+ continue
group.append(rev)
if group:
# XXX: in the sparse revlog case, group can become large,