tags-fnode-cache: do not repeatedly open the filelog in a loop
While getting multiple hgtagsfnodecache entries, we were opening (and closing)
the `.hgtags` filelog for each iteration. The meant repeatedly reading and
parsing the version same information from disk. A quite costly operation.
We no longer do this, leading to a sizable improvement in `hg debugupdatecache`
run for an already warm repositories.
### data-env-vars.name = mercurial-2018-08-01-zstd-sparse-revlog
# benchmark.name = debug-update-cache
# benchmark.variants.pre-state = warm
before: 1.711778 seconds
after: 0.213229 seconds (-87.54%)
# data-env-vars.name = pypy-2018-08-01-zstd-sparse-revlog
before: 4.010817 seconds
after: 0.381141 seconds (-90.50%)
# data-env-vars.name = netbeans-2018-08-01-zstd-sparse-revlog
before: 13.574141
after: 1.023007 seconds (-92.46%)
# data-env-vars.name = mozilla-central-2018-08-01-zstd-sparse-revlog
before: 18.884656
after: 1.465735 seconds (-92.24%)
# data-env-vars.name = mozilla-try-2019-02-18-zstd-sparse-revlog
before: 88.924823
after: 6.511771 seconds (-92.68%)
--- a/mercurial/tags.py Sat Nov 12 02:30:41 2022 +0100
+++ b/mercurial/tags.py Sat Nov 12 02:38:26 2022 +0100
@@ -491,11 +491,14 @@
cachefnode = {}
validated_fnodes = set()
unknown_entries = set()
+
+ flog = None
for node in nodes:
fnode = fnodescache.getfnode(node)
- flog = repo.file(b'.hgtags')
if fnode != repo.nullid:
if fnode not in validated_fnodes:
+ if flog is None:
+ flog = repo.file(b'.hgtags')
if flog.hasnode(fnode):
validated_fnodes.add(fnode)
else: