use core::iter::FusedIterator;
use oxgraph_topology::{
ContainsElement, ElementId, ElementIndex, ElementPredecessors, ElementSuccessors,
};
use crate::bfs::{
BfsError,
core::{Bfs, Forward, Reverse, SeededByteFlagFrontier, ValidatedScratch},
};
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct BreadthFirstSearchScratch<'graph, 'scratch, G>
where
G: ContainsElement + ElementSuccessors + ElementIndex,
{
inner: Bfs<'graph, G, SeededByteFlagFrontier<'scratch, G>, Forward>,
}
impl<G> Iterator for BreadthFirstSearchScratch<'_, '_, G>
where
G: ContainsElement + ElementSuccessors + ElementIndex,
{
type Item = ElementId<G>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<G> FusedIterator for BreadthFirstSearchScratch<'_, '_, G> where
G: ContainsElement + ElementSuccessors + ElementIndex
{
}
pub fn breadth_first_search_with_scratch<'graph, 'scratch, G>(
graph: &'graph G,
start: ElementId<G>,
visited: &'scratch mut [u8],
queue: &'scratch mut [ElementId<G>],
) -> Result<BreadthFirstSearchScratch<'graph, 'scratch, G>, BfsError>
where
G: ContainsElement + ElementSuccessors + ElementIndex,
{
let witness = ValidatedScratch::new(graph, start, visited.len(), queue.len())?;
let frontier = SeededByteFlagFrontier::new(visited, queue, start, witness);
Ok(BreadthFirstSearchScratch {
inner: Bfs::new(graph, frontier),
})
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct ReverseBreadthFirstSearchScratch<'graph, 'scratch, G>
where
G: ContainsElement + ElementPredecessors + ElementIndex,
{
inner: Bfs<'graph, G, SeededByteFlagFrontier<'scratch, G>, Reverse>,
}
impl<G> Iterator for ReverseBreadthFirstSearchScratch<'_, '_, G>
where
G: ContainsElement + ElementPredecessors + ElementIndex,
{
type Item = ElementId<G>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<G> FusedIterator for ReverseBreadthFirstSearchScratch<'_, '_, G> where
G: ContainsElement + ElementPredecessors + ElementIndex
{
}
pub fn reverse_breadth_first_search_with_scratch<'graph, 'scratch, G>(
graph: &'graph G,
start: ElementId<G>,
visited: &'scratch mut [u8],
queue: &'scratch mut [ElementId<G>],
) -> Result<ReverseBreadthFirstSearchScratch<'graph, 'scratch, G>, BfsError>
where
G: ContainsElement + ElementPredecessors + ElementIndex,
{
let witness = ValidatedScratch::new(graph, start, visited.len(), queue.len())?;
let frontier = SeededByteFlagFrontier::new(visited, queue, start, witness);
Ok(ReverseBreadthFirstSearchScratch {
inner: Bfs::new(graph, frontier),
})
}