view tests/hghave @ 47120:7109a38830c9

dirstate-tree: Fold "tracked descendants" counter update in main walk For the purpose of implementing `has_tracked_dir` (which means "has tracked descendants) without an expensive sub-tree traversal, we maintaing a counter of tracked descendants on each "directory" node of the tree-shaped dirstate. Before this changeset, mutating or inserting a node at a given path would involve: * Walking the tree from root through ancestors to find the node or the spot where to insert it * Looking at the previous node if any to decide what counter update is needed * Performing any node mutation * Walking the tree *again* to update counters in ancestor nodes When profiling `hg status` on a large repo, this second walk takes times while loading a the dirstate from disk. It turns out we have enough information to decide before he first tree walk what counter update is needed. This changeset merges the two walks, gaining ~10% of the total time for `hg update` (in the same hyperfine benchmark as the previous changeset). --- Profiling was done by compiling with this `.cargo/config`: [profile.release] debug = true then running with: py-spy record -r 500 -n -o /tmp/hg.json --format speedscope -- \ ./hg status -R $REPO --config experimental.dirstate-tree.in-memory=1 then visualizing the recorded JSON file in https://www.speedscope.app/ Differential Revision: https://phab.mercurial-scm.org/D10554
author Simon Sapin <simon.sapin@octobus.net>
date Fri, 30 Apr 2021 14:22:14 +0200
parents c102b704edb5
children 23f5ed6dbcb1
line wrap: on
line source

#!/usr/bin/env python3
"""Test the running system for features availability. Exit with zero
if all features are there, non-zero otherwise. If a feature name is
prefixed with "no-", the absence of feature is tested.
"""

from __future__ import absolute_import, print_function

import hghave
import optparse
import os
import sys

checks = hghave.checks


def list_features():
    for name, feature in sorted(checks.items()):
        desc = feature[1]
        print(name + ':', desc)


def test_features():
    failed = 0
    for name, feature in checks.items():
        check, _ = feature
        try:
            check()
        except Exception as e:
            print("feature %s failed:  %s" % (name, e))
            failed += 1
    return failed


parser = optparse.OptionParser("%prog [options] [features]")
parser.add_option(
    "--test-features", action="store_true", help="test available features"
)
parser.add_option(
    "--list-features", action="store_true", help="list available features"
)


def _loadaddon():
    if 'TESTDIR' in os.environ:
        # loading from '.' isn't needed, because `hghave` should be
        # running at TESTTMP in this case
        path = os.environ['TESTDIR']
    else:
        path = '.'

    if not os.path.exists(os.path.join(path, 'hghaveaddon.py')):
        return

    sys.path.insert(0, path)
    try:
        import hghaveaddon

        assert hghaveaddon  # silence pyflakes
    except BaseException as inst:
        sys.stderr.write(
            'failed to import hghaveaddon.py from %r: %s\n' % (path, inst)
        )
        sys.exit(2)
    sys.path.pop(0)


if __name__ == '__main__':
    options, args = parser.parse_args()
    _loadaddon()
    if options.list_features:
        list_features()
        sys.exit(0)

    if options.test_features:
        sys.exit(test_features())

    hghave.require(args)