Replace EdgeCondition with an Option<..> + other code cleanup

This commit is contained in:
Loïc Lecrenier
2023-03-16 11:52:51 +01:00
parent 7b1d8f4c6d
commit aa59c3bc2c
16 changed files with 202 additions and 204 deletions

View File

@ -1,7 +1,7 @@
use std::collections::HashSet;
use super::{Edge, RankingRuleGraph, RankingRuleGraphTrait};
use crate::search::new::interner::{DedupInterner, Interner};
use crate::search::new::interner::DedupInterner;
use crate::search::new::small_bitmap::SmallBitmap;
use crate::search::new::{QueryGraph, SearchContext};
use crate::Result;
@ -19,7 +19,7 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
let mut conditions_interner = DedupInterner::default();
let mut edges_store = Interner::default();
let mut edges_store = DedupInterner::default();
let mut edges_of_node = query_graph.nodes.map(|_| HashSet::new());
for (source_id, source_node) in graph_nodes.iter() {
@ -33,7 +33,7 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
}
for (cost, condition) in edges {
let new_edge_id = edges_store.push(Some(Edge {
let new_edge_id = edges_store.insert(Some(Edge {
source_node: source_id,
dest_node: dest_idx,
cost,

View File

@ -4,8 +4,8 @@ use std::collections::btree_map::Entry;
use std::collections::{BTreeMap, VecDeque};
use std::ops::ControlFlow;
use super::empty_paths_cache::DeadEndPathCache;
use super::{EdgeCondition, RankingRuleGraph, RankingRuleGraphTrait};
use super::dead_end_path_cache::DeadEndPathCache;
use super::{RankingRuleGraph, RankingRuleGraphTrait};
use crate::search::new::interner::{Interned, MappedInterner};
use crate::search::new::query_graph::QueryNode;
use crate::search::new::small_bitmap::SmallBitmap;
@ -23,7 +23,7 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
from: Interned<QueryNode>,
cost: u16,
all_distances: &MappedInterner<Vec<(u16, SmallBitmap<G::EdgeCondition>)>, QueryNode>,
empty_paths_cache: &mut DeadEndPathCache<G>,
dead_end_path_cache: &mut DeadEndPathCache<G>,
mut visit: impl FnMut(
&[Interned<G::EdgeCondition>],
&mut Self,
@ -34,11 +34,11 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
from,
cost,
all_distances,
empty_paths_cache,
dead_end_path_cache,
&mut visit,
&mut vec![],
&mut SmallBitmap::for_interned_values_in(&self.conditions_interner),
&mut empty_paths_cache.conditions.clone(),
&mut dead_end_path_cache.conditions.clone(),
)?;
Ok(())
}
@ -47,7 +47,7 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
from: Interned<QueryNode>,
cost: u16,
all_distances: &MappedInterner<Vec<(u16, SmallBitmap<G::EdgeCondition>)>, QueryNode>,
empty_paths_cache: &mut DeadEndPathCache<G>,
dead_end_path_cache: &mut DeadEndPathCache<G>,
visit: &mut impl FnMut(
&[Interned<G::EdgeCondition>],
&mut Self,
@ -66,10 +66,10 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
continue;
}
let next_any_valid = match edge.condition {
EdgeCondition::Unconditional => {
None => {
if edge.dest_node == self.query_graph.end_node {
any_valid = true;
let control_flow = visit(prev_conditions, self, empty_paths_cache)?;
let control_flow = visit(prev_conditions, self, dead_end_path_cache)?;
match control_flow {
ControlFlow::Continue(_) => {}
ControlFlow::Break(_) => return Ok(true),
@ -80,7 +80,7 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
edge.dest_node,
cost - edge.cost as u16,
all_distances,
empty_paths_cache,
dead_end_path_cache,
visit,
prev_conditions,
cur_path,
@ -88,7 +88,7 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
)?
}
}
EdgeCondition::Conditional(condition) => {
Some(condition) => {
if forbidden_conditions.contains(condition)
|| !all_distances.get(edge.dest_node).iter().any(
|(next_cost, necessary_conditions)| {
@ -104,8 +104,8 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
let mut new_forbidden_conditions = forbidden_conditions.clone();
new_forbidden_conditions
.union(empty_paths_cache.condition_couples.get(condition));
empty_paths_cache.prefixes.final_edges_after_prefix(
.union(dead_end_path_cache.condition_couples.get(condition));
dead_end_path_cache.prefixes.final_edges_after_prefix(
prev_conditions,
&mut |x| {
new_forbidden_conditions.insert(x);
@ -113,7 +113,7 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
);
let next_any_valid = if edge.dest_node == self.query_graph.end_node {
any_valid = true;
let control_flow = visit(prev_conditions, self, empty_paths_cache)?;
let control_flow = visit(prev_conditions, self, dead_end_path_cache)?;
match control_flow {
ControlFlow::Continue(_) => {}
ControlFlow::Break(_) => return Ok(true),
@ -124,7 +124,7 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
edge.dest_node,
cost - edge.cost as u16,
all_distances,
empty_paths_cache,
dead_end_path_cache,
visit,
prev_conditions,
cur_path,
@ -139,15 +139,15 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
any_valid |= next_any_valid;
if next_any_valid {
if empty_paths_cache.path_is_dead_end(prev_conditions, cur_path) {
if dead_end_path_cache.path_is_dead_end(prev_conditions, cur_path) {
return Ok(any_valid);
}
forbidden_conditions.union(&empty_paths_cache.conditions);
forbidden_conditions.union(&dead_end_path_cache.conditions);
for prev_condition in prev_conditions.iter() {
forbidden_conditions
.union(empty_paths_cache.condition_couples.get(*prev_condition));
.union(dead_end_path_cache.condition_couples.get(*prev_condition));
}
empty_paths_cache.prefixes.final_edges_after_prefix(prev_conditions, &mut |x| {
dead_end_path_cache.prefixes.final_edges_after_prefix(prev_conditions, &mut |x| {
forbidden_conditions.insert(x);
});
}
@ -178,16 +178,14 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
let cur_node_edges = &self.edges_of_node.get(cur_node);
for edge_idx in cur_node_edges.iter() {
let edge = self.edges_store.get(edge_idx).as_ref().unwrap();
let condition = match edge.condition {
EdgeCondition::Unconditional => None,
EdgeCondition::Conditional(condition) => Some(condition),
};
let succ_node = edge.dest_node;
let succ_distances = distances_to_end.get(succ_node);
for (succ_distance, succ_necessary_conditions) in succ_distances {
let mut potential_necessary_edges =
SmallBitmap::for_interned_values_in(&self.conditions_interner);
for condition in condition.into_iter().chain(succ_necessary_conditions.iter()) {
for condition in
edge.condition.into_iter().chain(succ_necessary_conditions.iter())
{
potential_necessary_edges.insert(condition);
}

View File

@ -9,44 +9,43 @@ use crate::search::new::SearchContext;
use crate::Result;
/// A cache storing the document ids associated with each ranking rule edge
pub struct EdgeConditionDocIdsCache<G: RankingRuleGraphTrait> {
pub struct ConditionDocIdsCache<G: RankingRuleGraphTrait> {
// TODO: should be FxHashMap<Interned<EdgeCondition>, RoaringBitmap>
pub cache: FxHashMap<Interned<G::EdgeCondition>, RoaringBitmap>,
pub cache: FxHashMap<Interned<G::Condition>, RoaringBitmap>,
_phantom: PhantomData<G>,
}
impl<G: RankingRuleGraphTrait> Default for EdgeConditionDocIdsCache<G> {
impl<G: RankingRuleGraphTrait> Default for ConditionDocIdsCache<G> {
fn default() -> Self {
Self { cache: Default::default(), _phantom: Default::default() }
}
}
impl<G: RankingRuleGraphTrait> EdgeConditionDocIdsCache<G> {
impl<G: RankingRuleGraphTrait> ConditionDocIdsCache<G> {
/// Retrieve the document ids for the given edge condition.
///
/// If the cache does not yet contain these docids, they are computed
/// and inserted in the cache.
pub fn get_edge_docids<'s, 'ctx>(
pub fn get_condition_docids<'s, 'ctx>(
&'s mut self,
ctx: &mut SearchContext<'ctx>,
// TODO: should be Interned<EdgeCondition>
interned_edge_condition: Interned<G::EdgeCondition>,
interned_condition: Interned<G::Condition>,
graph: &RankingRuleGraph<G>,
// TODO: maybe universe doesn't belong here
universe: &RoaringBitmap,
) -> Result<&'s RoaringBitmap> {
if self.cache.contains_key(&interned_edge_condition) {
if self.cache.contains_key(&interned_condition) {
// TODO: should we update the bitmap in the cache if the new universe
// reduces it?
// TODO: maybe have a generation: u32 to track every time the universe was
// reduced. Then only attempt to recompute the intersection when there is a chance
// that edge_docids & universe changed
return Ok(&self.cache[&interned_edge_condition]);
// that condition_docids & universe changed
return Ok(&self.cache[&interned_condition]);
}
// TODO: maybe universe doesn't belong here
let edge_condition = graph.conditions_interner.get(interned_edge_condition);
let condition = graph.conditions_interner.get(interned_condition);
// TODO: faster way to do this?
let docids = universe & G::resolve_edge_condition(ctx, edge_condition, universe)?;
let _ = self.cache.insert(interned_edge_condition, docids);
let docids = &self.cache[&interned_edge_condition];
let docids = universe & G::resolve_condition(ctx, condition, universe)?;
let _ = self.cache.insert(interned_condition, docids);
let docids = &self.cache[&interned_condition];
Ok(docids)
}
}

View File

@ -9,11 +9,11 @@ use crate::search::new::{
/// universe.
pub struct DeadEndPathCache<G: RankingRuleGraphTrait> {
/// The set of edge conditions that resolve to no documents.
pub conditions: SmallBitmap<G::EdgeCondition>,
pub conditions: SmallBitmap<G::Condition>,
/// A set of path prefixes that resolve to no documents.
pub prefixes: PathSet<G::EdgeCondition>,
pub prefixes: PathSet<G::Condition>,
/// A set of empty couples of edge conditions that resolve to no documents.
pub condition_couples: MappedInterner<SmallBitmap<G::EdgeCondition>, G::EdgeCondition>,
pub condition_couples: MappedInterner<SmallBitmap<G::Condition>, G::Condition>,
}
impl<G: RankingRuleGraphTrait> Clone for DeadEndPathCache<G> {
fn clone(&self) -> Self {
@ -27,17 +27,17 @@ impl<G: RankingRuleGraphTrait> Clone for DeadEndPathCache<G> {
impl<G: RankingRuleGraphTrait> DeadEndPathCache<G> {
/// Create a new cache for a ranking rule graph containing at most `all_edges_len` edges.
pub fn new(all_edge_conditions: &FixedSizeInterner<G::EdgeCondition>) -> Self {
pub fn new(all_conditions: &FixedSizeInterner<G::Condition>) -> Self {
Self {
conditions: SmallBitmap::for_interned_values_in(all_edge_conditions),
conditions: SmallBitmap::for_interned_values_in(all_conditions),
prefixes: PathSet::default(),
condition_couples: all_edge_conditions
.map(|_| SmallBitmap::for_interned_values_in(all_edge_conditions)),
condition_couples: all_conditions
.map(|_| SmallBitmap::for_interned_values_in(all_conditions)),
}
}
/// Store in the cache that every path containing the given edge resolves to no documents.
pub fn add_condition(&mut self, condition: Interned<G::EdgeCondition>) {
pub fn add_condition(&mut self, condition: Interned<G::Condition>) {
self.conditions.insert(condition);
self.condition_couples.get_mut(condition).clear();
self.prefixes.remove_edge(condition);
@ -46,7 +46,7 @@ impl<G: RankingRuleGraphTrait> DeadEndPathCache<G> {
}
}
/// Store in the cache that every path containing the given prefix resolves to no documents.
pub fn add_prefix(&mut self, prefix: &[Interned<G::EdgeCondition>]) {
pub fn add_prefix(&mut self, prefix: &[Interned<G::Condition>]) {
// TODO: typed PathSet
self.prefixes.insert(prefix.iter().copied());
}
@ -54,8 +54,8 @@ impl<G: RankingRuleGraphTrait> DeadEndPathCache<G> {
/// Store in the cache that every path containing the two given edges resolves to no documents.
pub fn add_condition_couple(
&mut self,
edge1: Interned<G::EdgeCondition>,
edge2: Interned<G::EdgeCondition>,
edge1: Interned<G::Condition>,
edge2: Interned<G::Condition>,
) {
self.condition_couples.get_mut(edge1).insert(edge2);
}
@ -63,8 +63,8 @@ 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: &[Interned<G::EdgeCondition>],
path_bitmap: &SmallBitmap<G::EdgeCondition>,
path: &[Interned<G::Condition>],
path_bitmap: &SmallBitmap<G::Condition>,
) -> bool {
if path_bitmap.intersects(&self.conditions) {
return true;

View File

@ -7,8 +7,8 @@ the same but the edges are replaced.
mod build;
mod cheapest_paths;
mod edge_docids_cache;
mod empty_paths_cache;
mod condition_docids_cache;
mod dead_end_path_cache;
mod path_set;
/// Implementation of the `proximity` ranking rule
@ -19,8 +19,8 @@ mod typo;
use std::collections::HashSet;
use std::hash::Hash;
pub use edge_docids_cache::EdgeConditionDocIdsCache;
pub use empty_paths_cache::DeadEndPathCache;
pub use condition_docids_cache::EdgeConditionDocIdsCache;
pub use dead_end_path_cache::DeadEndPathCache;
pub use proximity::{ProximityCondition, ProximityGraph};
use roaring::RoaringBitmap;
pub use typo::{TypoEdge, TypoGraph};
@ -32,31 +32,6 @@ use super::small_bitmap::SmallBitmap;
use super::{QueryGraph, QueryNode, SearchContext};
use crate::Result;
/// The condition that is associated with an edge in the ranking rule graph.
///
/// Some edges are unconditional, which means that traversing them does not reduce
/// the set of candidates.
///
/// Most edges, however, have a condition attached to them. For example, for the
/// proximity ranking rule, the condition could be that a word is N-close to another one.
/// When the edge is traversed, some database operations are executed to retrieve the set
/// of documents that satisfy the condition, which reduces the list of candidate document ids.
pub enum EdgeCondition<E> {
Unconditional,
Conditional(Interned<E>),
}
impl<E> Copy for EdgeCondition<E> {}
impl<E> Clone for EdgeCondition<E> {
fn clone(&self) -> Self {
match self {
Self::Unconditional => Self::Unconditional,
Self::Conditional(arg0) => Self::Conditional(*arg0),
}
}
}
/// An edge in the ranking rule graph.
///
/// It contains:
@ -68,7 +43,27 @@ pub struct Edge<E> {
pub source_node: Interned<QueryNode>,
pub dest_node: Interned<QueryNode>,
pub cost: u8,
pub condition: EdgeCondition<E>,
pub condition: Option<Interned<E>>,
}
impl<E> Hash for Edge<E> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.source_node.hash(state);
self.dest_node.hash(state);
self.cost.hash(state);
self.condition.hash(state);
}
}
impl<E> Eq for Edge<E> {}
impl<E> PartialEq for Edge<E> {
fn eq(&self, other: &Self) -> bool {
self.source_node == other.source_node
&& self.dest_node == other.dest_node
&& self.cost == other.cost
&& self.condition == other.condition
}
}
/// A trait to be implemented by a marker type to build a graph-based ranking rule.
@ -113,12 +108,12 @@ pub trait RankingRuleGraphTrait: Sized {
conditions_interner: &mut DedupInterner<Self::EdgeCondition>,
source_node: &QueryNode,
dest_node: &QueryNode,
) -> Result<Vec<(u8, EdgeCondition<Self::EdgeCondition>)>>;
) -> Result<Vec<(u8, Option<Interned<Self::EdgeCondition>>)>>;
fn log_state(
graph: &RankingRuleGraph<Self>,
paths: &[Vec<Interned<Self::EdgeCondition>>],
empty_paths_cache: &DeadEndPathCache<Self>,
dead_end_path_cache: &DeadEndPathCache<Self>,
universe: &RoaringBitmap,
distances: &MappedInterner<Vec<(u16, SmallBitmap<Self::EdgeCondition>)>, QueryNode>,
cost: u16,
@ -151,15 +146,12 @@ impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
pub fn remove_edges_with_condition(&mut self, condition_to_remove: Interned<G::EdgeCondition>) {
for (edge_id, edge_opt) in self.edges_store.iter_mut() {
let Some(edge) = edge_opt.as_mut() else { continue };
match edge.condition {
EdgeCondition::Unconditional => continue,
EdgeCondition::Conditional(condition) => {
if condition == condition_to_remove {
let (source_node, _dest_node) = (edge.source_node, edge.dest_node);
*edge_opt = None;
self.edges_of_node.get_mut(source_node).remove(edge_id);
}
}
let Some(condition) = edge.condition else { continue };
if condition == condition_to_remove {
let (source_node, _dest_node) = (edge.source_node, edge.dest_node);
*edge_opt = None;
self.edges_of_node.get_mut(source_node).remove(edge_id);
}
}
}

View File

@ -4,7 +4,7 @@
use crate::search::new::interner::Interned;
/// A set of [`Path`]
/// A set of `Vec<Interned<T>>`.
pub struct PathSet<T> {
nodes: Vec<(Interned<T>, Self)>,
is_end: bool,

View File

@ -7,7 +7,6 @@ use crate::search::new::interner::{DedupInterner, Interned};
use crate::search::new::query_graph::QueryNodeData;
use crate::search::new::query_term::{LocatedQueryTerm, Phrase, QueryTerm};
use crate::search::new::ranking_rule_graph::proximity::WordPair;
use crate::search::new::ranking_rule_graph::EdgeCondition;
use crate::search::new::{QueryNode, SearchContext};
use crate::Result;
use heed::RoTxn;
@ -40,7 +39,7 @@ pub fn build_edges<'ctx>(
conditions_interner: &mut DedupInterner<ProximityCondition>,
from_node: &QueryNode,
to_node: &QueryNode,
) -> Result<Vec<(u8, EdgeCondition<ProximityCondition>)>> {
) -> Result<Vec<(u8, Option<Interned<ProximityCondition>>)>> {
let SearchContext {
index,
txn,
@ -52,7 +51,7 @@ pub fn build_edges<'ctx>(
} = ctx;
let right_term = match &to_node.data {
QueryNodeData::End => return Ok(vec![(0, EdgeCondition::Unconditional)]),
QueryNodeData::End => return Ok(vec![(0, None)]),
QueryNodeData::Deleted | QueryNodeData::Start => return Ok(vec![]),
QueryNodeData::Term(term) => term,
};
@ -70,7 +69,7 @@ pub fn build_edges<'ctx>(
QueryNodeData::Start => {
return Ok(vec![(
(right_ngram_length - 1) as u8,
EdgeCondition::Conditional(
Some(
conditions_interner
.insert(ProximityCondition::Term { term: *right_term_interned }),
),
@ -88,7 +87,7 @@ pub fn build_edges<'ctx>(
// but `sun` and `are` have no proximity condition between them
return Ok(vec![(
(right_ngram_length - 1) as u8,
EdgeCondition::Conditional(
Some(
conditions_interner.insert(ProximityCondition::Term { term: *right_term_interned }),
),
)]);
@ -140,7 +139,7 @@ pub fn build_edges<'ctx>(
.map(|(cost, word_pairs)| {
(
cost,
EdgeCondition::Conditional(
Some(
conditions_interner
.insert(ProximityCondition::Pairs { pairs: word_pairs.into_boxed_slice() }),
),
@ -149,9 +148,7 @@ pub fn build_edges<'ctx>(
.collect::<Vec<_>>();
new_edges.push((
8 + (right_ngram_length - 1) as u8,
EdgeCondition::Conditional(
conditions_interner.insert(ProximityCondition::Term { term: *right_term_interned }),
),
Some(conditions_interner.insert(ProximityCondition::Term { term: *right_term_interned })),
));
Ok(new_edges)
}

View File

@ -6,8 +6,8 @@ use std::iter::FromIterator;
use roaring::RoaringBitmap;
use super::empty_paths_cache::DeadEndPathCache;
use super::{EdgeCondition, RankingRuleGraph, RankingRuleGraphTrait};
use super::dead_end_path_cache::DeadEndPathCache;
use super::{RankingRuleGraph, RankingRuleGraphTrait};
use crate::search::new::interner::{DedupInterner, Interned, MappedInterner};
use crate::search::new::logger::SearchLogger;
use crate::search::new::query_term::{Phrase, QueryTerm};
@ -60,20 +60,20 @@ impl RankingRuleGraphTrait for ProximityGraph {
conditions_interner: &mut DedupInterner<Self::EdgeCondition>,
source_node: &QueryNode,
dest_node: &QueryNode,
) -> Result<Vec<(u8, EdgeCondition<Self::EdgeCondition>)>> {
) -> Result<Vec<(u8, Option<Interned<Self::EdgeCondition>>)>> {
build::build_edges(ctx, conditions_interner, source_node, dest_node)
}
fn log_state(
graph: &RankingRuleGraph<Self>,
paths: &[Vec<Interned<ProximityCondition>>],
empty_paths_cache: &DeadEndPathCache<Self>,
dead_end_path_cache: &DeadEndPathCache<Self>,
universe: &RoaringBitmap,
distances: &MappedInterner<Vec<(u16, SmallBitmap<ProximityCondition>)>, QueryNode>,
cost: u16,
logger: &mut dyn SearchLogger<QueryGraph>,
) {
logger.log_proximity_state(graph, paths, empty_paths_cache, universe, distances, cost);
logger.log_proximity_state(graph, paths, dead_end_path_cache, universe, distances, cost);
}
fn label_for_edge_condition<'ctx>(

View File

@ -1,7 +1,7 @@
use roaring::RoaringBitmap;
use super::empty_paths_cache::DeadEndPathCache;
use super::{EdgeCondition, RankingRuleGraph, RankingRuleGraphTrait};
use super::dead_end_path_cache::DeadEndPathCache;
use super::{RankingRuleGraph, RankingRuleGraphTrait};
use crate::search::new::interner::{DedupInterner, Interned, MappedInterner};
use crate::search::new::logger::SearchLogger;
use crate::search::new::query_graph::QueryNodeData;
@ -58,7 +58,7 @@ impl RankingRuleGraphTrait for TypoGraph {
conditions_interner: &mut DedupInterner<Self::EdgeCondition>,
_from_node: &QueryNode,
to_node: &QueryNode,
) -> Result<Vec<(u8, EdgeCondition<Self::EdgeCondition>)>> {
) -> Result<Vec<(u8, Option<Interned<Self::EdgeCondition>>)>> {
let SearchContext { term_interner, .. } = ctx;
match &to_node.data {
QueryNodeData::Term(LocatedQueryTerm { value, positions }) => {
@ -121,7 +121,7 @@ impl RankingRuleGraphTrait for TypoGraph {
if !new_term.is_empty() {
edges.push((
nbr_typos as u8 + base_cost,
EdgeCondition::Conditional(conditions_interner.insert(TypoEdge {
Some(conditions_interner.insert(TypoEdge {
term: term_interner.insert(new_term),
nbr_typos: nbr_typos as u8,
})),
@ -130,7 +130,7 @@ impl RankingRuleGraphTrait for TypoGraph {
}
Ok(edges)
}
QueryNodeData::End => Ok(vec![(0, EdgeCondition::Unconditional)]),
QueryNodeData::End => Ok(vec![(0, None)]),
QueryNodeData::Deleted | QueryNodeData::Start => panic!(),
}
}
@ -138,13 +138,13 @@ impl RankingRuleGraphTrait for TypoGraph {
fn log_state(
graph: &RankingRuleGraph<Self>,
paths: &[Vec<Interned<TypoEdge>>],
empty_paths_cache: &DeadEndPathCache<Self>,
dead_end_path_cache: &DeadEndPathCache<Self>,
universe: &RoaringBitmap,
distances: &MappedInterner<Vec<(u16, SmallBitmap<TypoEdge>)>, QueryNode>,
cost: u16,
logger: &mut dyn SearchLogger<QueryGraph>,
) {
logger.log_typo_state(graph, paths, empty_paths_cache, universe, distances, cost);
logger.log_typo_state(graph, paths, dead_end_path_cache, universe, distances, cost);
}
fn label_for_edge_condition<'ctx>(