in src/reader.rs [1165:1216]
fn propagate_counts(
blocks: &SmallVec<[GcovBlock; 16]>,
edges: &mut SmallVec<[GcovEdge; 16]>,
block_no: usize,
pred_arc: Option<usize>,
visited: &mut FxHashSet<usize>,
) -> u64 {
// For each basic block, the sum of incoming edge counts equals the sum of
// outgoing edge counts by Kirchoff's circuit law. If the unmeasured arcs form a
// spanning tree, the count for each unmeasured arc (GCOV_ARC_ON_TREE) can be
// uniquely identified.
// Prevent infinite recursion
if !visited.insert(block_no) {
return 0;
}
let mut positive_excess = 0;
let mut negative_excess = 0;
let block = &blocks[block_no];
for edge_id in block.source.iter() {
if pred_arc != Some(*edge_id) {
let edge = &edges[*edge_id];
positive_excess += if edge.is_on_tree() {
let source = edge.source;
Self::propagate_counts(blocks, edges, source, Some(*edge_id), visited)
} else {
edge.counter
};
}
}
for edge_id in block.destination.iter() {
if pred_arc != Some(*edge_id) {
let edge = &edges[*edge_id];
negative_excess += if edge.is_on_tree() {
let destination = edge.destination;
Self::propagate_counts(blocks, edges, destination, Some(*edge_id), visited)
} else {
edge.counter
};
}
}
let excess = if positive_excess >= negative_excess {
positive_excess - negative_excess
} else {
negative_excess - positive_excess
};
if let Some(id) = pred_arc {
let edge = &mut edges[id];
edge.counter = excess;
}
excess
}