This is an archive of the discontinued Mercurial Phabricator instance.

dirstate-tree: Fold "tracked descendants" counter update in main walk
ClosedPublic

Authored by SimonSapin on May 3 2021, 6:25 AM.

Details

Summary

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/

Diff Detail

Repository
rHG Mercurial
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.