use std::time::Instant;
use macrame::graph::EdgeAssertion;
use macrame::{ConceptUpsert, Database};
const TS: &str = "2026-01-01T00:00:00.000000Z";
const OPEN: &str = "9999-12-31T23:59:59.999999Z";
const NOW: &str = "2026-06-01T00:00:00.000000Z";
const CURRENT_WALK: &str = r#"
WITH RECURSIVE walk(node_id, depth, path) AS (
SELECT ?1, 0, '/' || CAST(?1 AS BLOB) || '/'
UNION ALL
SELECT l.target_id, w.depth + 1, w.path || CAST(l.target_id AS BLOB) || '/'
FROM walk w
JOIN links_current l ON l.source_id = w.node_id
WHERE w.depth < ?2
AND l.valid_from <= ?3 AND ?3 < l.valid_to
AND l.weight >= ?4
AND INSTR(w.path, '/' || CAST(l.target_id AS BLOB) || '/') = 0
)
"#;
const REWRITE_WALK: &str = r#"
WITH RECURSIVE walk(node_id, depth) AS (
SELECT ?1, 0
UNION
SELECT l.target_id, w.depth + 1
FROM walk w
JOIN links_current l ON l.source_id = w.node_id
WHERE w.depth < ?2
AND l.valid_from <= ?3 AND ?3 < l.valid_to
AND l.weight >= ?4
)
"#;
const PROJECT_IDS: &str = r#"
SELECT DISTINCT w.node_id
FROM walk w JOIN concepts c ON c.id = w.node_id
WHERE c.retired = 0
ORDER BY w.node_id;
"#;
fn node(layer: usize, i: usize) -> String {
if layer == 0 {
"n00_0000".to_string()
} else {
format!("n{layer:02}_{i:04}")
}
}
async fn seed_layered(db: &Database, layers: usize, width: usize) -> usize {
let mut ids = vec![node(0, 0)];
for layer in 1..=layers {
for i in 0..width {
ids.push(node(layer, i));
}
}
for chunk in ids.chunks(500) {
db.write_concepts(
chunk
.iter()
.map(|id| ConceptUpsert::new(id.clone(), id.clone()).valid_from(TS))
.collect(),
)
.await
.unwrap();
}
let mut edges = Vec::new();
for i in 0..width {
edges.push(
EdgeAssertion::new(node(0, 0), node(1, i), "LINKS")
.valid_from(TS)
.valid_to(OPEN),
);
}
for layer in 1..layers {
for a in 0..width {
for b in 0..width {
edges.push(
EdgeAssertion::new(node(layer, a), node(layer + 1, b), "LINKS")
.valid_from(TS)
.valid_to(OPEN),
);
}
}
}
let total = edges.len();
for chunk in edges.chunks(500) {
db.bulk_import(chunk.to_vec()).await.unwrap();
}
total
}
async fn count_walk_rows(conn: &libsql::Connection, walk: &str, depth: usize) -> i64 {
let sql = format!("{walk} SELECT COUNT(*) FROM walk;");
let mut rows = conn
.query(
&sql,
libsql::params![node(0, 0), depth as i64, NOW, f64::NEG_INFINITY],
)
.await
.unwrap();
rows.next().await.unwrap().unwrap().get(0).unwrap()
}
async fn ids(conn: &libsql::Connection, walk: &str, depth: usize) -> (Vec<String>, f64) {
let sql = format!("{walk}{PROJECT_IDS}");
let start = Instant::now();
let mut rows = conn
.query(
&sql,
libsql::params![node(0, 0), depth as i64, NOW, f64::NEG_INFINITY],
)
.await
.unwrap();
let mut out = Vec::new();
while let Some(r) = rows.next().await.unwrap() {
out.push(r.get(0).unwrap());
}
let ms = start.elapsed().as_secs_f64() * 1000.0;
(out, ms)
}
async fn best_of(
conn: &libsql::Connection,
walk: &str,
depth: usize,
n: usize,
) -> (Vec<String>, f64) {
let mut best = f64::MAX;
let mut set = Vec::new();
for _ in 0..n {
let (v, ms) = ids(conn, walk, depth).await;
if ms < best {
best = ms;
}
set = v;
}
(set, best)
}
async fn shipped(conn: &libsql::Connection, depth: usize, n: usize) -> (Vec<String>, f64) {
let t = macrame::graph::TraversalBuilder::new(node(0, 0))
.max_depth(depth)
.min_weight(f64::NEG_INFINITY);
let mut best = f64::MAX;
let mut set = Vec::new();
for _ in 0..n {
let start = Instant::now();
set = t.execute_ids(conn, NOW).await.unwrap();
let ms = start.elapsed().as_secs_f64() * 1000.0;
if ms < best {
best = ms;
}
}
(set, best)
}
async fn seed_star(db: &Database, edges: usize) -> usize {
let ids: Vec<String> = (0..=edges).map(|i| format!("n{i:07}")).collect();
for chunk in ids.chunks(2_000) {
db.write_concepts(
chunk
.iter()
.map(|id| ConceptUpsert::new(id.clone(), id.clone()).valid_from(TS))
.collect(),
)
.await
.unwrap();
}
let mut batch = Vec::with_capacity(edges);
for i in 1..=edges {
let src = if i <= edges / 3 {
0
} else if i <= 2 * (edges / 3) {
i - edges / 3
} else {
i - 2 * (edges / 3)
};
batch.push(
EdgeAssertion::new(format!("n{src:07}"), format!("n{i:07}"), "LINKS")
.valid_from(TS)
.valid_to(OPEN),
);
}
for chunk in batch.chunks(2_000) {
db.bulk_import(chunk.to_vec()).await.unwrap();
}
edges
}
#[tokio::main]
async fn main() {
let depth: usize = std::env::args()
.nth(1)
.and_then(|s| s.parse().ok())
.unwrap_or(6);
println!(
"libSQL 0.9.30, best of 5. `old` is the simple-path CTE shipped through\n\
0.5.6, kept here as the baseline; `shipped` is TraversalBuilder::execute_ids.\n"
);
println!(
"== layered fixture, depth = {depth} — paths to a layer-i node grow as width^(i-1) ==\n"
);
println!(
"{:<16} {:>7} {:>14} {:>14} {:>11} {:>11}",
"fixture", "edges", "walk rows old", "walk rows new", "ms old", "ms shipped"
);
for (layers, width) in [(4, 6), (5, 6), (5, 8), (6, 8)] {
let dir = tempfile::TempDir::new().unwrap();
let path = dir.path().join("t.db");
let db = Database::open_with_cadence(&path, None).await.unwrap();
let edges = seed_layered(&db, layers, width).await;
let conn = db.read_conn();
let cur_rows = count_walk_rows(conn, CURRENT_WALK, depth).await;
let new_rows = count_walk_rows(conn, REWRITE_WALK, depth).await;
let (cur_ids, cur_ms) = best_of(conn, CURRENT_WALK, depth, 5).await;
let (new_ids, new_ms) = shipped(conn, depth, 5).await;
assert_eq!(
cur_ids, new_ids,
"the shipped traversal must return what the simple-path form returned ({layers} x {width})"
);
println!(
"{:<16} {:>7} {:>14} {:>14} {:>11.1} {:>11.1}",
format!("{layers} layers x {width}"),
edges,
cur_rows,
new_rows,
cur_ms,
new_ms
);
db.close().await.unwrap();
}
println!("\n== star-of-stars (a tree — the benches/ fixture), depth 3 ==\n");
println!(
"{:<16} {:>7} {:>14} {:>14} {:>11} {:>11}",
"fixture", "edges", "walk rows old", "walk rows new", "ms old", "ms shipped"
);
for edges in [1_010usize, 5_050, 10_100] {
let dir = tempfile::TempDir::new().unwrap();
let path = dir.path().join("s.db");
let db = Database::open_with_cadence(&path, None).await.unwrap();
seed_star(&db, edges).await;
let conn = db.read_conn();
let old_sql = format!("{CURRENT_WALK} SELECT COUNT(*) FROM walk;");
let new_sql = format!("{REWRITE_WALK} SELECT COUNT(*) FROM walk;");
let count = |sql: String| async move {
let mut rows = conn
.query(
&sql,
libsql::params!["n0000000", 3i64, NOW, f64::NEG_INFINITY],
)
.await
.unwrap();
rows.next().await.unwrap().unwrap().get::<i64>(0).unwrap()
};
let cur_rows = count(old_sql).await;
let new_rows = count(new_sql).await;
let mut old_ms = f64::MAX;
for _ in 0..15 {
let sql = format!("{CURRENT_WALK}{PROJECT_IDS}");
let start = Instant::now();
let mut rows = conn
.query(
&sql,
libsql::params!["n0000000", 3i64, NOW, f64::NEG_INFINITY],
)
.await
.unwrap();
let mut out: Vec<String> = Vec::new();
while let Some(r) = rows.next().await.unwrap() {
out.push(r.get(0).unwrap());
}
std::hint::black_box(&out);
old_ms = old_ms.min(start.elapsed().as_secs_f64() * 1000.0);
}
let t = macrame::graph::TraversalBuilder::new("n0000000")
.max_depth(3)
.min_weight(f64::NEG_INFINITY);
let mut new_ms = f64::MAX;
for _ in 0..15 {
let start = Instant::now();
t.execute_ids(conn, NOW).await.unwrap();
new_ms = new_ms.min(start.elapsed().as_secs_f64() * 1000.0);
}
println!(
"{:<16} {:>7} {:>14} {:>14} {:>11.1} {:>11.1}",
format!("{} nodes", edges + 1),
edges,
cur_rows,
new_rows,
old_ms,
new_ms
);
db.close().await.unwrap();
}
println!("\nNode sets agreed at every layered size (asserted, not eyeballed).");
}