use super::helpers;
use rapidhash::{HashMapExt, RapidHashMap, RapidHashSet};
use serde_json::Value;
#[derive(Debug, Clone, Default)]
pub struct TableIndex {
columns: RapidHashMap<String, RapidHashMap<String, RapidHashSet<usize>>>,
row_count: usize,
}
impl TableIndex {
pub fn new(data: &Value) -> Option<Self> {
let arr = data.as_array()?;
if arr.is_empty() {
return None;
}
if !arr.iter().any(|v| v.is_object()) {
return None;
}
let row_count = arr.len();
let mut columns: RapidHashMap<String, RapidHashMap<String, RapidHashSet<usize>>> =
RapidHashMap::new();
for (row_idx, row) in arr.iter().enumerate() {
if let Value::Object(obj) = row {
for (col_name, val) in obj {
if let Some(key) = helpers::scalar_hash_key(val) {
let col_index = columns.entry(col_name.clone()).or_default();
col_index.entry(key).or_default().insert(row_idx);
}
}
}
}
Some(Self { columns, row_count })
}
pub fn lookup(&self, col_name: &str, value: &Value) -> Option<&RapidHashSet<usize>> {
let col_index = self.columns.get(col_name)?;
let key = helpers::scalar_hash_key(value)?;
col_index.get(&key)
}
pub fn has_column(&self, col_name: &str) -> bool {
self.columns.contains_key(col_name)
}
pub fn len(&self) -> usize {
self.row_count
}
pub fn is_empty(&self) -> bool {
self.row_count == 0
}
}