use std::borrow::Borrow;
use std::collections::VecDeque;
use swh_graph::graph::*;
use crate::collections::{AdaptiveNodeSet, NodeSet, ReadNodeSet};
pub struct NodeVisit<G>
where
G: SwhForwardGraph,
{
graph: G,
visited: AdaptiveNodeSet,
queue: VecDeque<NodeId>,
}
impl<G> NodeVisit<G>
where
G: SwhForwardGraph,
{
fn new<I: IntoIterator<Item: Borrow<NodeId>>>(graph: G, nodes: I) -> Self {
NodeVisit {
visited: AdaptiveNodeSet::new(graph.num_nodes()),
graph,
queue: nodes.into_iter().map(|item| *item.borrow()).collect(),
}
}
}
impl<G> Iterator for NodeVisit<G>
where
G: SwhForwardGraph,
{
type Item = NodeId;
fn next(&mut self) -> Option<Self::Item> {
if let Some(current_node) = self.queue.pop_front() {
for succ in self.graph.successors(current_node) {
if !self.visited.contains(succ) {
self.queue.push_back(succ);
self.visited.insert(succ);
}
}
Some(current_node)
} else {
None
}
}
}
pub fn iter_nodes<G, I: IntoIterator<Item: Borrow<NodeId>>>(graph: G, start: I) -> NodeVisit<G>
where
G: SwhForwardGraph,
{
NodeVisit::new(graph, start)
}