use std::collections::HashMap;
const MAX_TRACKED_FIELDS: usize = 1024;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OrderByIndexState {
Missing,
BuiltButUncovered,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OrderByIndexSuggestion {
pub field: String,
pub observed_count: u64,
pub state: OrderByIndexState,
}
#[derive(Debug, Default)]
pub struct OrderByIndexAdvisor {
observations: HashMap<String, u64>,
}
impl OrderByIndexAdvisor {
pub(crate) fn observe(&mut self, field: &str) {
if let Some(count) = self.observations.get_mut(field) {
*count = count.saturating_add(1);
} else if self.observations.len() < MAX_TRACKED_FIELDS {
self.observations.insert(field.to_owned(), 1);
}
}
pub(crate) fn observed(&self, min_observations: u64) -> Vec<(String, u64)> {
let mut out: Vec<(String, u64)> = self
.observations
.iter()
.filter(|&(_, &count)| count >= min_observations)
.map(|(field, &count)| (field.clone(), count))
.collect();
out.sort_by(|a, b| b.1.cmp(&a.1).then_with(|| a.0.cmp(&b.0)));
out
}
}