revset: evaluate ancestors without using RevsetExpression builder API

I'm thinking of transforming RevsetExpression to a enum dedicated for
the evaluation stage. To help the migration, I want to remove the use of
the RevsetExpression builder API from the evaluation engine.

Fewer virtual dispatch is also better.
This commit is contained in:
Yuya Nishihara 2023-04-06 23:35:04 +09:00
parent ed0b23d009
commit 7dc35b82b0

View file

@ -21,7 +21,9 @@ use std::sync::Arc;
use itertools::Itertools; use itertools::Itertools;
use crate::backend::{ChangeId, CommitId, MillisSinceEpoch, ObjectId}; use crate::backend::{ChangeId, CommitId, MillisSinceEpoch, ObjectId};
use crate::default_index_store::{CompositeIndex, IndexEntry, IndexEntryByPosition, IndexPosition}; use crate::default_index_store::{
CompositeIndex, IndexEntry, IndexEntryByPosition, IndexPosition, RevWalk,
};
use crate::default_revset_graph_iterator::RevsetGraphIterator; use crate::default_revset_graph_iterator::RevsetGraphIterator;
use crate::index::{HexPrefix, Index, PrefixResolution}; use crate::index::{HexPrefix, Index, PrefixResolution};
use crate::matchers::{EverythingMatcher, Matcher, PrefixMatcher, Visit}; use crate::matchers::{EverythingMatcher, Matcher, PrefixMatcher, Visit};
@ -643,12 +645,14 @@ impl<'index, 'heads> EvaluationContext<'index, 'heads> {
})) }))
} }
RevsetExpression::Ancestors { heads, generation } => { RevsetExpression::Ancestors { heads, generation } => {
let range_expression = RevsetExpression::Range { let head_set = self.evaluate(heads)?;
roots: RevsetExpression::none(), let walk = self.walk_ancestors(&*head_set);
heads: heads.clone(), if generation == &GENERATION_RANGE_FULL {
generation: generation.clone(), Ok(Box::new(RevWalkRevset { walk }))
}; } else {
self.evaluate(&range_expression) let walk = walk.filter_by_generation(generation.clone());
Ok(Box::new(RevWalkRevset { walk }))
}
} }
RevsetExpression::Range { RevsetExpression::Range {
roots, roots,
@ -669,11 +673,11 @@ impl<'index, 'heads> EvaluationContext<'index, 'heads> {
} }
RevsetExpression::DagRange { roots, heads } => { RevsetExpression::DagRange { roots, heads } => {
let root_set = self.evaluate(roots)?; let root_set = self.evaluate(roots)?;
let candidate_set = self.evaluate(&heads.ancestors())?; let head_set = self.evaluate(heads)?;
let mut reachable: HashSet<_> = let mut reachable: HashSet<_> =
root_set.iter().map(|entry| entry.position()).collect(); root_set.iter().map(|entry| entry.position()).collect();
let mut result = vec![]; let mut result = vec![];
let candidates = candidate_set.iter().collect_vec(); let candidates = self.walk_ancestors(&*head_set).collect_vec();
for candidate in candidates.into_iter().rev() { for candidate in candidates.into_iter().rev() {
if reachable.contains(&candidate.position()) if reachable.contains(&candidate.position())
|| candidate || candidate
@ -816,6 +820,14 @@ impl<'index, 'heads> EvaluationContext<'index, 'heads> {
} }
} }
fn walk_ancestors<'a, S>(&self, head_set: &S) -> RevWalk<'index>
where
S: InternalRevset<'a> + ?Sized,
{
let head_ids = head_set.iter().map(|entry| entry.commit_id()).collect_vec();
self.composite_index.walk_revs(&head_ids, &[])
}
fn revset_for_commit_ids( fn revset_for_commit_ids(
&self, &self,
commit_ids: &[CommitId], commit_ids: &[CommitId],