Skip to content

Commit e58076d

Browse files
Introduce cache for parsed workspaces (#1296)
With complex workspace files, parsing takes significant amount of time on each commit. The cache saves that time and makes workspace rebuilds a lot faster. Change: parse-cache
1 parent fc7391a commit e58076d

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

josh-core/src/filter/mod.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ pub use parse::parse;
1212
lazy_static! {
1313
static ref FILTERS: std::sync::Mutex<std::collections::HashMap<Filter, Op>> =
1414
std::sync::Mutex::new(std::collections::HashMap::new());
15+
static ref WORKSPACES: std::sync::Mutex<std::collections::HashMap<git2::Oid, Filter>> =
16+
std::sync::Mutex::new(std::collections::HashMap::new());
1517
}
1618

1719
/// Filters are represented as `git2::Oid`, however they are not ever stored
@@ -397,13 +399,27 @@ fn resolve_workspace_redirect<'a>(
397399
}
398400

399401
fn get_workspace<'a>(repo: &'a git2::Repository, tree: &'a git2::Tree<'a>, path: &Path) -> Filter {
400-
let f = parse::parse(&tree::get_blob(repo, tree, &path.join("workspace.josh")))
401-
.unwrap_or_else(|_| to_filter(Op::Empty));
402+
let ws_path = normalize_path(&path.join("workspace.josh"));
403+
let ws_id = ok_or!(tree.get_path(&ws_path), {
404+
return to_filter(Op::Empty);
405+
})
406+
.id();
407+
let ws_blob = tree::get_blob(repo, tree, &ws_path);
402408

403-
if invert(f).is_ok() {
404-
f
409+
let mut workspaces = WORKSPACES.lock().unwrap();
410+
411+
if let Some(f) = workspaces.get(&ws_id) {
412+
*f
405413
} else {
406-
to_filter(Op::Empty)
414+
let f = parse::parse(&ws_blob).unwrap_or_else(|_| to_filter(Op::Empty));
415+
416+
let f = if invert(f).is_ok() {
417+
f
418+
} else {
419+
to_filter(Op::Empty)
420+
};
421+
workspaces.insert(ws_id, f);
422+
f
407423
}
408424
}
409425

0 commit comments

Comments
 (0)