@@ -31,8 +31,8 @@ pub struct DependencyQueue<N: Hash + Eq, E: Hash + Eq, V> {
3131 /// easily indexable with just an `N`
3232 reverse_dep_map : HashMap < N , HashMap < E , HashSet < N > > > ,
3333
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 > ,
3636}
3737
3838impl < N : Hash + Eq , E : Hash + Eq , V > Default for DependencyQueue < N , E , V > {
@@ -47,7 +47,7 @@ impl<N: Hash + Eq, E: Hash + Eq, V> DependencyQueue<N, E, V> {
4747 DependencyQueue {
4848 dep_map : HashMap :: new ( ) ,
4949 reverse_dep_map : HashMap :: new ( ) ,
50- depth : HashMap :: new ( ) ,
50+ priority : HashMap :: new ( ) ,
5151 }
5252 }
5353}
@@ -82,36 +82,39 @@ impl<N: Hash + Eq + Clone, E: Eq + Hash + Clone, V> DependencyQueue<N, E, V> {
8282 /// All nodes have been added, calculate some internal metadata and prepare
8383 /// for `dequeue`.
8484 pub fn queue_finished ( & mut self ) {
85+ let mut out = HashMap :: new ( ) ;
8586 for key in self . dep_map . keys ( ) {
86- depth ( key, & self . reverse_dep_map , & mut self . depth ) ;
87+ depth ( key, & self . reverse_dep_map , & mut out ) ;
8788 }
89+ self . priority = out. into_iter ( ) . map ( |( n, set) | ( n, set. len ( ) ) ) . collect ( ) ;
8890
89- fn depth < N : Hash + Eq + Clone , E : Hash + Eq + Clone > (
91+ fn depth < ' a , N : Hash + Eq + Clone , E : Hash + Eq + Clone > (
9092 key : & N ,
9193 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" ) ;
94+ results : & ' a mut HashMap < N , HashSet < N > > ,
95+ ) -> & ' a HashSet < N > {
96+ if results. contains_key ( key) {
97+ let depth = & results[ key] ;
98+ assert ! ( !depth. is_empty( ) , "cycle in DependencyQueue" ) ;
9899 return depth;
99100 }
101+ results. insert ( key. clone ( ) , HashSet :: new ( ) ) ;
100102
101- results. insert ( key. clone ( ) , IN_PROGRESS ) ;
103+ let mut set = HashSet :: new ( ) ;
104+ set. insert ( key. clone ( ) ) ;
102105
103- let depth = 1 + map
106+ for dep in map
104107 . get ( key)
105108 . into_iter ( )
106109 . flat_map ( |it| it. values ( ) )
107110 . flat_map ( |set| set)
108- . map ( |dep| depth ( dep, map, results) )
109- . max ( )
110- . unwrap_or ( 0 ) ;
111-
112- * results. get_mut ( key) . unwrap ( ) = depth;
111+ {
112+ set. extend ( depth ( dep, map, results) . iter ( ) . cloned ( ) )
113+ }
113114
114- depth
115+ let slot = results. get_mut ( key) . unwrap ( ) ;
116+ * slot = set;
117+ return & * slot;
115118 }
116119 }
117120
@@ -122,7 +125,7 @@ impl<N: Hash + Eq + Clone, E: Eq + Hash + Clone, V> DependencyQueue<N, E, V> {
122125 pub fn dequeue ( & mut self ) -> Option < ( N , V ) > {
123126 // Look at all our crates and find everything that's ready to build (no
124127 // 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
128+ // the maximum priority in the dependency graph. This way we should
126129 // hopefully keep CPUs hottest the longest by ensuring that long
127130 // dependency chains are scheduled early on in the build process and the
128131 // leafs higher in the tree can fill in the cracks later.
@@ -135,7 +138,7 @@ impl<N: Hash + Eq + Clone, E: Eq + Hash + Clone, V> DependencyQueue<N, E, V> {
135138 . iter ( )
136139 . filter ( |( _, ( deps, _) ) | deps. is_empty ( ) )
137140 . map ( |( key, _) | key. clone ( ) )
138- . max_by_key ( |k| self . depth [ k] ) ;
141+ . max_by_key ( |k| self . priority [ k] ) ;
139142 let key = match next {
140143 Some ( key) => key,
141144 None => return None ,
0 commit comments