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();
}
"converge" => converge(&dir, shape).await,
other => println!("unknown mode: {other}"),
}
}
const BATCH: usize = 900;
#[cfg(not(feature = "metrics"))]
async fn converge(_dir: &tempfile::TempDir, _shape: fixtures::Shape) {
println!(
" converge imports {BATCH} edges and reports the actor's own \
per-transaction readings,\n which a default build does not keep.\n \
re-run with: cargo run --release --features metrics --example chunk_matrix -- converge ..."
);
}
#[cfg(feature = "metrics")]
async fn converge(dir: &tempfile::TempDir, shape: fixtures::Shape) {
use macrame::metrics::CommandKind;
async fn fixture(
dir: &tempfile::TempDir,
name: &str,
shape: fixtures::Shape,
) -> (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 + BATCH + 8).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.write_bulk_atomic(chunk.to_vec()).await.unwrap();
}
(db, nodes)
}
let (db, nodes) = fixture(dir, "ca.db", shape).await;
println!(" nodes in fixture: {nodes}\n");
let t = Instant::now();
db.bulk_import(measured_chunk(BATCH, nodes)).await.unwrap();
let adaptive_total = ms(t.elapsed());
let snap = db.metrics();
let k = snap
.kinds
.iter()
.find(|k| k.kind == CommandKind::BulkImportChunk)
.expect("the import ran no chunks");
let (chunks, mean_hold, longest, over) = (k.turns, ms(k.mean), ms(k.longest), k.over_budget);
let mut trace = Vec::new();
let mut rows = db
.read_conn()
.query(
"SELECT COUNT(*) FROM links WHERE edge_type = 'MEASURED' \
GROUP BY recorded_at ORDER BY recorded_at",
(),
)
.await
.unwrap();
while let Some(r) = rows.next().await.unwrap() {
trace.push(r.get::<u64>(0).unwrap() as usize);
}
db.close().await.unwrap();
let settled = trace
.iter()
.max_by_key(|n| trace.iter().filter(|m| m == n).count())
.copied()
.unwrap_or(0);
let steady_mean = (mean_hold * chunks as f64 - longest) / (chunks - 1) as f64;
println!(" adaptive");
println!(
" chunks {chunks:>5} mean size {:>6.1} rows settled at {settled} rows",
BATCH as f64 / chunks as f64,
);
if trace.len() > 6 {
println!(
" sizes {:?} .. {:?}",
&trace[..3],
&trace[trace.len() - 3..]
);
} else {
println!(" sizes {trace:?}");
}
println!(" hold mean {mean_hold:>7.2} ms longest {longest:>7.2} ms over budget {over} of {chunks}");
println!(" hold mean excluding the first chunk: {steady_mean:>6.2} ms");
println!(
" total {adaptive_total:>8.2} ms ({:.1} µs/edge)",
adaptive_total * 1e3 / BATCH as f64
);
let (db, nodes) = fixture(dir, "cf.db", shape).await;
let batch = measured_chunk(BATCH, nodes);
let (mut fixed_total, mut worst, mut n) = (0.0f64, 0.0f64, 0u64);
for chunk in batch.chunks(chunk_rows::EDGES) {
let t = Instant::now();
db.write_bulk_atomic(chunk.to_vec()).await.unwrap();
let e = ms(t.elapsed());
fixed_total += e;
worst = worst.max(e);
n += 1;
}
db.close().await.unwrap();
println!("\n fixed at the ceiling ({} rows)", chunk_rows::EDGES);
println!(
" chunks {n:>5} hold mean {:>7.2} ms longest {worst:>7.2} ms",
fixed_total / n as f64
);
println!(
" total {fixed_total:>8.2} ms ({:.1} µs/edge)",
fixed_total * 1e3 / BATCH as f64
);
println!("\n budget {BUDGET_MS} ms");
println!(
" latency : longest hold {:.2}x {}",
longest / worst,
if longest < worst {
"-- the adaptive loop is the shorter stall"
} else {
"-- adapting did NOT shorten the worst stall"
}
);
println!(
" throughput: {:.2}x {}",
adaptive_total / fixed_total,
if adaptive_total > fixed_total {
"-- more chunks, more fixed cost, as D-058 predicts"
} else {
"-- no throughput cost measured on this shape"
}
);
}