Skip to content

Commit

Permalink
revset: ad-hoc optimization for range queries containing unwanted wan…
Browse files Browse the repository at this point in the history
…ted heads

In my linux stable mirror, this makes the default log revset evaluation super
fast. immutable_heads(), if configured properly, includes many historical
branch heads which are also the visible heads.

revsets/immutable_heads()..
---------------------------
0     12.27     117.1±0.77m
3      1.00       9.5±0.08m
  • Loading branch information
yuja committed Feb 22, 2024
1 parent c93d9ef commit 2ec0fc9
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
2 changes: 2 additions & 0 deletions cli/testing/bench-revsets-git.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ v2.39.0::v2.40.0
# Tags and branches
tags()
branches()
# Local changes
(tags() | remote_branches())..
# Intersection of range with a small subset
tags() & ::v2.40.0
v2.39.0 & ::v2.40.0
Expand Down
10 changes: 9 additions & 1 deletion lib/src/default_index/revset_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -764,8 +764,16 @@ impl<'index> EvaluationContext<'index> {
} => {
let root_set = self.evaluate(roots)?;
let root_positions = root_set.positions(index).collect_vec();
// Pre-filter heads so queries like 'immutable_heads()..' can
// terminate early. immutable_heads() usually includes some
// visible heads, which can be trivially rejected.
let head_set = self.evaluate(heads)?;
let head_positions = head_set.positions(index).collect_vec();
let head_positions = difference_by(
head_set.positions(index),
root_positions.iter().copied(),
|pos1, pos2| pos1.cmp(pos2).reverse(),
)
.collect_vec();
if generation == &GENERATION_RANGE_FULL {
Ok(Box::new(RevWalkRevset::new(move |index| {
Box::new(index.walk_revs(&head_positions, &root_positions))
Expand Down

0 comments on commit 2ec0fc9

Please sign in to comment.