mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-11-22 21:04:27 +01:00
Apply review suggestions: simplify implementation of exactness criterion
This commit is contained in:
parent
32c6062e65
commit
b5df889dcb
@ -191,7 +191,7 @@ fn resolve_state(
|
|||||||
attribute_start_with_docids(ctx, id, query)?;
|
attribute_start_with_docids(ctx, id, query)?;
|
||||||
attribute_candidates_array.push(attribute_allowed_docids);
|
attribute_candidates_array.push(attribute_allowed_docids);
|
||||||
|
|
||||||
candidates |= intersection_of(attribute_candidates_array.iter().collect());
|
candidates |= MultiOps::intersection(attribute_candidates_array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ fn resolve_state(
|
|||||||
let attributes_ids = ctx.searchable_fields_ids()?;
|
let attributes_ids = ctx.searchable_fields_ids()?;
|
||||||
for id in attributes_ids {
|
for id in attributes_ids {
|
||||||
let attribute_candidates_array = attribute_start_with_docids(ctx, id, query)?;
|
let attribute_candidates_array = attribute_start_with_docids(ctx, id, query)?;
|
||||||
candidates |= intersection_of(attribute_candidates_array.iter().collect());
|
candidates |= MultiOps::intersection(attribute_candidates_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
// only keep allowed candidates
|
// only keep allowed candidates
|
||||||
@ -289,12 +289,6 @@ fn attribute_start_with_docids(
|
|||||||
Ok(attribute_candidates_array)
|
Ok(attribute_candidates_array)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(never)]
|
|
||||||
fn intersection_of(mut rbs: Vec<&RoaringBitmap>) -> RoaringBitmap {
|
|
||||||
rbs.sort_unstable_by_key(|rb| rb.len());
|
|
||||||
roaring::MultiOps::intersection(rbs.into_iter())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ExactQueryPart {
|
pub enum ExactQueryPart {
|
||||||
Phrase(Vec<Option<String>>),
|
Phrase(Vec<Option<String>>),
|
||||||
@ -440,8 +434,7 @@ fn compute_combinations(
|
|||||||
fn create_non_disjoint_combinations(bitmaps: Vec<RoaringBitmap>) -> Vec<RoaringBitmap> {
|
fn create_non_disjoint_combinations(bitmaps: Vec<RoaringBitmap>) -> Vec<RoaringBitmap> {
|
||||||
let nbr_parts = bitmaps.len();
|
let nbr_parts = bitmaps.len();
|
||||||
if nbr_parts == 1 {
|
if nbr_parts == 1 {
|
||||||
let flattened_base_level = MultiOps::union(bitmaps.into_iter());
|
return bitmaps;
|
||||||
return vec![flattened_base_level];
|
|
||||||
}
|
}
|
||||||
let mut flattened_levels = vec![];
|
let mut flattened_levels = vec![];
|
||||||
let mut last_level: BTreeMap<usize, RoaringBitmap> =
|
let mut last_level: BTreeMap<usize, RoaringBitmap> =
|
||||||
@ -466,12 +459,12 @@ fn create_non_disjoint_combinations(bitmaps: Vec<RoaringBitmap>) -> Vec<RoaringB
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Now flatten the last level to save memory
|
// Now flatten the last level to save memory
|
||||||
let flattened_last_level = MultiOps::union(last_level.values());
|
let flattened_last_level = MultiOps::union(last_level.into_values());
|
||||||
flattened_levels.push(flattened_last_level);
|
flattened_levels.push(flattened_last_level);
|
||||||
last_level = new_level;
|
last_level = new_level;
|
||||||
}
|
}
|
||||||
// Flatten the last level
|
// Flatten the last level
|
||||||
let flattened_last_level = MultiOps::union(last_level.values());
|
let flattened_last_level = MultiOps::union(last_level.into_values());
|
||||||
flattened_levels.push(flattened_last_level);
|
flattened_levels.push(flattened_last_level);
|
||||||
flattened_levels
|
flattened_levels
|
||||||
}
|
}
|
||||||
@ -480,27 +473,17 @@ fn create_non_disjoint_combinations(bitmaps: Vec<RoaringBitmap>) -> Vec<RoaringB
|
|||||||
/// such that `Xi` contains all the elements that are contained in **exactly** `i+1` bitmaps among `b0,b1,...,bn`.
|
/// such that `Xi` contains all the elements that are contained in **exactly** `i+1` bitmaps among `b0,b1,...,bn`.
|
||||||
///
|
///
|
||||||
/// The returned vector is guaranteed to be of length `n`. It is equal to `vec![X0, X1, ..., Xn]`.
|
/// The returned vector is guaranteed to be of length `n`. It is equal to `vec![X0, X1, ..., Xn]`.
|
||||||
///
|
|
||||||
/// ## Implementation
|
|
||||||
/// 1. We first create `Y0,Y1,...Yn` such that `Yi` contains all the elements that are contained in
|
|
||||||
/// **at least** `i+1` bitmaps among `b0,b1,...,bn`. This is done using `create_non_disjoint_combinations`.
|
|
||||||
///
|
|
||||||
/// 2. We create a set of "forbidden" elements, `Fn`, which is initialised to the empty set.
|
|
||||||
///
|
|
||||||
/// 3. We compute:
|
|
||||||
/// - `Xn = Yn - Fn`
|
|
||||||
/// - `Fn-1 = Fn | Xn`
|
|
||||||
fn create_disjoint_combinations(parts_candidates_array: Vec<RoaringBitmap>) -> Vec<RoaringBitmap> {
|
fn create_disjoint_combinations(parts_candidates_array: Vec<RoaringBitmap>) -> Vec<RoaringBitmap> {
|
||||||
let non_disjoint_combinations = create_non_disjoint_combinations(parts_candidates_array);
|
let non_disjoint_combinations = create_non_disjoint_combinations(parts_candidates_array);
|
||||||
|
|
||||||
let mut disjoint_combinations = vec![];
|
let mut disjoint_combinations = vec![];
|
||||||
let mut forbidden = RoaringBitmap::new();
|
let mut combinations = non_disjoint_combinations.into_iter().peekable();
|
||||||
for mut combination in non_disjoint_combinations.into_iter().rev() {
|
while let Some(mut combination) = combinations.next() {
|
||||||
combination -= &forbidden;
|
if let Some(forbidden) = combinations.peek() {
|
||||||
forbidden |= &combination;
|
combination -= forbidden;
|
||||||
|
}
|
||||||
disjoint_combinations.push(combination)
|
disjoint_combinations.push(combination)
|
||||||
}
|
}
|
||||||
disjoint_combinations.reverse();
|
|
||||||
disjoint_combinations
|
disjoint_combinations
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user