Skip to content

Commit f9cf2dc

Browse files
christian-schillingLMG
authored andcommitted
Execute simpler filters before more complex ones
This deterministic execution order divides the filtering of complex filters into stages that can then be parallelised with a later patch. Change-Id: filter-execution-order
1 parent fab6946 commit f9cf2dc

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

src/cache.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ impl Transaction {
329329

330330
pub fn get_missing(&self) -> Vec<(filter::Filter, git2::Oid)> {
331331
let mut missing = self.t2.borrow().missing.clone();
332-
missing.sort();
332+
missing.sort_by_key(|(f, i)| (filter::nesting(*f), *f, *i));
333333
missing.dedup();
334334
missing.retain(|(f, i)| !self.known(*f, *i));
335335
self.t2.borrow_mut().missing = missing.clone();

src/filter/mod.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,21 @@ fn pretty2(op: &Op, indent: usize, compose: bool) -> String {
143143
}
144144
}
145145

146+
pub fn nesting(filter: Filter) -> usize {
147+
nesting2(&to_op(filter))
148+
}
149+
150+
fn nesting2(op: &Op) -> usize {
151+
match op {
152+
Op::Compose(filters) => 1 + filters.iter().map(|f| nesting(*f)).fold(0, |a, b| a.max(b)),
153+
Op::Exclude(filter) => 1 + nesting(*filter),
154+
Op::Workspace(_) => usize::MAX,
155+
Op::Chain(a, b) => 1 + nesting(*a).max(nesting(*b)),
156+
Op::Subtract(a, b) => 1 + nesting(*a).max(nesting(*b)),
157+
_ => 0,
158+
}
159+
}
160+
146161
/// Compact, single line string representation of a filter so that `parse(spec(F)) == F`
147162
/// Note that this is will not be the best human readable representation. For that see `pretty(...)`
148163
pub fn spec(filter: Filter) -> String {
@@ -236,7 +251,15 @@ pub fn apply_to_commit(
236251
return Ok(id);
237252
}
238253

239-
for (f, i) in transaction.get_missing() {
254+
let missing = transaction.get_missing();
255+
256+
// Since 'missing' is sorted by nesting, the first is always the minimal
257+
let minimal_nesting = missing.get(0).map(|(f, _)| nesting(*f)).unwrap_or(0);
258+
259+
for (f, i) in missing {
260+
if nesting(f) != minimal_nesting {
261+
break;
262+
}
240263
history::walk2(f, i, transaction)?;
241264
}
242265
}
@@ -319,6 +342,8 @@ fn apply_to_commit2(
319342
let filtered = filters
320343
.iter()
321344
.map(|f| apply_to_commit2(&to_op(*f), commit, transaction))
345+
.collect::<Vec<_>>()
346+
.into_iter()
322347
.collect::<JoshResult<Option<Vec<_>>>>()?;
323348

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

0 commit comments

Comments
 (0)