Compute the output order using Tarjan's SCC algorithm. This function: 1. Runs Tarjan's algorithm to find all SCCs 2. Builds the conflict tree 3. Identifies forward edges # Arguments `graph` - The alive graph (will be modified to set SCC indices) # Returns An `OrderResult` containing SCCs and conflict information. # Example ```rust,ignore use atomic_core::output::alive::{AliveGraph, compute_
(graph: &mut AliveGraph)
| 352 | /// println!("Found {} SCCs", order.num_sccs()); |
| 353 | /// ``` |
| 354 | pub fn compute_order(graph: &mut AliveGraph) -> OrderResult { |
| 355 | let mut result = OrderResult::new(); |
| 356 | |
| 357 | if graph.is_empty() { |
| 358 | return result; |
| 359 | } |
| 360 | |
| 361 | let mut state = TarjanState::new(graph.len_vertices()); |
| 362 | |
| 363 | // Run Tarjan's algorithm starting from span 1 (root) |
| 364 | // Skip span 0 which is DUMMY |
| 365 | for i in 1..graph.len_vertices() { |
| 366 | let vid = VertexId::new(i); |
| 367 | if !graph.get_vertex(vid).is_visited() { |
| 368 | tarjan_visit(graph, vid, &mut state, &mut result); |
| 369 | } |
| 370 | } |
| 371 | |
| 372 | // Count cyclic conflicts |
| 373 | result.cyclic_conflicts = result.sccs.iter().filter(|scc| scc.len() > 1).count(); |
| 374 | |
| 375 | // Build a simple conflict tree (can be enhanced later for nested conflicts) |
| 376 | build_conflict_tree(graph, &mut result); |
| 377 | |
| 378 | result |
| 379 | } |
| 380 | |
| 381 | /// Internal state for Tarjan's algorithm. |
| 382 | struct TarjanState { |