use std::collections::{HashMap, HashSet};
use std::time::{Duration, Instant};
use crate::algebra::{TriplePattern, Variable};
use crate::optimizer::IndexType;
#[derive(Clone)]
pub struct IndexAdvisor {
#[allow(dead_code)]
query_patterns: HashMap<String, QueryPattern>,
index_usage_stats: HashMap<IndexType, IndexUsageStats>,
recommended_indexes: Vec<IndexRecommendation>,
}
#[derive(Debug, Clone)]
pub struct QueryPattern {
pub pattern_hash: u64,
pub triple_patterns: Vec<TriplePattern>,
pub join_variables: HashSet<Variable>,
pub filter_variables: HashSet<Variable>,
pub frequency: usize,
pub avg_execution_time: Duration,
pub avg_cardinality: usize,
}
#[derive(Debug, Clone, Default)]
pub struct IndexUsageStats {
pub access_count: usize,
pub total_access_time: Duration,
pub avg_selectivity: f64,
pub memory_usage: usize,
pub last_updated: Option<Instant>,
}
#[derive(Debug, Clone)]
pub struct IndexRecommendation {
pub index_type: IndexType,
pub priority: IndexPriority,
pub estimated_benefit: f64,
pub estimated_cost: f64,
pub supporting_patterns: Vec<String>,
pub confidence: f64,
}
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub enum IndexPriority {
Critical = 4,
High = 3,
Medium = 2,
Low = 1,
}
impl IndexAdvisor {
pub fn new() -> Self {
Self {
query_patterns: HashMap::new(),
index_usage_stats: HashMap::new(),
recommended_indexes: Vec::new(),
}
}
pub fn analyze_query_pattern(&mut self, _patterns: &[TriplePattern]) -> anyhow::Result<()> {
Ok(())
}
pub fn get_recommendations(&self) -> &[IndexRecommendation] {
&self.recommended_indexes
}
pub fn update_index_usage(
&mut self,
index_type: IndexType,
access_time: Duration,
selectivity: f64,
) {
let stats = self.index_usage_stats.entry(index_type).or_default();
stats.access_count += 1;
stats.total_access_time += access_time;
stats.avg_selectivity = (stats.avg_selectivity * (stats.access_count - 1) as f64
+ selectivity)
/ stats.access_count as f64;
stats.last_updated = Some(Instant::now());
}
pub fn recommendations_count(&self) -> usize {
self.recommended_indexes.len()
}
}
impl Default for IndexAdvisor {
fn default() -> Self {
Self::new()
}
}