use clap::Parser;
use rand::{Rng, SeedableRng};
use ringdb::{QueryResult, RingDb, RingDbConfig, RingQuery};
#[derive(Parser)]
#[command(name = "ringdb-cli", about = "ringdb demo: random dataset ring query")]
struct Cli {
#[arg(short, long, default_value_t = 10_000)]
n: usize,
#[arg(long, default_value_t = 128)]
dims: usize,
#[arg(short = 'd', long, default_value_t = 5.0)]
d: f32,
#[arg(short = 'l', long, default_value_t = 0.5)]
lambda: f32,
#[arg(long, default_value_t = 42)]
seed: u64,
}
fn main() {
let cli = Cli::parse();
let config = RingDbConfig::new(cli.dims);
println!("ringdb demo");
println!(" dataset : {} vectors × {} dims", cli.n, cli.dims);
println!(" ring : d={}, λ={}", cli.d, cli.lambda);
println!();
print!("Building database … ");
let build_start = std::time::Instant::now();
let mut db = RingDb::new(config).expect("failed to create RingDb");
let mut rng = rand::rngs::SmallRng::seed_from_u64(cli.seed);
let mut buf = vec![0.0f32; cli.dims];
for x in buf.iter_mut() {
*x = rng.gen_range(-1.0f32..1.0);
}
let query_vec = buf.clone();
db.add_vector(&buf, ()).expect("failed to add vector");
for _ in 1..cli.n {
for x in buf.iter_mut() {
*x = rng.gen_range(-1.0f32..1.0);
}
db.add_vector(&buf, ()).expect("failed to add vector");
}
let db = db.build().expect("failed to build");
let build_elapsed = build_start.elapsed();
println!("done in {:.2?}", build_elapsed);
println!(" backend : {}", db.backend_name());
println!();
let rq = RingQuery {
query: &query_vec,
d: cli.d,
lambda: cli.lambda,
};
print!("Running ring query … ");
let QueryResult {
ids,
backend_used,
elapsed,
} = db.query(&rq).expect("query failed");
println!("done");
println!();
println!("Results:");
println!(" backend : {backend_used}");
println!(" hits : {}", ids.len());
println!(" query time : {elapsed:.2?}");
if ids.len() <= 20 {
println!(" hit IDs : {ids:?}");
} else {
println!(
" hit IDs : [{}, {}, … {} total]",
ids[0],
ids[1],
ids.len()
);
}
}