use spg_engine::Engine;
use std::sync::atomic::Ordering::Relaxed;
use std::time::Instant;
const BATCH: i64 = 500;
const BATCHES: i64 = 20;
fn batch(table: &str, lo: i64, hi: i64, per_row_lead: bool) -> String {
let mut s = String::with_capacity((hi - lo) as usize * 24 + 32);
s.push_str("INSERT INTO ");
s.push_str(table);
s.push_str(" VALUES ");
for (k, id) in (lo..hi).enumerate() {
if k > 0 {
s.push(',');
}
let lead = if per_row_lead { id } else { 1 };
s.push_str(&format!("({id},{lead},{id})"));
}
s
}
fn run(label: &str, table: &str, per_row_lead: bool) {
let mut e = Engine::new();
e.set_autovacuum(false);
e.execute(&format!(
"CREATE TABLE {table}(id BIGINT PRIMARY KEY, lead_col BIGINT, uid BIGINT, \
UNIQUE(lead_col, uid))"
))
.unwrap();
println!("\n## {label}");
println!("| rows before | ms | probes | locators | locators/probe |");
println!("|------------:|---:|-------:|---------:|---------------:|");
for b in 0..BATCHES {
let (lo, hi) = (b * BATCH + 1, (b + 1) * BATCH + 1);
let sql = batch(table, lo, hi, per_row_lead);
let base = (
spg_engine::UNIQ_PROBE_CALLS.load(Relaxed),
spg_engine::UNIQ_PROBE_LOCATORS.load(Relaxed),
);
let t0 = Instant::now();
e.execute(&sql).unwrap();
let ms = t0.elapsed().as_secs_f64() * 1000.0;
let calls = spg_engine::UNIQ_PROBE_CALLS.load(Relaxed) - base.0;
let locs = spg_engine::UNIQ_PROBE_LOCATORS.load(Relaxed) - base.1;
if b % 4 == 0 || b == BATCHES - 1 {
let per = if calls == 0 {
0.0
} else {
locs as f64 / calls as f64
};
println!("| {} | {ms:.1} | {calls} | {locs} | {per:.1} |", b * BATCH);
}
}
}
fn main() {
run(
"UNIQUE(lead_col, uid), ONE distinct leading value (mailrs)",
"low_card",
false,
);
run(
"UNIQUE(lead_col, uid), leading value distinct per row (control)",
"high_card",
true,
);
}