mirror of
https://github.com/martinvonz/jj.git
synced 2025-02-10 22:39:32 +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;
|
||||||
use crate::backend::{TreeId, TreeValue};
|
use crate::backend::{TreeId, TreeValue};
|
||||||
use crate::repo_path::{RepoPath, RepoPathJoin};
|
use crate::repo_path::RepoPath;
|
||||||
use crate::store::Store;
|
use crate::store::Store;
|
||||||
use crate::tree::Tree;
|
use crate::tree::Tree;
|
||||||
|
|
||||||
|
@ -115,30 +115,32 @@ impl TreeBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_base_trees(&self) -> BTreeMap<RepoPath, backend::Tree> {
|
fn get_base_trees(&self) -> BTreeMap<RepoPath, backend::Tree> {
|
||||||
let store = self.store.clone();
|
let store = &self.store;
|
||||||
let mut tree_cache = {
|
let mut tree_cache = {
|
||||||
let dir = RepoPath::root();
|
let dir = RepoPath::root();
|
||||||
let tree = store.get_tree(&dir, &self.base_tree_id).unwrap();
|
let tree = store.get_tree(&dir, &self.base_tree_id).unwrap();
|
||||||
BTreeMap::from([(dir, tree)])
|
BTreeMap::from([(dir, tree)])
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut populate_trees = |dir: &RepoPath| {
|
fn populate_trees<'a>(
|
||||||
let mut current_dir = RepoPath::root();
|
tree_cache: &'a mut BTreeMap<RepoPath, Tree>,
|
||||||
for component in dir.components() {
|
store: &Arc<Store>,
|
||||||
let next_dir = current_dir.join(component);
|
dir: RepoPath,
|
||||||
let current_tree = tree_cache.get(¤t_dir).unwrap();
|
) -> &'a Tree {
|
||||||
if !tree_cache.contains_key(&next_dir) {
|
// `if let Some(tree) = ...` doesn't pass lifetime check as of Rust 1.69.0
|
||||||
let tree = current_tree
|
if tree_cache.contains_key(&dir) {
|
||||||
.sub_tree(component)
|
return tree_cache.get(&dir).unwrap();
|
||||||
.unwrap_or_else(|| Tree::null(self.store.clone(), next_dir.clone()));
|
|
||||||
tree_cache.insert(next_dir.clone(), tree);
|
|
||||||
}
|
|
||||||
current_dir = next_dir;
|
|
||||||
}
|
}
|
||||||
};
|
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() {
|
for path in self.overrides.keys() {
|
||||||
let parent = path.parent().unwrap();
|
let parent = path.parent().unwrap();
|
||||||
populate_trees(&parent);
|
populate_trees(&mut tree_cache, store, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
tree_cache
|
tree_cache
|
||||||
|
|
Loading…
Reference in a new issue