use std::sync::Arc;
use iqdb_index::{Index, IndexCore};
use iqdb_ivf::{IvfConfig, IvfIndex};
use iqdb_types::{DistanceMetric, Result, SearchParams, VectorId};
fn arc(v: &[f32]) -> Arc<[f32]> {
Arc::from(v)
}
fn main() -> Result<()> {
let cfg = IvfConfig::default()
.with_n_clusters(2)
.with_n_probes(2)
.with_training_sample_size(64)
.with_seed(7);
let mut idx = IvfIndex::new(2, DistanceMetric::Euclidean, cfg)?;
let sample: Vec<Vec<f32>> = vec![
vec![0.0, 0.0],
vec![0.2, -0.1],
vec![-0.1, 0.1],
vec![10.0, 10.0],
vec![10.2, 9.8],
vec![9.9, 10.1],
];
let sample_refs: Vec<&[f32]> = sample.iter().map(|v| v.as_slice()).collect();
idx.train(&sample_refs)?;
idx.insert(VectorId::from(1u64), arc(&[0.0, 0.0]), None)?;
idx.insert(VectorId::from(2u64), arc(&[10.0, 10.0]), None)?;
idx.insert(VectorId::from(3u64), arc(&[0.1, 0.1]), None)?;
let hits = idx.search(
&[0.0, 0.0],
&SearchParams::new(2, DistanceMetric::Euclidean),
)?;
println!("nearest 2 to (0, 0):");
for (rank, hit) in hits.iter().enumerate() {
println!(" #{rank}: id={} distance={:.3}", hit.id, hit.distance);
}
assert_eq!(hits[0].id, VectorId::U64(1));
assert_eq!(hits[1].id, VectorId::U64(3));
let stats = idx.stats();
println!(
"index_type={} n_vectors={} ~memory_bytes={}",
stats.index_type, stats.n_vectors, stats.memory_bytes
);
assert_eq!(stats.index_type, "ivf");
assert_eq!(idx.len(), 3);
Ok(())
}