From eb348be32cca3a3db81c10bcf4b546d72aaafa11 Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Sun, 2 May 2021 14:58:44 -0700 Subject: [PATCH] revsets: make description() lazy by using new FilterRevset --- lib/src/revset.rs | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/lib/src/revset.rs b/lib/src/revset.rs index 6612e3169..448db9418 100644 --- a/lib/src/revset.rs +++ b/lib/src/revset.rs @@ -612,7 +612,7 @@ impl<'repo> Iterator for ChildrenRevsetIterator<'_, 'repo> { struct FilterRevset<'revset, 'repo: 'revset> { candidates: Box + 'revset>, - predicate: Box) -> bool>, + predicate: Box) -> bool + 'repo>, } impl<'repo> Revset<'repo> for FilterRevset<'_, 'repo> { @@ -897,27 +897,20 @@ pub fn evaluate_expression<'revset, 'repo: 'revset>( index_entries.dedup(); Ok(Box::new(EagerRevset { index_entries })) } - RevsetExpression::Description { - needle, - candidates: base_expression, - } => { - // TODO: Definitely make this lazy. We should have a common way of defining - // revsets that simply filter a base revset. - let base_set = evaluate_expression(repo, base_expression.as_ref())?; - let mut commit_ids = vec![]; - for entry in base_set.iter() { - let commit = repo.store().get_commit(&entry.commit_id()).unwrap(); - if commit.description().contains(needle.as_str()) { - commit_ids.push(entry.commit_id()); - } - } - let index = repo.index(); - let mut index_entries: Vec<_> = commit_ids - .iter() - .map(|id| index.entry_by_id(id).unwrap()) - .collect(); - index_entries.sort_by_key(|b| Reverse(b.position())); - Ok(Box::new(EagerRevset { index_entries })) + RevsetExpression::Description { needle, candidates } => { + let candidates = evaluate_expression(repo, candidates.as_ref())?; + let repo = repo; + let needle = needle.clone(); + Ok(Box::new(FilterRevset { + candidates, + predicate: Box::new(move |entry| { + repo.store() + .get_commit(&entry.commit_id()) + .unwrap() + .description() + .contains(needle.as_str()) + }), + })) } RevsetExpression::Union(expression1, expression2) => { let set1 = evaluate_expression(repo, expression1.as_ref())?;