Skip to content

Commit 4f4350d

Browse files
committed
[WIP] deduplicate the successors of each SCC
1 parent 1f749b3 commit 4f4350d

File tree

1 file changed

+19
-2
lines changed
  • src/librustc_data_structures/graph/scc

1 file changed

+19
-2
lines changed

src/librustc_data_structures/graph/scc/mod.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
//! node in the graph. This uses Tarjan's algorithm that completes in
1414
//! O(n) time.
1515
16+
use fx::FxHashSet;
1617
use graph::{DirectedGraph, WithNumNodes, WithSuccessors};
1718
use indexed_vec::{Idx, IndexVec};
1819
use std::ops::Range;
@@ -113,6 +114,13 @@ struct SccsConstruction<'c, G: DirectedGraph + WithNumNodes + WithSuccessors + '
113114
/// we push it on the stack. When we complete an SCC, we can pop
114115
/// everything off the stack that was found along the way.
115116
successors_stack: Vec<S>,
117+
118+
/// A set used to strip duplicates. As we accumulate successors
119+
/// into the successors_stack, we sometimes get duplicate entries.
120+
/// We use this set to remove those -- we keep it around between
121+
/// successors to amortize memory allocation costs.
122+
duplicate_set: FxHashSet<S>,
123+
116124
scc_data: SccData<S>,
117125
}
118126

@@ -180,6 +188,7 @@ where
180188
ranges: IndexVec::new(),
181189
all_successors: Vec::new(),
182190
},
191+
duplicate_set: FxHashSet::default(),
183192
};
184193

185194
let scc_indices = (0..num_nodes)
@@ -307,8 +316,16 @@ where
307316
debug_assert_eq!(r, Some(node));
308317

309318
if min_depth == depth {
310-
let scc_index = self.scc_data
311-
.create_scc(self.successors_stack.drain(successors_len..));
319+
// Note that successor stack may have duplicates, so we
320+
// want to remove those:
321+
let deduplicated_successors = {
322+
let duplicate_set = &mut self.duplicate_set;
323+
duplicate_set.clear();
324+
self.successors_stack
325+
.drain(successors_len..)
326+
.filter(move |&i| duplicate_set.insert(i))
327+
};
328+
let scc_index = self.scc_data.create_scc(deduplicated_successors);
312329
self.node_states[node] = NodeState::InCycle { scc_index };
313330
WalkReturn::Complete { scc_index }
314331
} else {

0 commit comments

Comments
 (0)