use std::time::{Duration, Instant};
use macrame::prelude::*;
#[path = "../tests/common/fixtures.rs"]
mod fixtures;
const TS: &str = "2026-01-01T00:00:00.000000Z";
const OPEN: &str = "9999-12-31T23:59:59.999999Z";
const POPULATION: usize = 8_000;
const BUDGET_MS: f64 = 3.0;
fn ms(d: Duration) -> f64 {
d.as_secs_f64() * 1e3
}
fn shape_of(name: &str) -> fixtures::Shape {
match name {
"star" => fixtures::Shape::StarOfStars,
"clustered" => fixtures::Shape::Clustered,
"chain" => fixtures::Shape::Chain,
"dense" => fixtures::Shape::DenseSmall,
other => panic!("unknown shape {other:?}; expected star|clustered|chain|dense"),
}
}
fn nodes_for(shape: fixtures::Shape, edges: usize) -> usize {
let mut lo = 2usize;
let mut hi = edges + 2;
while lo < hi {
let mid = lo + (hi - lo) / 2;
if shape.edges(mid).len() >= edges {
hi = mid;
} else {
lo = mid + 1;
}
}
lo
}
async fn populated(
dir: &tempfile::TempDir,
name: &str,
shape: fixtures::Shape,
spare: usize,
) -> (Database, usize) {
let nodes = nodes_for(shape, POPULATION);
let db = Database::open_with_cadence(dir.path().join(name), None)
.await
.unwrap();
let mut concepts = shape.concepts(nodes);
concepts.extend((nodes..nodes + spare).map(fixtures::concept));
for c in concepts.chunks(600) {
db.write_concepts(c.to_vec()).await.unwrap();
}
let mut edges = shape.edges(nodes);
edges.truncate(POPULATION);
for chunk in edges.chunks(2_000) {
db.bulk_import(chunk.to_vec()).await.unwrap();
}
(db, nodes)
}
fn measured_chunk(n: usize, first_target: usize) -> Vec<EdgeAssertion> {
(0..n)
.map(|k| {
EdgeAssertion::new(
fixtures::node_id(0),
fixtures::node_id(first_target + k),
"MEASURED",
)
.valid_from(TS)
.valid_to(OPEN)
})
.collect()
}
fn verdict(rows: &[(usize, f64)]) -> String {
let largest = rows
.iter()
.filter(|(_, t)| *t <= BUDGET_MS)
.map(|(n, _)| *n)
.max();
match largest {
Some(n) => format!("largest size within {BUDGET_MS} ms: {n}"),
None => format!(
"no swept size meets {BUDGET_MS} ms — smallest measured is {} rows at {:.2} ms",
rows[0].0, rows[0].1
),
}
}
#[tokio::main]
async fn main() {
let mode = std::env::args().nth(1).unwrap_or_else(|| "edges".into());
let shape_name = std::env::args().nth(2).unwrap_or_else(|| "star".into());
let shape = shape_of(&shape_name);
let dir = tempfile::TempDir::new().unwrap();
println!(
"== {mode}: chunk cost into a {POPULATION}-edge {} table ==",
shape.name()
);
println!(" worst case for: {}", shape.worst_case_for());
match mode.as_str() {
"edges" => {
const SIZES: [usize; 5] = [5, 10, 20, 45, 90];
let mut rows = Vec::new();
for n in SIZES {
let (db, nodes) = populated(&dir, &format!("e{n}.db"), shape, SIZES.len() + n).await;
let batch = measured_chunk(n, nodes);
let t = Instant::now();
db.write_bulk_atomic(batch).await.unwrap();
let e = ms(t.elapsed());
println!(
" {n:>5} edges : {e:>8.2} ms ({:>6.1} µs/row){}",
e * 1e3 / n as f64,
if e <= BUDGET_MS { "" } else { " over budget" }
);
rows.push((n, e));
db.close().await.unwrap();
}
println!("\n nodes in fixture: {}", nodes_for(shape, POPULATION));
println!(" current constant: {}", chunk_rows::EDGES);
println!(" {}", verdict(&rows));
}
"rest" => {
let (db, nodes) = populated(&dir, "r.db", shape, 4_000).await;
println!(" nodes in fixture: {nodes}\n");
let mut rows = Vec::new();
for n in [10usize, 30, 50, 70] {
let batch: Vec<ConceptUpsert> = (0..n)
.map(|i| {
ConceptUpsert::new(fixtures::node_id(i), format!("Rewritten {i}"))
.content(format!("new body for {i}"))
.valid_from(TS)
})
.collect();
let t = Instant::now();
db.write_concepts(batch).await.unwrap();
rows.push((n, ms(t.elapsed())));
println!(" concepts {n:>5} : {:>8.2} ms", rows.last().unwrap().1);
}
println!(
" -> constant {}, {}\n",
chunk_rows::CONCEPTS,
verdict(&rows)
);
let mut rows = Vec::new();
for n in [100usize, 300, 600] {
let batch: Vec<Annotation> = (0..n)
.map(|i| Annotation {
concept_id: fixtures::node_id(i),
label: "community".into(),
value: format!("{}", i % 7),
})
.collect();
let t = Instant::now();
db.write_analytics_annotations(batch).await.unwrap();
rows.push((n, ms(t.elapsed())));
println!(" annotations{n:>5} : {:>8.2} ms", rows.last().unwrap().1);
}
println!(
" -> constant {}, {}\n",
chunk_rows::ANNOTATIONS,
verdict(&rows)
);
let model = ModelName::new("matrix_v1").unwrap();
db.register_model(&model, 8).await.unwrap();
let mut rows = Vec::new();
for n in [10usize, 20, 30] {
let batch: Vec<(String, Vec<f32>)> = (0..n)
.map(|i| {
let t = i as f32 / 500.0;
(
fixtures::node_id(i),
(0..8).map(|k| ((t + k as f32) * 0.37).sin()).collect(),
)
})
.collect();
let t = Instant::now();
db.upsert_embeddings(&model, batch).await.unwrap();
rows.push((n, ms(t.elapsed())));
println!(" embeddings {n:>5} : {:>8.2} ms", rows.last().unwrap().1);
}
println!(
" -> constant {}, {}",
chunk_rows::EMBEDDINGS,
verdict(&rows)
);
db.close().await.unwrap();
}
other => println!("unknown mode: {other}"),
}
}