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

76 lines
2.7 KiB
Rust
Raw Normal View History

2021-03-23 15:25:46 +01:00
use log::debug;
use roaring::RoaringBitmap;
2021-06-16 18:33:33 +02:00
use super::{resolve_query_tree, Context, Criterion, CriterionParameters, CriterionResult};
2021-03-23 15:25:46 +01:00
use crate::search::query_tree::Operation;
use crate::search::WordDerivationsCache;
2021-06-16 18:33:33 +02:00
use crate::Result;
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> {
2021-06-16 18:33:33 +02:00
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) -> Result<Option<FinalResult>> {
2021-05-10 10:27:18 +02:00
debug!("Final iteration");
2021-05-10 12:33:37 +02:00
let excluded_candidates = &self.returned_candidates | excluded_candidates;
2021-05-10 10:27:18 +02:00
let mut criterion_parameters = CriterionParameters {
wdcache: &mut self.wdcache,
// returned_candidates is merged with excluded_candidates to avoid duplicas
2021-05-10 12:33:37 +02:00
excluded_candidates: &excluded_candidates,
2021-05-10 10:27:18 +02:00
};
match self.parent.next(&mut criterion_parameters)? {
2021-06-16 18:33:33 +02:00
Some(CriterionResult {
query_tree,
candidates,
filtered_candidates,
bucket_candidates,
}) => {
2021-05-10 12:33:37 +02:00
let mut candidates = match (candidates, query_tree.as_ref()) {
2021-05-10 10:27:18 +02:00
(Some(candidates), _) => candidates,
2021-06-16 18:33:33 +02:00
(None, Some(qt)) => {
resolve_query_tree(self.ctx, qt, &mut self.wdcache)? - excluded_candidates
}
2021-05-10 12:33:37 +02:00
(None, None) => self.ctx.documents_ids()? - excluded_candidates,
2021-05-10 10:27:18 +02:00
};
2021-05-10 12:33:37 +02:00
if let Some(filtered_candidates) = filtered_candidates {
candidates &= filtered_candidates;
}
2021-05-10 10:27:18 +02:00
let bucket_candidates = bucket_candidates.unwrap_or_else(|| candidates.clone());
self.returned_candidates |= &candidates;
2021-05-10 12:33:37 +02:00
Ok(Some(FinalResult { query_tree, candidates, bucket_candidates }))
2021-06-16 18:33:33 +02:00
}
2021-05-10 12:33:37 +02:00
None => Ok(None),
2021-03-23 15:25:46 +01:00
}
}
}