mirror of
https://github.com/meilisearch/meilisearch.git
synced 2024-11-27 04:25:06 +08:00
Add forgotten file
This commit is contained in:
parent
825f742000
commit
a59ca28e2c
93
milli/src/search/new/ranking_rule_graph/dead_ends_cache.rs
Normal file
93
milli/src/search/new/ranking_rule_graph/dead_ends_cache.rs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
use crate::search::new::{
|
||||||
|
interner::{FixedSizeInterner, Interned},
|
||||||
|
small_bitmap::SmallBitmap,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct DeadEndsCache<T> {
|
||||||
|
conditions: Vec<Interned<T>>,
|
||||||
|
next: Vec<Self>,
|
||||||
|
pub forbidden: SmallBitmap<T>,
|
||||||
|
}
|
||||||
|
impl<T> Clone for DeadEndsCache<T> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
conditions: self.conditions.clone(),
|
||||||
|
next: self.next.clone(),
|
||||||
|
forbidden: self.forbidden.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T> DeadEndsCache<T> {
|
||||||
|
pub fn new(for_interner: &FixedSizeInterner<T>) -> Self {
|
||||||
|
Self {
|
||||||
|
conditions: vec![],
|
||||||
|
next: vec![],
|
||||||
|
forbidden: SmallBitmap::for_interned_values_in(for_interner),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn forbid_condition(&mut self, condition: Interned<T>) {
|
||||||
|
self.forbidden.insert(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn advance(&mut self, condition: Interned<T>) -> Option<&mut Self> {
|
||||||
|
if let Some(idx) = self.conditions.iter().position(|c| *c == condition) {
|
||||||
|
Some(&mut self.next[idx])
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn forbidden_conditions_for_all_prefixes_up_to(
|
||||||
|
&mut self,
|
||||||
|
prefix: &[Interned<T>],
|
||||||
|
) -> SmallBitmap<T> {
|
||||||
|
let mut forbidden = self.forbidden.clone();
|
||||||
|
let mut cursor = self;
|
||||||
|
for c in prefix.iter() {
|
||||||
|
if let Some(next) = cursor.advance(*c) {
|
||||||
|
cursor = next;
|
||||||
|
forbidden.union(&cursor.forbidden);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
forbidden
|
||||||
|
}
|
||||||
|
pub fn forbidden_conditions_after_prefix(
|
||||||
|
&mut self,
|
||||||
|
prefix: &[Interned<T>],
|
||||||
|
) -> Option<SmallBitmap<T>> {
|
||||||
|
let mut cursor = self;
|
||||||
|
for c in prefix.iter() {
|
||||||
|
if let Some(next) = cursor.advance(*c) {
|
||||||
|
cursor = next;
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(cursor.forbidden.clone())
|
||||||
|
}
|
||||||
|
pub fn forbid_condition_after_prefix(
|
||||||
|
&mut self,
|
||||||
|
mut prefix: impl Iterator<Item = Interned<T>>,
|
||||||
|
forbidden: Interned<T>,
|
||||||
|
) {
|
||||||
|
match prefix.next() {
|
||||||
|
None => {
|
||||||
|
self.forbidden.insert(forbidden);
|
||||||
|
}
|
||||||
|
Some(first_condition) => {
|
||||||
|
if let Some(idx) = self.conditions.iter().position(|c| *c == first_condition) {
|
||||||
|
return self.next[idx].forbid_condition_after_prefix(prefix, forbidden);
|
||||||
|
}
|
||||||
|
let mut rest = DeadEndsCache {
|
||||||
|
conditions: vec![],
|
||||||
|
next: vec![],
|
||||||
|
forbidden: SmallBitmap::new(self.forbidden.universe_length()),
|
||||||
|
};
|
||||||
|
rest.forbid_condition_after_prefix(prefix, forbidden);
|
||||||
|
self.conditions.push(first_condition);
|
||||||
|
self.next.push(rest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user