Incorporate iter_nodes
into graph::DirectedGraph
This assumes that the set of valid node IDs is exactly `0..num_nodes`. In practice, we have a lot of graph-algorithm code that already assumes that nodes are densely numbered, by using `num_nodes` to allocate per-node indexed data structures.
This commit is contained in:
parent
6fb03584cf
commit
d36e2b88d6
6 changed files with 18 additions and 23 deletions
|
@ -14,7 +14,23 @@ mod tests;
|
||||||
pub trait DirectedGraph {
|
pub trait DirectedGraph {
|
||||||
type Node: Idx;
|
type Node: Idx;
|
||||||
|
|
||||||
|
/// Returns the total number of nodes in this graph.
|
||||||
|
///
|
||||||
|
/// Several graph algorithm implementations assume that every node ID is
|
||||||
|
/// strictly less than the number of nodes, i.e. nodes are densely numbered.
|
||||||
|
/// That assumption allows them to use `num_nodes` to allocate per-node
|
||||||
|
/// data structures, indexed by node.
|
||||||
fn num_nodes(&self) -> usize;
|
fn num_nodes(&self) -> usize;
|
||||||
|
|
||||||
|
/// Iterates over all nodes of a graph in ascending numeric order.
|
||||||
|
///
|
||||||
|
/// Assumes that nodes are densely numbered, i.e. every index in
|
||||||
|
/// `0..num_nodes` is a valid node.
|
||||||
|
fn iter_nodes(
|
||||||
|
&self,
|
||||||
|
) -> impl Iterator<Item = Self::Node> + DoubleEndedIterator + ExactSizeIterator {
|
||||||
|
(0..self.num_nodes()).map(<Self::Node as Idx>::new)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait NumEdges: DirectedGraph {
|
pub trait NumEdges: DirectedGraph {
|
||||||
|
|
|
@ -333,8 +333,8 @@ where
|
||||||
to_annotation,
|
to_annotation,
|
||||||
};
|
};
|
||||||
|
|
||||||
let scc_indices = (0..num_nodes)
|
let scc_indices = graph
|
||||||
.map(G::Node::new)
|
.iter_nodes()
|
||||||
.map(|node| match this.start_walk_from(node) {
|
.map(|node| match this.start_walk_from(node) {
|
||||||
WalkReturn::Complete { scc_index, .. } => scc_index,
|
WalkReturn::Complete { scc_index, .. } => scc_index,
|
||||||
WalkReturn::Cycle { min_depth, .. } => {
|
WalkReturn::Cycle { min_depth, .. } => {
|
||||||
|
|
|
@ -10,14 +10,12 @@ use rustc_index::bit_set::DenseBitSet;
|
||||||
use rustc_middle::mir::coverage::{CounterId, CovTerm, Expression, ExpressionId, Op};
|
use rustc_middle::mir::coverage::{CounterId, CovTerm, Expression, ExpressionId, Op};
|
||||||
|
|
||||||
use crate::coverage::counters::balanced_flow::BalancedFlowGraph;
|
use crate::coverage::counters::balanced_flow::BalancedFlowGraph;
|
||||||
use crate::coverage::counters::iter_nodes::IterNodes;
|
|
||||||
use crate::coverage::counters::node_flow::{
|
use crate::coverage::counters::node_flow::{
|
||||||
CounterTerm, NodeCounters, make_node_counters, node_flow_data_for_balanced_graph,
|
CounterTerm, NodeCounters, make_node_counters, node_flow_data_for_balanced_graph,
|
||||||
};
|
};
|
||||||
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
|
use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
|
||||||
|
|
||||||
mod balanced_flow;
|
mod balanced_flow;
|
||||||
mod iter_nodes;
|
|
||||||
mod node_flow;
|
mod node_flow;
|
||||||
mod union_find;
|
mod union_find;
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,6 @@ use rustc_data_structures::graph::reversed::ReversedGraph;
|
||||||
use rustc_index::Idx;
|
use rustc_index::Idx;
|
||||||
use rustc_index::bit_set::DenseBitSet;
|
use rustc_index::bit_set::DenseBitSet;
|
||||||
|
|
||||||
use crate::coverage::counters::iter_nodes::IterNodes;
|
|
||||||
|
|
||||||
/// A view of an underlying graph that has been augmented to have “balanced flow”.
|
/// A view of an underlying graph that has been augmented to have “balanced flow”.
|
||||||
/// This means that the flow (execution count) of each node is equal to the
|
/// This means that the flow (execution count) of each node is equal to the
|
||||||
/// sum of its in-edge flows, and also equal to the sum of its out-edge flows.
|
/// sum of its in-edge flows, and also equal to the sum of its out-edge flows.
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
use rustc_data_structures::graph;
|
|
||||||
use rustc_index::Idx;
|
|
||||||
|
|
||||||
pub(crate) trait IterNodes: graph::DirectedGraph {
|
|
||||||
/// Iterates over all nodes of a graph in ascending numeric order.
|
|
||||||
/// Assumes that nodes are densely numbered, i.e. every index in
|
|
||||||
/// `0..num_nodes` is a valid node.
|
|
||||||
///
|
|
||||||
/// FIXME: Can this just be part of [`graph::DirectedGraph`]?
|
|
||||||
fn iter_nodes(
|
|
||||||
&self,
|
|
||||||
) -> impl Iterator<Item = Self::Node> + DoubleEndedIterator + ExactSizeIterator {
|
|
||||||
(0..self.num_nodes()).map(<Self::Node as Idx>::new)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<G: graph::DirectedGraph> IterNodes for G {}
|
|
|
@ -11,7 +11,6 @@ use rustc_index::bit_set::DenseBitSet;
|
||||||
use rustc_index::{Idx, IndexSlice, IndexVec};
|
use rustc_index::{Idx, IndexSlice, IndexVec};
|
||||||
use rustc_middle::mir::coverage::Op;
|
use rustc_middle::mir::coverage::Op;
|
||||||
|
|
||||||
use crate::coverage::counters::iter_nodes::IterNodes;
|
|
||||||
use crate::coverage::counters::union_find::UnionFind;
|
use crate::coverage::counters::union_find::UnionFind;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue