#![allow(clippy::unwrap_used, clippy::expect_used, clippy::print_stdout)]
use std::path::PathBuf;
use iqdb_eval::{LatencyConfig, build_index_from_base, latency, load_sift_dataset, recall_at_k};
use iqdb_flat::{FlatConfig, FlatIndex};
use iqdb_hnsw::{HnswConfig, HnswIndex};
use iqdb_types::{DistanceMetric, SearchParams};
const K: usize = 10;
const SIFTSMALL_RECALL_FLOOR: f64 = 0.95;
#[test]
#[ignore]
fn siftsmall_recall_and_latency_via_harness() {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(".bench-data/siftsmall");
if !root.exists() {
println!(
"SKIP siftsmall: missing dataset under {}.\n \
Fetch with:\n \
mkdir -p iqdb-eval/.bench-data && cd iqdb-eval/.bench-data\n \
curl -O ftp://ftp.irisa.fr/local/texmex/corpus/siftsmall.tar.gz\n \
tar -xzf siftsmall.tar.gz",
root.display(),
);
return;
}
let dataset = load_sift_dataset(&root, "siftsmall").unwrap();
println!(
"loaded siftsmall: base={} query={} gt={} dim={}",
dataset.base.len(),
dataset.queries.len(),
dataset.ground_truth.len(),
dataset.dim,
);
let metric = DistanceMetric::Euclidean;
let oracle: FlatIndex =
build_index_from_base(FlatConfig, dataset.dim, metric, &dataset.base).unwrap();
let target: HnswIndex =
build_index_from_base(HnswConfig::default(), dataset.dim, metric, &dataset.base).unwrap();
let params = SearchParams::new(K, metric);
let recall_loaded =
recall_at_k(&target, &dataset.queries, &dataset.ground_truth, ¶ms).unwrap();
println!(
"recall@10 (loaded gt): mean={:.4} min={:.4} max={:.4} n_queries={}",
recall_loaded.mean_recall,
recall_loaded.min_recall,
recall_loaded.max_recall,
recall_loaded.query_count,
);
assert!(
recall_loaded.mean_recall >= SIFTSMALL_RECALL_FLOOR,
"siftsmall recall@10 vs loaded gt = {:.4} < floor {:.4}",
recall_loaded.mean_recall,
SIFTSMALL_RECALL_FLOOR,
);
let oracle_gt = iqdb_eval::compute_ground_truth(&oracle, &dataset.queries, K).unwrap();
let recall_oracle = recall_at_k(&target, &dataset.queries, &oracle_gt, ¶ms).unwrap();
println!(
"recall@10 (flat oracle): mean={:.4} min={:.4} max={:.4}",
recall_oracle.mean_recall, recall_oracle.min_recall, recall_oracle.max_recall,
);
assert!(
recall_oracle.mean_recall >= SIFTSMALL_RECALL_FLOOR,
"siftsmall recall@10 vs flat oracle = {:.4} < floor {:.4}",
recall_oracle.mean_recall,
SIFTSMALL_RECALL_FLOOR,
);
let warmup = dataset.queries.len() / 10;
let lat = latency(
&target,
&dataset.queries,
¶ms,
&LatencyConfig { warmup },
)
.unwrap();
println!(
"latency (us): mean={:.1} p50={:.1} p95={:.1} p99={:.1} qps={:.0}",
lat.mean_us, lat.p50_us, lat.p95_us, lat.p99_us, lat.qps,
);
assert!(lat.p50_us <= lat.p95_us);
assert!(lat.p95_us <= lat.p99_us);
assert!(lat.qps > 0.0);
}