Skip to content

Commit c1527c4

Browse files
Introduce cache for parsed workspaces
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 c1527c4

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)