use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::collections::HashMap;
use std::collections::HashSet;
use std::iter::FromIterator;
use smallvec::SmallVec;
use sparta::graph::Graph;
use sparta::graph::DEFAULT_GRAPH_SUCCS_NUM;
pub type NodeId = u32;
pub type EdgeId = u32;
pub struct Edge(NodeId, NodeId);
#[derive(Default)]
pub struct SimpleGraph {
edges: HashMap<NodeId, BTreeSet<EdgeId>>,
pred_edges: BTreeMap<NodeId, BTreeSet<EdgeId>>,
edge_interner: Vec<Edge>,
enter: NodeId,
exit: NodeId,
}
impl SimpleGraph {
pub fn new(enter: NodeId, exit: NodeId) -> Self {
Self {
enter,
exit,
..Default::default()
}
}
pub fn add_edge(&mut self, source: NodeId, target: NodeId) {
self.edge_interner.push(Edge(source, target));
let edge_id = self.edge_interner.len() - 1;
self.edges.entry(source).or_default().insert(edge_id as u32);
self.pred_edges
.entry(target)
.or_default()
.insert(edge_id as u32);
}
}
impl Graph for SimpleGraph {
type NodeId = NodeId;
type EdgeId = EdgeId;
fn entry(&self) -> Self::NodeId {
self.enter
}
fn exit(&self) -> Self::NodeId {
self.exit
}
fn predecessors(&self, n: Self::NodeId) -> SmallVec<[Self::EdgeId; DEFAULT_GRAPH_SUCCS_NUM]> {
self.pred_edges
.get(&n)
.map(|v| v.iter().copied().collect())
.unwrap_or_else(SmallVec::new)
}
fn successors(&self, n: Self::NodeId) -> SmallVec<[Self::EdgeId; DEFAULT_GRAPH_SUCCS_NUM]> {
self.edges
.get(&n)
.map(|v| v.iter().copied().collect())
.unwrap_or_else(SmallVec::new)
}
fn source(&self, e: Self::EdgeId) -> Self::NodeId {
self.edge_interner[e as usize].0
}
fn target(&self, e: Self::EdgeId) -> Self::NodeId {
self.edge_interner[e as usize].1
}
fn size(&self) -> usize {
let mut nodes: HashSet<NodeId> = HashSet::from_iter(self.edges.keys().copied());
nodes.extend(self.pred_edges.keys().copied());
nodes.len()
}
}