Skip to content

Commit 6594236

Browse files
christian-schillingLMG
authored andcommitted
Use faster compose implementation for symmetric filters
Such filters can never have any non unique mappings and as such don't need the complexity of the more general algorithm that ensures uniqueness. The simpler implementation compose_fast() results in large speedups (2x and more) when trying different compose filters on the Josh repo. Change-Id: compose-fast
1 parent 9556fb8 commit 6594236

File tree

3 files changed

+39
-8
lines changed

3 files changed

+39
-8
lines changed

src/filter/mod.rs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -322,15 +322,30 @@ fn apply_to_commit2(
322322

323323
let filtered = some_or!(filtered, { return Ok(None) });
324324

325-
let filtered = filters
326-
.iter()
327-
.zip(filtered.into_iter())
328-
.filter(|(_, id)| *id != git2::Oid::zero())
329-
.into_iter()
330-
.map(|(f, id)| Ok((f, repo.find_commit(id)?.tree()?)))
331-
.collect::<JoshResult<Vec<_>>>()?;
325+
let inverted = filter::invert(filter)?;
326+
327+
if filter == inverted {
328+
// If the filter is symetric it does not change any paths and uniqueness of
329+
// mappings is already guaranteed.
330+
let filtered = filtered
331+
.into_iter()
332+
.filter(|id| *id != git2::Oid::zero())
333+
.into_iter()
334+
.map(|id| Ok(repo.find_commit(id)?.tree_id()))
335+
.collect::<JoshResult<Vec<_>>>()?;
336+
337+
tree::compose_fast(transaction, filtered)?
338+
} else {
339+
let filtered = filters
340+
.iter()
341+
.zip(filtered.into_iter())
342+
.filter(|(_, id)| *id != git2::Oid::zero())
343+
.into_iter()
344+
.map(|(f, id)| Ok((f, repo.find_commit(id)?.tree()?)))
345+
.collect::<JoshResult<Vec<_>>>()?;
332346

333-
tree::compose(transaction, filtered)?
347+
tree::compose(transaction, filtered)?
348+
}
334349
}
335350
Op::Workspace(ws_path) => {
336351
let normal_parents = commit

src/filter/opt.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,8 @@ pub fn invert(filter: Filter) -> JoshResult<Filter> {
445445
_ => return Err(josh_error("no invert")),
446446
});
447447

448+
let result = optimize(result);
449+
448450
INVERTED.lock().unwrap().insert(original, result);
449451
Ok(result)
450452
}

src/filter/tree.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,20 @@ fn populate(
796796
Ok(result_tree)
797797
}
798798

799+
pub fn compose_fast<'a>(
800+
transaction: &'a cache::Transaction,
801+
trees: Vec<git2::Oid>,
802+
) -> super::JoshResult<git2::Tree<'a>> {
803+
rs_tracing::trace_scoped!("compose_fast");
804+
let repo = transaction.repo();
805+
let mut result = tree::empty_id();
806+
for tree in trees {
807+
result = overlay(repo, tree, result)?;
808+
}
809+
810+
Ok(repo.find_tree(result)?)
811+
}
812+
799813
pub fn compose<'a>(
800814
transaction: &'a cache::Transaction,
801815
trees: Vec<(&super::filter::Filter, git2::Tree<'a>)>,

0 commit comments

Comments
 (0)