Skip to content

Commit b6c6f68

Browse files
committed
Auto merge of #7390 - Eh2406:better-graph, r=alexcrichton
change the priority in witch we build crates On my windows 4 core, this made clean builds (of 3596cb8) go from 257-223s to 210-205s. So that looks like an improvement.
2 parents b385d51 + 384056e commit b6c6f68

File tree

1 file changed

+24
-21
lines changed

1 file changed

+24
-21
lines changed

src/cargo/util/dependency_queue.rs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

3838
impl<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

Comments
 (0)