MeiliSearch/milli/src/search/criteria/final.rs

60 lines
2.3 KiB
Rust
Raw Normal View History

2021-03-23 15:25:46 +01:00
use log::debug;
use roaring::RoaringBitmap;
use crate::search::query_tree::Operation;
use crate::search::WordDerivationsCache;
use super::{resolve_query_tree, Criterion, CriterionResult, CriterionParameters, Context};
2021-03-23 15:25:46 +01:00
/// The result of a call to the fetcher.
#[derive(Debug, Clone, PartialEq)]
pub struct FinalResult {
/// The query tree corresponding to the current bucket of the last criterion.
pub query_tree: Option<Operation>,
/// The candidates of the current bucket of the last criterion.
pub candidates: RoaringBitmap,
/// Candidates that comes from the current bucket of the initial criterion.
pub bucket_candidates: RoaringBitmap,
}
pub struct Final<'t> {
ctx: &'t dyn Context<'t>,
2021-03-23 15:25:46 +01:00
parent: Box<dyn Criterion + 't>,
wdcache: WordDerivationsCache,
returned_candidates: RoaringBitmap,
2021-03-23 15:25:46 +01:00
}
impl<'t> Final<'t> {
pub fn new(ctx: &'t dyn Context<'t>, parent: Box<dyn Criterion + 't>) -> Final<'t> {
Final { ctx, parent, wdcache: WordDerivationsCache::new(), returned_candidates: RoaringBitmap::new() }
2021-03-23 15:25:46 +01:00
}
#[logging_timer::time("Final::{}")]
pub fn next(&mut self, excluded_candidates: &RoaringBitmap) -> anyhow::Result<Option<FinalResult>> {
2021-03-23 15:25:46 +01:00
loop {
debug!("Final iteration");
let mut criterion_parameters = CriterionParameters {
wdcache: &mut self.wdcache,
// returned_candidates is merged with excluded_candidates to avoid duplicas
excluded_candidates: &(&self.returned_candidates | excluded_candidates),
};
2021-03-23 15:25:46 +01:00
match self.parent.next(&mut criterion_parameters)? {
2021-05-05 20:46:56 +02:00
Some(CriterionResult { query_tree, candidates, bucket_candidates }) => {
let candidates = match (candidates, query_tree.as_ref()) {
(Some(candidates), _) => candidates,
(None, Some(qt)) => resolve_query_tree(self.ctx, qt, &mut self.wdcache)?,
(None, None) => self.ctx.documents_ids()?,
2021-03-23 15:25:46 +01:00
};
2021-05-05 20:46:56 +02:00
let bucket_candidates = bucket_candidates.unwrap_or_else(|| candidates.clone());
self.returned_candidates |= &candidates;
2021-03-23 15:25:46 +01:00
return Ok(Some(FinalResult { query_tree, candidates, bucket_candidates }));
2021-03-23 15:25:46 +01:00
},
None => return Ok(None),
}
}
}
}