mirror of
https://github.com/meilisearch/meilisearch.git
synced 2025-07-31 02:40:01 +00:00
Make PathSet strongly typed
This commit is contained in:
@ -24,7 +24,11 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
|
||||
cost: u16,
|
||||
all_distances: &MappedInterner<Vec<(u16, SmallBitmap<G::EdgeCondition>)>, QueryNode>,
|
||||
empty_paths_cache: &mut DeadEndPathCache<G>,
|
||||
mut visit: impl FnMut(&[u16], &mut Self, &mut DeadEndPathCache<G>) -> Result<ControlFlow<()>>,
|
||||
mut visit: impl FnMut(
|
||||
&[Interned<G::EdgeCondition>],
|
||||
&mut Self,
|
||||
&mut DeadEndPathCache<G>,
|
||||
) -> Result<ControlFlow<()>>,
|
||||
) -> Result<()> {
|
||||
let _ = self.visit_paths_of_cost_rec(
|
||||
from,
|
||||
@ -44,8 +48,12 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
|
||||
cost: u16,
|
||||
all_distances: &MappedInterner<Vec<(u16, SmallBitmap<G::EdgeCondition>)>, QueryNode>,
|
||||
empty_paths_cache: &mut DeadEndPathCache<G>,
|
||||
visit: &mut impl FnMut(&[u16], &mut Self, &mut DeadEndPathCache<G>) -> Result<ControlFlow<()>>,
|
||||
prev_conditions: &mut Vec<u16>,
|
||||
visit: &mut impl FnMut(
|
||||
&[Interned<G::EdgeCondition>],
|
||||
&mut Self,
|
||||
&mut DeadEndPathCache<G>,
|
||||
) -> Result<ControlFlow<()>>,
|
||||
prev_conditions: &mut Vec<Interned<G::EdgeCondition>>,
|
||||
cur_path: &mut SmallBitmap<G::EdgeCondition>,
|
||||
forbidden_conditions: &mut SmallBitmap<G::EdgeCondition>,
|
||||
) -> Result<bool> {
|
||||
@ -92,8 +100,7 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
|
||||
continue;
|
||||
}
|
||||
cur_path.insert(condition);
|
||||
// TODO: typed path set
|
||||
prev_conditions.push(condition.into_inner());
|
||||
prev_conditions.push(condition);
|
||||
|
||||
let mut new_forbidden_conditions = forbidden_conditions.clone();
|
||||
new_forbidden_conditions
|
||||
@ -101,7 +108,7 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
|
||||
empty_paths_cache.prefixes.final_edges_after_prefix(
|
||||
prev_conditions,
|
||||
&mut |x| {
|
||||
new_forbidden_conditions.insert(Interned::new(x));
|
||||
new_forbidden_conditions.insert(x);
|
||||
},
|
||||
);
|
||||
let next_any_valid = if edge.dest_node == self.query_graph.end_node {
|
||||
@ -137,12 +144,11 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
|
||||
}
|
||||
forbidden_conditions.union(&empty_paths_cache.conditions);
|
||||
for prev_condition in prev_conditions.iter() {
|
||||
forbidden_conditions.union(
|
||||
empty_paths_cache.condition_couples.get(Interned::new(*prev_condition)),
|
||||
);
|
||||
forbidden_conditions
|
||||
.union(empty_paths_cache.condition_couples.get(*prev_condition));
|
||||
}
|
||||
empty_paths_cache.prefixes.final_edges_after_prefix(prev_conditions, &mut |x| {
|
||||
forbidden_conditions.insert(Interned::new(x));
|
||||
forbidden_conditions.insert(x);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ pub struct DeadEndPathCache<G: RankingRuleGraphTrait> {
|
||||
/// The set of edge conditions that resolve to no documents.
|
||||
pub conditions: SmallBitmap<G::EdgeCondition>,
|
||||
/// A set of path prefixes that resolve to no documents.
|
||||
pub prefixes: PathSet,
|
||||
pub prefixes: PathSet<G::EdgeCondition>,
|
||||
/// A set of empty couples of edge conditions that resolve to no documents.
|
||||
pub condition_couples: MappedInterner<SmallBitmap<G::EdgeCondition>, G::EdgeCondition>,
|
||||
}
|
||||
@ -40,13 +40,13 @@ impl<G: RankingRuleGraphTrait> DeadEndPathCache<G> {
|
||||
pub fn add_condition(&mut self, condition: Interned<G::EdgeCondition>) {
|
||||
self.conditions.insert(condition);
|
||||
self.condition_couples.get_mut(condition).clear();
|
||||
self.prefixes.remove_edge(condition.into_inner()); // TODO: typed PathSet
|
||||
self.prefixes.remove_edge(condition);
|
||||
for (_, edges2) in self.condition_couples.iter_mut() {
|
||||
edges2.remove(condition);
|
||||
}
|
||||
}
|
||||
/// Store in the cache that every path containing the given prefix resolves to no documents.
|
||||
pub fn add_prefix(&mut self, prefix: &[u16]) {
|
||||
pub fn add_prefix(&mut self, prefix: &[Interned<G::EdgeCondition>]) {
|
||||
// TODO: typed PathSet
|
||||
self.prefixes.insert(prefix.iter().copied());
|
||||
}
|
||||
@ -63,15 +63,15 @@ impl<G: RankingRuleGraphTrait> DeadEndPathCache<G> {
|
||||
/// Returns true if the cache can determine that the given path resolves to no documents.
|
||||
pub fn path_is_dead_end(
|
||||
&self,
|
||||
path: &[u16],
|
||||
path: &[Interned<G::EdgeCondition>],
|
||||
path_bitmap: &SmallBitmap<G::EdgeCondition>,
|
||||
) -> bool {
|
||||
if path_bitmap.intersects(&self.conditions) {
|
||||
return true;
|
||||
}
|
||||
for edge in path.iter() {
|
||||
for condition in path.iter() {
|
||||
// TODO: typed path
|
||||
let forbidden_other_edges = self.condition_couples.get(Interned::new(*edge));
|
||||
let forbidden_other_edges = self.condition_couples.get(*condition);
|
||||
if path_bitmap.intersects(forbidden_other_edges) {
|
||||
return true;
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ pub trait RankingRuleGraphTrait: Sized {
|
||||
|
||||
fn log_state(
|
||||
graph: &RankingRuleGraph<Self>,
|
||||
paths: &[Vec<u16>],
|
||||
paths: &[Vec<Interned<Self::EdgeCondition>>],
|
||||
empty_paths_cache: &DeadEndPathCache<Self>,
|
||||
universe: &RoaringBitmap,
|
||||
distances: &MappedInterner<Vec<(u16, SmallBitmap<Self::EdgeCondition>)>, QueryNode>,
|
||||
|
@ -2,14 +2,34 @@
|
||||
// For the empty_prefixes field in the EmptyPathsCache only :/
|
||||
// but it could be used for more, like efficient computing of a set of paths
|
||||
|
||||
use crate::search::new::interner::Interned;
|
||||
|
||||
/// A set of [`Path`]
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct PathSet {
|
||||
nodes: Vec<(u16, PathSet)>,
|
||||
pub struct PathSet<T> {
|
||||
nodes: Vec<(Interned<T>, Self)>,
|
||||
is_end: bool,
|
||||
}
|
||||
impl PathSet {
|
||||
pub fn insert(&mut self, mut edges: impl Iterator<Item = u16>) {
|
||||
|
||||
impl<T> Clone for PathSet<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self { nodes: self.nodes.clone(), is_end: self.is_end }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::fmt::Debug for PathSet<T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("PathSet").field("nodes", &self.nodes).field("is_end", &self.is_end).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for PathSet<T> {
|
||||
fn default() -> Self {
|
||||
Self { nodes: Default::default(), is_end: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> PathSet<T> {
|
||||
pub fn insert(&mut self, mut edges: impl Iterator<Item = Interned<T>>) {
|
||||
match edges.next() {
|
||||
None => {
|
||||
self.is_end = true;
|
||||
@ -27,7 +47,7 @@ impl PathSet {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_edge(&mut self, forbidden_edge: u16) {
|
||||
pub fn remove_edge(&mut self, forbidden_edge: Interned<T>) {
|
||||
let mut i = 0;
|
||||
while i < self.nodes.len() {
|
||||
let should_remove = if self.nodes[i].0 == forbidden_edge {
|
||||
@ -46,7 +66,11 @@ impl PathSet {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn final_edges_after_prefix(&self, prefix: &[u16], visit: &mut impl FnMut(u16)) {
|
||||
pub fn final_edges_after_prefix(
|
||||
&self,
|
||||
prefix: &[Interned<T>],
|
||||
visit: &mut impl FnMut(Interned<T>),
|
||||
) {
|
||||
let [first_edge, remaining_prefix @ ..] = prefix else {
|
||||
for node in self.nodes.iter() {
|
||||
if node.1.is_end {
|
||||
@ -62,7 +86,7 @@ impl PathSet {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn contains_prefix_of_path(&self, path: &[u16]) -> bool {
|
||||
pub fn contains_prefix_of_path(&self, path: &[Interned<T>]) -> bool {
|
||||
if self.is_end {
|
||||
return true;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ impl RankingRuleGraphTrait for ProximityGraph {
|
||||
|
||||
fn log_state(
|
||||
graph: &RankingRuleGraph<Self>,
|
||||
paths: &[Vec<u16>],
|
||||
paths: &[Vec<Interned<ProximityCondition>>],
|
||||
empty_paths_cache: &DeadEndPathCache<Self>,
|
||||
universe: &RoaringBitmap,
|
||||
distances: &MappedInterner<Vec<(u16, SmallBitmap<ProximityCondition>)>, QueryNode>,
|
||||
|
@ -137,7 +137,7 @@ impl RankingRuleGraphTrait for TypoGraph {
|
||||
|
||||
fn log_state(
|
||||
graph: &RankingRuleGraph<Self>,
|
||||
paths: &[Vec<u16>],
|
||||
paths: &[Vec<Interned<TypoEdge>>],
|
||||
empty_paths_cache: &DeadEndPathCache<Self>,
|
||||
universe: &RoaringBitmap,
|
||||
distances: &MappedInterner<Vec<(u16, SmallBitmap<TypoEdge>)>, QueryNode>,
|
||||
|
Reference in New Issue
Block a user