2023-03-07 14:42:58 +01:00
|
|
|
use std::collections::HashSet;
|
|
|
|
|
2023-02-21 09:46:00 +01:00
|
|
|
use super::{Edge, RankingRuleGraph, RankingRuleGraphTrait};
|
2023-03-13 12:46:32 +01:00
|
|
|
use crate::search::new::interner::Interner;
|
2023-03-08 09:55:53 +01:00
|
|
|
use crate::search::new::small_bitmap::SmallBitmap;
|
|
|
|
use crate::search::new::{QueryGraph, SearchContext};
|
2023-03-06 19:21:55 +01:00
|
|
|
use crate::Result;
|
2023-02-21 09:46:00 +01:00
|
|
|
|
|
|
|
impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
|
2023-03-13 14:03:48 +01:00
|
|
|
// TODO: here, the docids of all the edges should already be computed!
|
|
|
|
// an edge condition would then be reduced to a (ptr to) a roaring bitmap?
|
|
|
|
// we could build fewer of them by directly comparing them with the universe
|
|
|
|
// (e.g. for each word pairs?) with `deserialize_within_universe` maybe
|
|
|
|
//
|
|
|
|
|
2023-03-08 15:04:25 +01:00
|
|
|
/// Build the ranking rule graph from the given query graph
|
2023-03-06 19:21:55 +01:00
|
|
|
pub fn build(ctx: &mut SearchContext, query_graph: QueryGraph) -> Result<Self> {
|
2023-03-07 14:42:58 +01:00
|
|
|
let QueryGraph { nodes: graph_nodes, edges: graph_edges, .. } = &query_graph;
|
|
|
|
|
2023-03-13 12:46:32 +01:00
|
|
|
let mut conditions_interner = Interner::default();
|
|
|
|
|
2023-03-08 15:04:25 +01:00
|
|
|
let mut edges_store = vec![];
|
|
|
|
let mut edges_of_node = vec![];
|
2023-02-21 09:46:00 +01:00
|
|
|
|
2023-03-07 14:42:58 +01:00
|
|
|
for (node_idx, node) in graph_nodes.iter().enumerate() {
|
2023-03-08 15:04:25 +01:00
|
|
|
edges_of_node.push(HashSet::new());
|
|
|
|
let new_edges = edges_of_node.last_mut().unwrap();
|
2023-02-21 09:46:00 +01:00
|
|
|
|
2023-03-08 15:04:25 +01:00
|
|
|
let Some(source_node_data) = G::build_step_visit_source_node(ctx, node)? else { continue };
|
2023-02-21 09:46:00 +01:00
|
|
|
|
2023-03-07 14:42:58 +01:00
|
|
|
for successor_idx in graph_edges[node_idx].successors.iter() {
|
2023-03-08 15:04:25 +01:00
|
|
|
let dest_node = &graph_nodes[successor_idx as usize];
|
2023-03-13 12:46:32 +01:00
|
|
|
let edges = G::build_step_visit_destination_node(
|
|
|
|
ctx,
|
|
|
|
&mut conditions_interner,
|
|
|
|
dest_node,
|
|
|
|
&source_node_data,
|
|
|
|
)?;
|
2023-02-21 12:33:32 +01:00
|
|
|
if edges.is_empty() {
|
|
|
|
continue;
|
|
|
|
}
|
2023-03-08 15:04:25 +01:00
|
|
|
|
2023-03-13 12:46:32 +01:00
|
|
|
for (cost, condition) in edges {
|
2023-03-08 15:04:25 +01:00
|
|
|
edges_store.push(Some(Edge {
|
|
|
|
source_node: node_idx as u16,
|
|
|
|
dest_node: successor_idx,
|
2023-02-21 09:46:00 +01:00
|
|
|
cost,
|
2023-03-13 12:46:32 +01:00
|
|
|
condition,
|
2023-02-21 09:46:00 +01:00
|
|
|
}));
|
2023-03-08 15:04:25 +01:00
|
|
|
new_edges.insert(edges_store.len() as u16 - 1);
|
2023-02-21 09:46:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-03-08 15:04:25 +01:00
|
|
|
let edges_of_node = edges_of_node
|
2023-03-07 14:42:58 +01:00
|
|
|
.into_iter()
|
2023-03-08 15:04:25 +01:00
|
|
|
.map(|edges| SmallBitmap::from_iter(edges.into_iter(), edges_store.len() as u16))
|
2023-03-07 14:42:58 +01:00
|
|
|
.collect();
|
|
|
|
|
2023-03-13 12:46:32 +01:00
|
|
|
Ok(RankingRuleGraph { query_graph, edges_store, edges_of_node, conditions_interner })
|
2023-02-21 09:46:00 +01:00
|
|
|
}
|
|
|
|
}
|