use iqdb::{
CacheConfig, DistanceMetric, HnswConfig, IndexKind, Iqdb, IqdbConfig, IvfConfig, Result,
Vector, VectorId,
};
fn load(db: &Iqdb) -> Result<()> {
for i in 0..50u64 {
let x = (i as f32) * 0.1;
db.upsert(VectorId::from(i), Vector::new(vec![x, 1.0 - x])?, None)?;
}
Ok(())
}
fn nearest(db: &Iqdb, label: &str) -> Result<()> {
let hits = db.search(&Vector::new(vec![0.0, 1.0])?, 3)?;
let ids: Vec<String> = hits.iter().map(|h| h.id.to_string()).collect();
println!("{label:<22} top-3 ids: {ids:?}");
Ok(())
}
fn main() -> Result<()> {
let metric = DistanceMetric::Euclidean;
let flat = Iqdb::open_in_memory(2, metric)?;
load(&flat)?;
nearest(&flat, "flat (exact)")?;
let hnsw = Iqdb::open_in_memory_with(
IqdbConfig::new(2, metric)
.index(IndexKind::Hnsw(HnswConfig::default().with_ef_search(128)))
.cache(CacheConfig::new().capacity(1_024)),
)?;
load(&hnsw)?;
nearest(&hnsw, "hnsw (approximate)")?;
let _ = hnsw.search(&Vector::new(vec![0.0, 1.0])?, 3)?;
if let Some(stats) = hnsw.cache_stats() {
println!(" cache hits={} misses={}", stats.hits, stats.misses);
}
let ivf = Iqdb::open_in_memory_with(IqdbConfig::new(2, metric).index(IndexKind::Ivf(
IvfConfig::default().with_n_clusters(8).with_n_probes(8),
)))?;
load(&ivf)?;
nearest(&ivf, "ivf (approximate)")?;
ivf.optimize()?;
nearest(&ivf, "ivf (after optimize)")?;
flat.close()?;
hnsw.close()?;
ivf.close()
}