use std::collections::{BTreeMap, BTreeSet};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct JoinCost {
pub cardinality: usize,
pub operations: u64,
}
impl JoinCost {
pub fn new(cardinality: usize, operations: u64) -> Self {
Self { cardinality, operations }
}
pub fn total(&self) -> u64 {
(self.cardinality as u64).saturating_mul(1000).saturating_add(self.operations)
}
}
#[derive(Debug, Clone, Default)]
pub struct CascadingFilterState {
pub filtered_tables: BTreeMap<String, f64>,
pub correlation_factor: f64,
}
impl CascadingFilterState {
pub fn new() -> Self {
Self { filtered_tables: BTreeMap::new(), correlation_factor: 1.0 }
}
pub fn add_filtered_table(&mut self, table: String, selectivity: f64) {
self.filtered_tables.insert(table, selectivity);
}
pub fn is_filtered(&self, table: &str) -> bool {
self.filtered_tables.contains_key(table)
}
pub fn get_table_selectivity(&self, table: &str) -> f64 {
self.filtered_tables.get(table).copied().unwrap_or(1.0)
}
pub fn apply_correlation_for_join(&mut self, joined_tables: &BTreeSet<String>) {
let filtered_count = joined_tables.iter().filter(|t| self.is_filtered(t)).count();
if filtered_count > 0 {
self.correlation_factor *= 0.85_f64.powi(filtered_count as i32);
}
}
}
#[derive(Debug, Clone)]
pub(super) struct SearchState {
pub joined_tables: BTreeSet<String>,
pub cost_so_far: JoinCost,
pub order: Vec<String>,
pub current_cardinality: usize,
pub filter_state: CascadingFilterState,
}