Skip to content

Commit f203dea

Browse files
committed
optimize conflict_store for looking up only older matches
1 parent f4bd3a4 commit f203dea

File tree

3 files changed

+34
-8
lines changed

3 files changed

+34
-8
lines changed

crates/resolver-tests/tests/resolve.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,6 +1333,25 @@ fn large_conflict_cache() {
13331333
let _ = resolve(root_deps, &reg);
13341334
}
13351335

1336+
#[test]
1337+
fn off_by_one_bug() {
1338+
let input = vec![
1339+
pkg!(("A-sys", "0.0.1")),
1340+
pkg!(("A-sys", "0.0.4")),
1341+
pkg!(("A-sys", "0.0.6")),
1342+
pkg!(("A-sys", "0.0.7")),
1343+
pkg!(("NA", "0.0.0") => [dep_req("A-sys", "<= 0.0.5"),]),
1344+
pkg!(("NA", "0.0.1") => [dep_req("A-sys", ">= 0.0.6, <= 0.0.8"),]),
1345+
pkg!(("a", "0.0.1")),
1346+
pkg!(("a", "0.0.2")),
1347+
pkg!(("aa", "0.0.0") => [dep_req("A-sys", ">= 0.0.4, <= 0.0.6"),dep_req("NA", "<= 0.0.0"),]),
1348+
pkg!(("f", "0.0.3") => [dep("NA"),dep_req("a", "<= 0.0.2"),dep("aa"),]),
1349+
];
1350+
1351+
let reg = registry(input);
1352+
let _ = resolve_and_validated(vec![dep("f")], &reg, None);
1353+
}
1354+
13361355
#[test]
13371356
fn conflict_store_bug() {
13381357
let input = vec![

src/cargo/core/resolver/conflict_cache.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ impl ConflictStoreTrie {
2525
&self,
2626
is_active: &impl Fn(PackageId) -> Option<usize>,
2727
must_contain: Option<PackageId>,
28+
mut max_age: usize,
2829
) -> Option<(&ConflictMap, usize)> {
2930
match self {
3031
ConflictStoreTrie::Leaf(c) => {
@@ -43,8 +44,12 @@ impl ConflictStoreTrie {
4344
{
4445
// If the key is active, then we need to check all of the corresponding subtrie.
4546
if let Some(age_this) = is_active(pid) {
47+
if age_this >= max_age && must_contain != Some(pid) {
48+
// not worth looking at, it is to old.
49+
continue;
50+
}
4651
if let Some((o, age_o)) =
47-
store.find(is_active, must_contain.filter(|&f| f != pid))
52+
store.find(is_active, must_contain.filter(|&f| f != pid), max_age)
4853
{
4954
let age = if must_contain == Some(pid) {
5055
// all the results will include `must_contain`
@@ -53,10 +58,11 @@ impl ConflictStoreTrie {
5358
} else {
5459
std::cmp::max(age_this, age_o)
5560
};
56-
let out_age = out.get_or_insert((o, age)).1;
57-
if out_age > age {
61+
if max_age > age {
5862
// we found one that can jump-back further so replace the out.
5963
out = Some((o, age));
64+
// and dont look at anything older
65+
max_age = age
6066
}
6167
}
6268
}
@@ -152,10 +158,11 @@ impl ConflictCache {
152158
dep: &Dependency,
153159
is_active: &impl Fn(PackageId) -> Option<usize>,
154160
must_contain: Option<PackageId>,
161+
max_age: usize,
155162
) -> Option<&ConflictMap> {
156163
self.con_from_dep
157164
.get(dep)?
158-
.find(is_active, must_contain)
165+
.find(is_active, must_contain, max_age)
159166
.map(|(c, _)| c)
160167
}
161168
/// Finds any known set of conflicts, if any,
@@ -168,7 +175,7 @@ impl ConflictCache {
168175
dep: &Dependency,
169176
must_contain: Option<PackageId>,
170177
) -> Option<&ConflictMap> {
171-
let out = self.find(dep, &|id| cx.is_active(id), must_contain);
178+
let out = self.find(dep, &|id| cx.is_active(id), must_contain, std::usize::MAX);
172179
if cfg!(debug_assertions) {
173180
if let Some(c) = &out {
174181
assert!(cx.is_conflicting(None, c).is_some());

src/cargo/core/resolver/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -902,12 +902,12 @@ fn generalize_conflicting(
902902
// we are imagining that we used other instead
903903
Some(backtrack_critical_age)
904904
} else {
905-
cx.is_active(id).filter(|&age|
906-
// we only care about things that are older then critical_age
907-
age < backtrack_critical_age)
905+
cx.is_active(id)
908906
}
909907
},
910908
Some(other.package_id()),
909+
// we only care about things that are newer then critical_age
910+
backtrack_critical_age,
911911
)
912912
.map(|con| (other.package_id(), con))
913913
})

0 commit comments

Comments
 (0)