MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / tarjan_visit

Function tarjan_visit

atomic-core/src/output/alive/order.rs:413–518  ·  view source on GitHub ↗

Iterative Tarjan visit function. Equivalent to the classic recursive Tarjan's SCC algorithm, but uses an explicit work stack instead of the call stack. This avoids stack overflow for files with tens of thousands of vertices.

(
    graph: &mut AliveGraph,
    start: VertexId,
    state: &mut TarjanState,
    result: &mut OrderResult,
)

Source from the content-addressed store, hash-verified

411/// an explicit work stack instead of the call stack. This avoids stack
412/// overflow for files with tens of thousands of vertices.
413fn tarjan_visit(
414 graph: &mut AliveGraph,
415 start: VertexId,
416 state: &mut TarjanState,
417 result: &mut OrderResult,
418) {
419 let mut work: Vec<TarjanFrame> = Vec::new();
420
421 // Initialize the start vertex
422 {
423 let vertex = graph.vertex_mut(start);
424 vertex.index = state.index;
425 vertex.lowlink = state.index;
426 vertex.mark_visited();
427 vertex.push_stack();
428 }
429 state.index += 1;
430 state.stack.push(start);
431
432 let children: Vec<VertexId> = graph
433 .children(start)
434 .map(|(_, child)| *child)
435 .filter(|c| !c.is_dummy())
436 .collect();
437 work.push(TarjanFrame {
438 v: start,
439 children,
440 child_idx: 0,
441 });
442
443 while let Some(frame) = work.last_mut() {
444 if frame.child_idx < frame.children.len() {
445 let w = frame.children[frame.child_idx];
446 frame.child_idx += 1;
447
448 let w_visited = graph.get_vertex(w).is_visited();
449 let w_on_stack = graph.get_vertex(w).is_on_stack();
450
451 if !w_visited {
452 // Initialize w and push a new frame (replaces recursive call)
453 {
454 let vertex = graph.vertex_mut(w);
455 vertex.index = state.index;
456 vertex.lowlink = state.index;
457 vertex.mark_visited();
458 vertex.push_stack();
459 }
460 state.index += 1;
461 state.stack.push(w);
462
463 let w_children: Vec<VertexId> = graph
464 .children(w)
465 .map(|(_, child)| *child)
466 .filter(|c| !c.is_dummy())
467 .collect();
468 work.push(TarjanFrame {
469 v: w,
470 children: w_children,

Callers 1

compute_orderFunction · 0.85

Calls 14

vertex_mutMethod · 0.80
mark_visitedMethod · 0.80
push_stackMethod · 0.80
childrenMethod · 0.80
is_dummyMethod · 0.80
is_visitedMethod · 0.80
get_vertexMethod · 0.80
is_on_stackMethod · 0.80
lastMethod · 0.80
pop_stackMethod · 0.80
pushMethod · 0.45
lenMethod · 0.45

Tested by

no test coverage detected