use roaring::RoaringBitmap;
pub fn local_selectivity_at(node_neighbors: &[u32], allowed: &RoaringBitmap) -> f32 {
if node_neighbors.is_empty() {
return 0.0;
}
let matched = node_neighbors
.iter()
.filter(|&&n| allowed.contains(n))
.count();
matched as f32 / node_neighbors.len() as f32
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum NavixHeuristic {
Standard,
Directed,
Blind,
}
pub fn pick_heuristic(local_selectivity: f32) -> NavixHeuristic {
if local_selectivity > 0.50 {
NavixHeuristic::Standard
} else if local_selectivity >= 0.01 {
NavixHeuristic::Directed
} else {
NavixHeuristic::Blind
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn heuristic_zero() {
assert_eq!(pick_heuristic(0.0), NavixHeuristic::Blind);
}
#[test]
fn heuristic_below_directed_threshold() {
assert_eq!(pick_heuristic(0.005), NavixHeuristic::Blind);
}
#[test]
fn heuristic_at_directed_lower_boundary() {
assert_eq!(pick_heuristic(0.01), NavixHeuristic::Directed);
}
#[test]
fn heuristic_mid_directed() {
assert_eq!(pick_heuristic(0.30), NavixHeuristic::Directed);
}
#[test]
fn heuristic_at_standard_lower_boundary() {
assert_eq!(pick_heuristic(0.50), NavixHeuristic::Directed);
}
#[test]
fn heuristic_just_above_standard_boundary() {
assert_eq!(pick_heuristic(0.51), NavixHeuristic::Standard);
}
#[test]
fn heuristic_full_selectivity() {
assert_eq!(pick_heuristic(1.0), NavixHeuristic::Standard);
}
#[test]
fn empty_neighbors_returns_zero() {
let allowed = RoaringBitmap::new();
assert_eq!(local_selectivity_at(&[], &allowed), 0.0);
}
#[test]
fn all_matching_returns_one() {
let mut allowed = RoaringBitmap::new();
allowed.insert(0);
allowed.insert(1);
allowed.insert(2);
let neighbors = [0u32, 1, 2];
assert!((local_selectivity_at(&neighbors, &allowed) - 1.0).abs() < 1e-6);
}
#[test]
fn half_matching_returns_half() {
let mut allowed = RoaringBitmap::new();
allowed.insert(0);
allowed.insert(2);
let neighbors = [0u32, 1, 2, 3];
assert!((local_selectivity_at(&neighbors, &allowed) - 0.5).abs() < 1e-6);
}
#[test]
fn none_matching_returns_zero() {
let allowed = RoaringBitmap::new();
let neighbors = [0u32, 1, 2, 3];
assert_eq!(local_selectivity_at(&neighbors, &allowed), 0.0);
}
}