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

Function detect_fork_conflicts

atomic-core/src/output/repo/fork.rs:50–170  ·  view source on GitHub ↗

Detect fork conflicts in the alive graph. A fork is a vertex with ≥2 children that reside in different SCCs (i.e. there is no ordering between them). Only non-empty, non-root content children are considered — structural markers (empty inode vertices) are filtered out. # Arguments `graph` - The alive graph to scan for forks `order` - The computed SCC ordering from Tarjan's algorithm # Returns

(graph: &AliveGraph, order: &OrderResult)

Source from the content-addressed store, hash-verified

48///
49/// A (possibly empty) list of fork conflicts.
50pub(crate) fn detect_fork_conflicts(graph: &AliveGraph, order: &OrderResult) -> Vec<ForkConflict> {
51 use std::collections::{HashMap, HashSet, VecDeque};
52
53 let mut forks = Vec::new();
54
55 // Build vertex → SCC-index map so we can identify multi-vertex SCCs.
56 let mut vertex_to_scc: HashMap<VertexId, usize> = HashMap::new();
57 for (scc_idx, scc) in order.sccs.iter().enumerate() {
58 for &vid in scc {
59 vertex_to_scc.insert(vid, scc_idx);
60 }
61 }
62
63 // Reachability helper: does `from` reach `to` by following the alive
64 // graph's child edges (i.e. is `to` topologically downstream of
65 // `from`)? Used to filter out children that are linearly ordered
66 // through the additive edge model — they form a chain, not a fork.
67 let reachable = |from: VertexId, to: VertexId| -> bool {
68 if from == to {
69 return false;
70 }
71 let mut seen: HashSet<VertexId> = HashSet::new();
72 let mut queue: VecDeque<VertexId> = VecDeque::new();
73 queue.push_back(from);
74 seen.insert(from);
75 while let Some(v) = queue.pop_front() {
76 for (_, child) in graph.children(v) {
77 if child.is_dummy() || !seen.insert(*child) {
78 continue;
79 }
80 if *child == to {
81 return true;
82 }
83 queue.push_back(*child);
84 }
85 }
86 false
87 };
88
89 let vertex_count = graph.len_vertices();
90 for vid_raw in 0..vertex_count {
91 let vid = VertexId::new(vid_raw);
92 if vid.is_dummy() {
93 continue;
94 }
95
96 if graph.child_count(vid) <= 1 {
97 continue;
98 }
99
100 // Collect non-dummy, deduped children
101 let mut children: Vec<VertexId> = Vec::new();
102 for (_, child_vid) in graph.children(vid) {
103 if child_vid.is_dummy() {
104 continue;
105 }
106 if !children.contains(child_vid) {
107 children.push(*child_vid);

Callers 3

three_way_forkFunction · 0.85

Calls 15

childrenMethod · 0.80
is_dummyMethod · 0.80
len_verticesMethod · 0.80
child_countMethod · 0.80
try_get_vertexMethod · 0.80
getMethod · 0.65
iterMethod · 0.45
insertMethod · 0.45
containsMethod · 0.45
pushMethod · 0.45
lenMethod · 0.45
allMethod · 0.45

Tested by 2

three_way_forkFunction · 0.68