#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum IndexType {
Hnsw,
Vamana,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum QuantizationKind {
Sq8,
Pq,
RaBitQ,
Bbq,
Binary,
Ternary,
Opq,
None,
}
#[derive(Debug, Clone)]
pub struct VectorQueryOptions {
pub index_type: IndexType,
pub quantization: QuantizationKind,
pub query_dim: Option<u32>,
pub oversample: u8,
pub meta_token_budget: Option<u8>,
pub ef_search: usize,
pub k: usize,
pub target_recall: f32,
}
impl Default for VectorQueryOptions {
fn default() -> Self {
Self {
index_type: IndexType::Hnsw,
quantization: QuantizationKind::Sq8,
query_dim: None,
oversample: 3,
meta_token_budget: None,
ef_search: 64,
k: 10,
target_recall: 0.95,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_produces_reasonable_values() {
let opts = VectorQueryOptions::default();
assert_eq!(opts.index_type, IndexType::Hnsw);
assert_eq!(opts.oversample, 3);
assert!(opts.ef_search >= opts.k, "ef_search must be >= k");
assert!(opts.target_recall > 0.0 && opts.target_recall <= 1.0);
assert!(opts.query_dim.is_none());
assert!(opts.meta_token_budget.is_none());
}
#[test]
fn custom_options_roundtrip() {
let opts = VectorQueryOptions {
index_type: IndexType::Vamana,
quantization: QuantizationKind::RaBitQ,
query_dim: Some(512),
oversample: 5,
meta_token_budget: Some(8),
ef_search: 128,
k: 20,
target_recall: 0.99,
};
assert_eq!(opts.index_type, IndexType::Vamana);
assert_eq!(opts.quantization, QuantizationKind::RaBitQ);
assert_eq!(opts.query_dim, Some(512));
assert_eq!(opts.oversample, 5);
assert_eq!(opts.meta_token_budget, Some(8));
assert_eq!(opts.ef_search, 128);
assert_eq!(opts.k, 20);
assert!((opts.target_recall - 0.99).abs() < f32::EPSILON);
}
}