mirror of
https://github.com/martinvonz/jj.git
synced 2025-02-10 14:26:58 +00:00
tree_builder: populate base trees by recursion
Suppose many override entries share the same parent directories, it should be cheaper to look up the tree_cache from leaf than root. I also think recursion is easier to follow than for loop.
This commit is contained in:
parent
941f41e62e
commit
6872051270
1 changed files with 18 additions and 16 deletions
|
@ -19,7 +19,7 @@ use itertools::Itertools as _;
|
|||
|
||||
use crate::backend;
|
||||
use crate::backend::{TreeId, TreeValue};
|
||||
use crate::repo_path::{RepoPath, RepoPathJoin};
|
||||
use crate::repo_path::RepoPath;
|
||||
use crate::store::Store;
|
||||
use crate::tree::Tree;
|
||||
|
||||
|
@ -115,30 +115,32 @@ impl TreeBuilder {
|
|||
}
|
||||
|
||||
fn get_base_trees(&self) -> BTreeMap<RepoPath, backend::Tree> {
|
||||
let store = self.store.clone();
|
||||
let store = &self.store;
|
||||
let mut tree_cache = {
|
||||
let dir = RepoPath::root();
|
||||
let tree = store.get_tree(&dir, &self.base_tree_id).unwrap();
|
||||
BTreeMap::from([(dir, tree)])
|
||||
};
|
||||
|
||||
let mut populate_trees = |dir: &RepoPath| {
|
||||
let mut current_dir = RepoPath::root();
|
||||
for component in dir.components() {
|
||||
let next_dir = current_dir.join(component);
|
||||
let current_tree = tree_cache.get(¤t_dir).unwrap();
|
||||
if !tree_cache.contains_key(&next_dir) {
|
||||
let tree = current_tree
|
||||
.sub_tree(component)
|
||||
.unwrap_or_else(|| Tree::null(self.store.clone(), next_dir.clone()));
|
||||
tree_cache.insert(next_dir.clone(), tree);
|
||||
}
|
||||
current_dir = next_dir;
|
||||
fn populate_trees<'a>(
|
||||
tree_cache: &'a mut BTreeMap<RepoPath, Tree>,
|
||||
store: &Arc<Store>,
|
||||
dir: RepoPath,
|
||||
) -> &'a Tree {
|
||||
// `if let Some(tree) = ...` doesn't pass lifetime check as of Rust 1.69.0
|
||||
if tree_cache.contains_key(&dir) {
|
||||
return tree_cache.get(&dir).unwrap();
|
||||
}
|
||||
};
|
||||
let (parent, basename) = dir.split().expect("root must be populated");
|
||||
let tree = populate_trees(tree_cache, store, parent)
|
||||
.sub_tree(basename)
|
||||
.unwrap_or_else(|| Tree::null(store.clone(), dir.clone()));
|
||||
tree_cache.entry(dir).or_insert(tree)
|
||||
}
|
||||
|
||||
for path in self.overrides.keys() {
|
||||
let parent = path.parent().unwrap();
|
||||
populate_trees(&parent);
|
||||
populate_trees(&mut tree_cache, store, parent);
|
||||
}
|
||||
|
||||
tree_cache
|
||||
|
|
Loading…
Reference in a new issue