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

Function tarjan_visit

atomic-core/src/output/alive/order.rs:523–628  ·  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

521/// an explicit work stack instead of the call stack. This avoids stack
522/// overflow for files with tens of thousands of vertices.
523fn tarjan_visit(
524 graph: &mut AliveGraph,
525 start: VertexId,
526 state: &mut TarjanState,
527 result: &mut OrderResult,
528) {
529 let mut work: Vec<TarjanFrame> = Vec::new();
530
531 // Initialize the start vertex
532 {
533 let vertex = graph.vertex_mut(start);
534 vertex.index = state.index;
535 vertex.lowlink = state.index;
536 vertex.mark_visited();
537 vertex.push_stack();
538 }
539 state.index += 1;
540 state.stack.push(start);
541
542 let children: Vec<VertexId> = graph
543 .children(start)
544 .map(|(_, child)| *child)
545 .filter(|c| !c.is_dummy())
546 .collect();
547 work.push(TarjanFrame {
548 v: start,
549 children,
550 child_idx: 0,
551 });
552
553 while let Some(frame) = work.last_mut() {
554 if frame.child_idx < frame.children.len() {
555 let w = frame.children[frame.child_idx];
556 frame.child_idx += 1;
557
558 let w_visited = graph.get_vertex(w).is_visited();
559 let w_on_stack = graph.get_vertex(w).is_on_stack();
560
561 if !w_visited {
562 // Initialize w and push a new frame (replaces recursive call)
563 {
564 let vertex = graph.vertex_mut(w);
565 vertex.index = state.index;
566 vertex.lowlink = state.index;
567 vertex.mark_visited();
568 vertex.push_stack();
569 }
570 state.index += 1;
571 state.stack.push(w);
572
573 let w_children: Vec<VertexId> = graph
574 .children(w)
575 .map(|(_, child)| *child)
576 .filter(|c| !c.is_dummy())
577 .collect();
578 work.push(TarjanFrame {
579 v: w,
580 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