use std::mem::swap;
use crate::DbError;
use crate::StorageData;
use crate::graph::GraphData;
use crate::graph::GraphImpl;
use crate::graph::GraphIndex;
use crate::graph_search::SearchControl;
use crate::graph_search::SearchHandler;
use crate::storage::Storage;
pub struct ElementSearch<'a, D, Data, Handler>
where
Data: GraphData<D>,
D: StorageData,
Handler: SearchHandler,
{
graph: &'a GraphImpl<D, Data>,
storage: &'a Storage<D>,
handler: Handler,
result: Vec<GraphIndex>,
}
impl<'a, D, Data, Handler> ElementSearch<'a, D, Data, Handler>
where
Data: GraphData<D>,
D: StorageData,
Handler: SearchHandler,
{
pub fn new(graph: &'a GraphImpl<D, Data>, storage: &'a Storage<D>, handler: Handler) -> Self {
Self {
graph,
storage,
handler,
result: vec![],
}
}
pub fn search(&mut self) -> Result<Vec<GraphIndex>, DbError> {
for (distance, index) in self.graph.iter(self.storage).enumerate() {
let add_index;
let finished;
match self.handler.process(index, distance as u64)? {
SearchControl::Continue(add) => {
add_index = add;
finished = false;
}
SearchControl::Finish(add) => {
add_index = add;
finished = true;
}
SearchControl::Stop(add) => {
add_index = add;
finished = false;
}
}
if add_index {
self.result.push(index);
}
if finished {
break;
}
}
Ok(self.take_result())
}
fn take_result(&mut self) -> Vec<GraphIndex> {
let mut res = Vec::<GraphIndex>::new();
swap(&mut res, &mut self.result);
res
}
}