@@ -177,9 +177,6 @@ where
177
177
/// D' (i.e., D' < D), we know that N, N', and all nodes in
178
178
/// between them on the stack are part of an SCC.
179
179
///
180
- /// For each node, we track the lowest depth of any successor we
181
- /// have found, along with that
182
- ///
183
180
/// [wikipedia]: https://bit.ly/2EZIx84
184
181
fn construct ( graph : & ' c G ) -> Sccs < G :: Node , S > {
185
182
let num_nodes = graph. num_nodes ( ) ;
@@ -213,6 +210,17 @@ where
213
210
}
214
211
}
215
212
213
+ /// Visit a node during the DFS. We first examine its current
214
+ /// state -- if it is not yet visited (`NotVisited`), we can push
215
+ /// it onto the stack and start walking its successors.
216
+ ///
217
+ /// If it is already on the DFS stack it will be in the state
218
+ /// `BeingVisited`. In that case, we have found a cycle and we
219
+ /// return the depth from the stack.
220
+ ///
221
+ /// Otherwise, we are looking at a node that has already been
222
+ /// completely visited. We therefore return `WalkReturn::Complete`
223
+ /// with its associated SCC index.
216
224
fn walk_node ( & mut self , depth : usize , node : G :: Node ) -> WalkReturn < S > {
217
225
debug ! ( "walk_node(depth = {:?}, node = {:?})" , depth, node) ;
218
226
match self . find_state ( node) {
@@ -276,6 +284,7 @@ where
276
284
_ => false ,
277
285
} ) ;
278
286
287
+ // Push `node` onto the stack.
279
288
self . node_states [ node] = NodeState :: BeingVisited { depth } ;
280
289
self . node_stack . push ( node) ;
281
290
@@ -294,6 +303,7 @@ where
294
303
WalkReturn :: Cycle {
295
304
min_depth : successor_min_depth,
296
305
} => {
306
+ // Track the minimum depth we can reach.
297
307
assert ! ( successor_min_depth <= depth) ;
298
308
if successor_min_depth < min_depth {
299
309
debug ! (
@@ -308,6 +318,8 @@ where
308
318
WalkReturn :: Complete {
309
319
scc_index : successor_scc_index,
310
320
} => {
321
+ // Push the completed SCC indices onto
322
+ // the `successors_stack` for later.
311
323
debug ! (
312
324
"walk_unvisited_node: node = {:?} successor_scc_index = {:?}" ,
313
325
node, successor_scc_index
@@ -317,9 +329,12 @@ where
317
329
}
318
330
}
319
331
332
+ // Completed walk, remove `node` from the stack.
320
333
let r = self . node_stack . pop ( ) ;
321
334
debug_assert_eq ! ( r, Some ( node) ) ;
322
335
336
+ // If `min_depth == depth`, then we are the root of the
337
+ // cycle: we can't reach anyone further down the stack.
323
338
if min_depth == depth {
324
339
// Note that successor stack may have duplicates, so we
325
340
// want to remove those:
@@ -335,7 +350,7 @@ where
335
350
WalkReturn :: Complete { scc_index }
336
351
} else {
337
352
// We are not the head of the cycle. Return back to our
338
- // caller. They will take ownership of the
353
+ // caller. They will take ownership of the
339
354
// `self.successors` data that we pushed.
340
355
self . node_states [ node] = NodeState :: InCycleWith {
341
356
parent : min_cycle_root,
0 commit comments