Skip to content

Commit

Permalink
Introduce cache for parsed workspaces (#1296)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
christian-schilling authored Nov 14, 2023
1 parent fc7391a commit e58076d
Showing 1 changed file with 21 additions and 5 deletions.
26 changes: 21 additions & 5 deletions josh-core/src/filter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub use parse::parse;
lazy_static! {
static ref FILTERS: std::sync::Mutex<std::collections::HashMap<Filter, Op>> =
std::sync::Mutex::new(std::collections::HashMap::new());
static ref WORKSPACES: std::sync::Mutex<std::collections::HashMap<git2::Oid, Filter>> =
std::sync::Mutex::new(std::collections::HashMap::new());
}

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

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

if invert(f).is_ok() {
f
let mut workspaces = WORKSPACES.lock().unwrap();

if let Some(f) = workspaces.get(&ws_id) {
*f
} else {
to_filter(Op::Empty)
let f = parse::parse(&ws_blob).unwrap_or_else(|_| to_filter(Op::Empty));

let f = if invert(f).is_ok() {
f
} else {
to_filter(Op::Empty)
};
workspaces.insert(ws_id, f);
f
}
}

Expand Down

0 comments on commit e58076d

Please sign in to comment.