From 308a5b9eaef5437e6eda12903dcb8c30ac01867f Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Wed, 5 Apr 2023 16:19:32 +0900 Subject: [PATCH] revset: make empty()/file(".") not load root tree for liner history TreeDiffIterator wouldn't load identical subtrees, but it's up to caller to optimize out the root tree loading. --- lib/src/default_revset_engine.rs | 12 +++++++++++- testing/bench-revsets-git.txt | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/src/default_revset_engine.rs b/lib/src/default_revset_engine.rs index 0c54086a1..d3b717780 100644 --- a/lib/src/default_revset_engine.rs +++ b/lib/src/default_revset_engine.rs @@ -24,7 +24,8 @@ use crate::backend::{ChangeId, CommitId, MillisSinceEpoch, ObjectId}; use crate::default_index_store::{CompositeIndex, IndexEntry, IndexEntryByPosition, IndexPosition}; use crate::default_revset_graph_iterator::RevsetGraphIterator; use crate::index::{HexPrefix, Index, PrefixResolution}; -use crate::matchers::{EverythingMatcher, Matcher, PrefixMatcher}; +use crate::matchers::{EverythingMatcher, Matcher, PrefixMatcher, Visit}; +use crate::repo_path::RepoPath; use crate::revset::{ ChangeIdIndex, Revset, RevsetEvaluationError, RevsetExpression, RevsetFilterPredicate, RevsetGraphEdge, GENERATION_RANGE_FULL, @@ -954,6 +955,15 @@ fn has_diff_from_parent( ) -> bool { let commit = store.get_commit(&entry.commit_id()).unwrap(); let parents = commit.parents(); + if let [parent] = parents.as_slice() { + // Fast path: no need to load the root tree + let unchanged = commit.tree_id() == parent.tree_id(); + if matcher.visit(&RepoPath::root()) == Visit::AllRecursively { + return !unchanged; + } else if unchanged { + return false; + } + } let from_tree = rewrite::merge_commit_trees_without_repo(store, index, &parents); let to_tree = commit.tree(); from_tree.diff(&to_tree, matcher).next().is_some() diff --git a/testing/bench-revsets-git.txt b/testing/bench-revsets-git.txt index 67881bdac..cd724154a 100644 --- a/testing/bench-revsets-git.txt +++ b/testing/bench-revsets-git.txt @@ -45,3 +45,4 @@ merges() ~merges() # Files are unbearably slow, so only filter within small set file(Makefile) & v1.0.0..v1.2.0 +empty() & v1.0.0..v1.2.0