@@ -31,8 +31,8 @@ pub struct DependencyQueue<N: Hash + Eq, E: Hash + Eq, V> {
31
31
/// easily indexable with just an `N`
32
32
reverse_dep_map : HashMap < N , HashMap < E , HashSet < N > > > ,
33
33
34
- /// Topological depth of each key
35
- depth : HashMap < N , usize > ,
34
+ /// The total number of packages that are transitively waiting on this package
35
+ priority : HashMap < N , usize > ,
36
36
}
37
37
38
38
impl < N : Hash + Eq , E : Hash + Eq , V > Default for DependencyQueue < N , E , V > {
@@ -47,12 +47,14 @@ impl<N: Hash + Eq, E: Hash + Eq, V> DependencyQueue<N, E, V> {
47
47
DependencyQueue {
48
48
dep_map : HashMap :: new ( ) ,
49
49
reverse_dep_map : HashMap :: new ( ) ,
50
- depth : HashMap :: new ( ) ,
50
+ priority : HashMap :: new ( ) ,
51
51
}
52
52
}
53
53
}
54
54
55
- impl < N : Hash + Eq + Clone , E : Eq + Hash + Clone , V > DependencyQueue < N , E , V > {
55
+ impl < N : Hash + Eq + Clone + std:: fmt:: Debug + PartialEq , E : Eq + Hash + Clone , V >
56
+ DependencyQueue < N , E , V >
57
+ {
56
58
/// Adds a new ndoe and its dependencies to this queue.
57
59
///
58
60
/// The `key` specified is a new node in the dependency graph, and the node
@@ -82,36 +84,39 @@ impl<N: Hash + Eq + Clone, E: Eq + Hash + Clone, V> DependencyQueue<N, E, V> {
82
84
/// All nodes have been added, calculate some internal metadata and prepare
83
85
/// for `dequeue`.
84
86
pub fn queue_finished ( & mut self ) {
87
+ let mut out = HashMap :: new ( ) ;
85
88
for key in self . dep_map . keys ( ) {
86
- depth ( key, & self . reverse_dep_map , & mut self . depth ) ;
89
+ depth ( key, & self . reverse_dep_map , & mut out ) ;
87
90
}
91
+ self . priority = out. into_iter ( ) . map ( |( n, set) | ( n, set. len ( ) ) ) . collect ( ) ;
88
92
89
- fn depth < N : Hash + Eq + Clone , E : Hash + Eq + Clone > (
93
+ fn depth < N : Hash + Eq + Clone + std :: fmt :: Debug + PartialEq , E : Hash + Eq + Clone > (
90
94
key : & N ,
91
95
map : & HashMap < N , HashMap < E , HashSet < N > > > ,
92
- results : & mut HashMap < N , usize > ,
93
- ) -> usize {
94
- const IN_PROGRESS : usize = !0 ;
95
-
96
- if let Some ( & depth) = results. get ( key) {
97
- assert_ne ! ( depth, IN_PROGRESS , "cycle in DependencyQueue" ) ;
98
- return depth;
96
+ results : & mut HashMap < N , HashSet < N > > ,
97
+ ) -> HashSet < N > {
98
+ let in_progress: HashSet < N > = HashSet :: new ( ) ;
99
+ if let Some ( depth) = results. get ( key) {
100
+ assert_ne ! ( depth, & in_progress, "cycle in DependencyQueue" ) ;
101
+ return depth. clone ( ) ;
99
102
}
103
+ results. insert ( key. clone ( ) , in_progress) ;
100
104
101
- results. insert ( key. clone ( ) , IN_PROGRESS ) ;
105
+ let mut set = HashSet :: new ( ) ;
106
+ set. insert ( key. clone ( ) ) ;
102
107
103
- let depth = 1 + map
108
+ for dep in map
104
109
. get ( key)
105
110
. into_iter ( )
106
111
. flat_map ( |it| it. values ( ) )
107
112
. flat_map ( |set| set)
108
- . map ( |dep| depth ( dep , map , results ) )
109
- . max ( )
110
- . unwrap_or ( 0 ) ;
113
+ {
114
+ set . extend ( depth ( dep , map , results ) . into_iter ( ) )
115
+ }
111
116
112
- * results. get_mut ( key) . unwrap ( ) = depth ;
117
+ * results. get_mut ( key) . unwrap ( ) = set . clone ( ) ;
113
118
114
- depth
119
+ set
115
120
}
116
121
}
117
122
@@ -122,7 +127,7 @@ impl<N: Hash + Eq + Clone, E: Eq + Hash + Clone, V> DependencyQueue<N, E, V> {
122
127
pub fn dequeue ( & mut self ) -> Option < ( N , V ) > {
123
128
// Look at all our crates and find everything that's ready to build (no
124
129
// deps). After we've got that candidate set select the one which has
125
- // the maximum depth in the dependency graph. This way we should
130
+ // the maximum priority in the dependency graph. This way we should
126
131
// hopefully keep CPUs hottest the longest by ensuring that long
127
132
// dependency chains are scheduled early on in the build process and the
128
133
// leafs higher in the tree can fill in the cracks later.
@@ -135,7 +140,7 @@ impl<N: Hash + Eq + Clone, E: Eq + Hash + Clone, V> DependencyQueue<N, E, V> {
135
140
. iter ( )
136
141
. filter ( |( _, ( deps, _) ) | deps. is_empty ( ) )
137
142
. map ( |( key, _) | key. clone ( ) )
138
- . max_by_key ( |k| self . depth [ k] ) ;
143
+ . max_by_key ( |k| self . priority [ k] ) ;
139
144
let key = match next {
140
145
Some ( key) => key,
141
146
None => return None ,
0 commit comments