use rushdb_lmpg::Lmpg;
use crate::planner::OwnerSet;
use crate::{
check_walk_budget, index_candidates_with_budget, working_set_budget, Expr, QueryError,
QuerySnapshot, SearchRequest,
};
pub struct PlannedCandidates {
ords: roaring::treemap::IntoIter,
exact: bool,
}
impl PlannedCandidates {
#[must_use]
pub fn exact(&self) -> bool {
self.exact
}
}
impl Iterator for PlannedCandidates {
type Item = u64;
fn next(&mut self) -> Option<u64> {
self.ords.next()
}
}
pub fn planned_candidates(
lmpg: &Lmpg,
snap: &QuerySnapshot,
labels: &[String],
conditions: &[Expr],
is_cancelled: &dyn Fn() -> bool,
) -> Result<Option<PlannedCandidates>, QueryError> {
let req = SearchRequest {
labels: labels.to_vec(),
where_: Some(Expr::And(conditions.to_vec())),
..SearchRequest::default()
};
check_walk_budget(lmpg, snap, &req)?;
let is_cancelled: &dyn Fn() -> bool = &crate::cancel_probe(lmpg, is_cancelled);
let plan =
index_candidates_with_budget(lmpg, snap, &req, working_set_budget(lmpg), is_cancelled)?;
Ok(plan.map(|plan| {
let ords: OwnerSet = plan.ords;
PlannedCandidates {
ords: ords.into_iter(),
exact: plan.exact,
}
}))
}