use vibesql_types::SqlValue;
use crate::database::indexes::index_metadata::{acquire_btree_lock, IndexData};
impl IndexData {
pub fn get_distinct_prefix_values(&self, num_columns: usize) -> Vec<Vec<SqlValue>> {
if num_columns == 0 {
return vec![vec![]]; }
match self {
IndexData::InMemory { data, .. } => {
let mut prefixes = Vec::new();
let mut last_prefix: Option<Vec<SqlValue>> = None;
for key in data.keys() {
if key.len() < num_columns {
continue; }
let prefix: Vec<SqlValue> = key[..num_columns].to_vec();
let is_new = match &last_prefix {
None => true,
Some(last) => prefix != *last,
};
if is_new {
prefixes.push(prefix.clone());
last_prefix = Some(prefix);
}
}
prefixes
}
IndexData::DiskBacked { btree, .. } => {
match acquire_btree_lock(btree) {
Ok(guard) => {
guard.get_distinct_prefix_values(num_columns).unwrap_or_else(|_| vec![])
}
Err(e) => {
log::warn!(
"BTreeIndex lock acquisition failed in get_distinct_prefix_values: {}",
e
);
vec![]
}
}
}
IndexData::IVFFlat { .. } | IndexData::Hnsw { .. } => {
vec![]
}
}
}
pub fn get_distinct_first_column_values(&self) -> Vec<SqlValue> {
match self {
IndexData::InMemory { data, .. } => {
let mut distinct_values = Vec::new();
let mut last_first_col: Option<SqlValue> = None;
for key in data.keys() {
if let Some(first_val) = key.first() {
let is_new = match &last_first_col {
None => true,
Some(last) => first_val != last,
};
if is_new {
distinct_values.push(first_val.clone());
last_first_col = Some(first_val.clone());
}
}
}
distinct_values
}
IndexData::DiskBacked { btree, .. } => {
match acquire_btree_lock(btree) {
Ok(guard) => {
guard.get_distinct_first_column_values().unwrap_or_else(|_| vec![])
}
Err(e) => {
log::warn!(
"BTreeIndex lock acquisition failed in get_distinct_first_column_values: {}",
e
);
vec![]
}
}
}
IndexData::IVFFlat { .. } | IndexData::Hnsw { .. } => {
vec![]
}
}
}
}