use std::collections::HashMap;
use std::io::Write;
use std::path::Path;
use quiver_core::{Descriptor, DistanceMetric, Dtype, Store};
const DIM: usize = 8;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut args = std::env::args().skip(1);
let data_dir = args
.next()
.ok_or("usage: crash_writer <data_dir> <ack_log> [checkpoint_every]")?;
let ack_path = args.next().ok_or("missing ack log path")?;
let checkpoint_every: u64 = args.next().map_or(0, |s| s.parse().unwrap_or(0));
let mut store = Store::open(Path::new(&data_dir))?;
let cid = match store.collection_id("crash") {
Some(c) => c,
None => store.create_collection(
"crash",
Descriptor::new(DIM as u32, Dtype::F32, DistanceMetric::L2),
)?,
};
let mut next = store.len(cid)? as u64;
let mut ack = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(&ack_path)?;
loop {
let id = format!("k{next}");
let vector: Vec<f32> = (0..DIM).map(|j| next as f32 + j as f32).collect();
let payload = format!(r#"{{"n":{next}}}"#).into_bytes();
store.upsert(cid, &id, &vector, &payload)?;
writeln!(ack, "{next}")?;
ack.flush()?;
ack.sync_data()?;
if checkpoint_every > 0 && (next + 1).is_multiple_of(checkpoint_every) {
let blob = (store.len(cid)? as u64).to_le_bytes().to_vec();
store.checkpoint_with_index_snapshots(&HashMap::from([(cid, blob)]))?;
}
next += 1;
}
}