2023-03-07 21:42:58 +08:00
|
|
|
use std::collections::HashSet;
|
|
|
|
|
2023-02-21 16:46:00 +08:00
|
|
|
use super::{Edge, RankingRuleGraph, RankingRuleGraphTrait};
|
2023-03-16 18:52:51 +08:00
|
|
|
use crate::search::new::interner::DedupInterner;
|
2023-03-08 16:55:53 +08:00
|
|
|
use crate::search::new::small_bitmap::SmallBitmap;
|
|
|
|
use crate::search::new::{QueryGraph, SearchContext};
|
2023-03-07 02:21:55 +08:00
|
|
|
use crate::Result;
|
2023-02-21 16:46:00 +08:00
|
|
|
|
|
|
|
impl<G: RankingRuleGraphTrait> RankingRuleGraph<G> {
|
2023-03-13 21:03:48 +08: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 22:04:25 +08:00
|
|
|
/// Build the ranking rule graph from the given query graph
|
2023-03-07 02:21:55 +08:00
|
|
|
pub fn build(ctx: &mut SearchContext, query_graph: QueryGraph) -> Result<Self> {
|
2023-03-14 23:37:47 +08:00
|
|
|
let QueryGraph { nodes: graph_nodes, .. } = &query_graph;
|
2023-03-07 21:42:58 +08:00
|
|
|
|
2023-03-14 23:37:47 +08:00
|
|
|
let mut conditions_interner = DedupInterner::default();
|
2023-03-13 19:46:32 +08:00
|
|
|
|
2023-03-16 18:52:51 +08:00
|
|
|
let mut edges_store = DedupInterner::default();
|
2023-03-14 23:37:47 +08:00
|
|
|
let mut edges_of_node = query_graph.nodes.map(|_| HashSet::new());
|
2023-02-21 16:46:00 +08:00
|
|
|
|
2023-03-14 23:37:47 +08:00
|
|
|
for (source_id, source_node) in graph_nodes.iter() {
|
|
|
|
let new_edges = edges_of_node.get_mut(source_id);
|
2023-02-21 16:46:00 +08:00
|
|
|
|
2023-03-14 23:37:47 +08:00
|
|
|
for dest_idx in source_node.successors.iter() {
|
|
|
|
let dest_node = graph_nodes.get(dest_idx);
|
2023-03-14 17:54:55 +08:00
|
|
|
let edges = G::build_edges(ctx, &mut conditions_interner, source_node, dest_node)?;
|
2023-02-21 19:33:32 +08:00
|
|
|
if edges.is_empty() {
|
|
|
|
continue;
|
|
|
|
}
|
2023-03-08 22:04:25 +08:00
|
|
|
|
2023-03-13 19:46:32 +08:00
|
|
|
for (cost, condition) in edges {
|
2023-03-16 18:52:51 +08:00
|
|
|
let new_edge_id = edges_store.insert(Some(Edge {
|
2023-03-14 23:37:47 +08:00
|
|
|
source_node: source_id,
|
2023-03-14 17:54:55 +08:00
|
|
|
dest_node: dest_idx,
|
2023-02-21 16:46:00 +08:00
|
|
|
cost,
|
2023-03-13 19:46:32 +08:00
|
|
|
condition,
|
2023-02-21 16:46:00 +08:00
|
|
|
}));
|
2023-03-14 23:37:47 +08:00
|
|
|
new_edges.insert(new_edge_id);
|
2023-02-21 16:46:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-03-14 23:37:47 +08:00
|
|
|
let edges_store = edges_store.freeze();
|
|
|
|
let edges_of_node =
|
|
|
|
edges_of_node.map(|edges| SmallBitmap::from_iter(edges.iter().copied(), &edges_store));
|
|
|
|
|
|
|
|
Ok(RankingRuleGraph {
|
|
|
|
query_graph,
|
|
|
|
edges_store,
|
|
|
|
edges_of_node,
|
|
|
|
conditions_interner: conditions_interner.freeze(),
|
|
|
|
})
|
2023-02-21 16:46:00 +08:00
|
|
|
}
|
|
|
|
}
|