@@ -4,15 +4,20 @@ use super::types::ConflictReason;
4
4
use core:: resolver:: Context ;
5
5
use core:: { Dependency , PackageId } ;
6
6
7
+ /// This is a data structure for storing a large number of Sets designed to
8
+ /// efficiently see if any of the stored Sets are a subset of a search Set.
7
9
enum ConflictStore {
8
- Con ( BTreeMap < PackageId , ConflictReason > ) ,
9
- Map ( HashMap < PackageId , ConflictStore > ) ,
10
+ /// a Leaf is one of the stored Sets.
11
+ Leaf ( BTreeMap < PackageId , ConflictReason > ) ,
12
+ /// a Node is a map from an element to a subset of the stored data
13
+ /// where all the Sets in the subset contains that element.
14
+ Node ( HashMap < PackageId , ConflictStore > ) ,
10
15
}
11
16
12
17
impl ConflictStore {
13
18
/// Finds any known set of conflicts, if any,
14
19
/// which are activated in `cx` and pass the `filter` specified?
15
- pub fn find_conflicting < F > (
20
+ fn find_conflicting < F > (
16
21
& self ,
17
22
cx : & Context ,
18
23
filter : & F ,
@@ -21,17 +26,23 @@ impl ConflictStore {
21
26
for < ' r > F : Fn ( & ' r & BTreeMap < PackageId , ConflictReason > ) -> bool ,
22
27
{
23
28
match self {
24
- ConflictStore :: Con ( c) => {
29
+ ConflictStore :: Leaf ( c) => {
25
30
if filter ( & c) {
26
31
Some ( c)
27
32
} else {
28
33
None
29
34
}
30
35
}
31
- ConflictStore :: Map ( m) => {
36
+ ConflictStore :: Node ( m) => {
32
37
for ( pid, store) in m {
38
+ // if the key is active then we need to check all of the corresponding subset,
39
+ // but if it is not active then there is no way any of the corresponding subset
40
+ // will be conflicting.
33
41
if cx. is_active ( pid) {
34
42
if let Some ( o) = store. find_conflicting ( cx, filter) {
43
+ debug_assert ! ( cx. is_conflicting( None , o) ) ;
44
+ // is_conflicting checks that all the elements are active,
45
+ // but we have checked each one by the recursion of this function.
35
46
return Some ( o) ;
36
47
}
37
48
}
@@ -41,20 +52,30 @@ impl ConflictStore {
41
52
}
42
53
}
43
54
44
- pub fn insert < ' a > (
55
+ fn insert < ' a > (
45
56
& mut self ,
46
57
mut iter : impl Iterator < Item = & ' a PackageId > ,
47
58
con : BTreeMap < PackageId , ConflictReason > ,
48
59
) {
49
60
if let Some ( pid) = iter. next ( ) {
50
- if let ConflictStore :: Map ( p) = self {
61
+ if let ConflictStore :: Node ( p) = self {
51
62
p. entry ( pid. clone ( ) )
52
- . or_insert_with ( || ConflictStore :: Map ( HashMap :: new ( ) ) )
63
+ . or_insert_with ( || ConflictStore :: Node ( HashMap :: new ( ) ) )
53
64
. insert ( iter, con) ;
54
- }
55
- // else, We already have a subset of this in the ConflictStore
65
+ } // else, We already have a subset of this in the ConflictStore
56
66
} else {
57
- * self = ConflictStore :: Con ( con)
67
+ // we are at the end of the set we are adding, there are 3 cases for what to do next:
68
+ // 1. self is a empty dummy Node inserted by `or_insert_with`
69
+ // in witch case we should replace it with `Leaf(con)`.
70
+ // 2. self is a Node because we previously inserted a superset of
71
+ // the thing we are working on (I don't know if this happens in practice)
72
+ // but the subset that we are working on will
73
+ // always match any time the larger set would have
74
+ // in witch case we can replace it with `Leaf(con)`.
75
+ // 3. self is a Leaf that is in the same spot in the structure as
76
+ // the thing we are working on. So it is equivalent.
77
+ // We can replace it with `Leaf(con)`.
78
+ * self = ConflictStore :: Leaf ( con)
58
79
}
59
80
}
60
81
}
@@ -85,7 +106,7 @@ pub(super) struct ConflictCache {
85
106
// This is used to make sure we don't queue work we know will fail. See the
86
107
// discussion in https://github.com/rust-lang/cargo/pull/5168 for why this
87
108
// is so important. The nested HashMaps act as a kind of btree, that lets us
88
- // look up a witch entry's are still active without
109
+ // look up which entries are still active without
89
110
// linearly scanning through the full list.
90
111
//
91
112
// Also, as a final note, this map is *not* ever removed from. This remains
@@ -132,7 +153,7 @@ impl ConflictCache {
132
153
pub fn insert ( & mut self , dep : & Dependency , con : & BTreeMap < PackageId , ConflictReason > ) {
133
154
self . con_from_dep
134
155
. entry ( dep. clone ( ) )
135
- . or_insert_with ( || ConflictStore :: Map ( HashMap :: new ( ) ) )
156
+ . or_insert_with ( || ConflictStore :: Node ( HashMap :: new ( ) ) )
136
157
. insert ( con. keys ( ) , con. clone ( ) ) ;
137
158
138
159
trace ! (
0 commit comments