Trusty: provenance library workspace (initial import)

This commit is contained in:
2026-09-09 18:31:00 -04:00
commit 693f3bef1e
73 changed files with 26295 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
// ============================================================
// EXAMPLE: bench_append
// PURPOSE: Measure fsync-amortization speedup of append_batch over
// a loop of append() calls on a file-backed SQLite DB.
// Intended for ad-hoc inspection, not CI regression
// tracking (no criterion / no gate). Prints rows/sec +
// speedup ratio.
//
// RUN: cargo run -p trusty-sqlite --release --example bench_append
// (release mode matters: debug rusqlite is much slower)
// ============================================================
use serde_json::json;
use std::time::Instant;
use trusty_core::SecretKey;
use trusty_sqlite::{RowSpec, Trusty};
const N: usize = 1000;
fn tmp_db_path(tag: &str) -> std::path::PathBuf {
let mut p = std::env::temp_dir();
let nanos = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_nanos())
.unwrap_or(0);
p.push(format!("trusty_bench_{tag}_{nanos}.db"));
p
}
fn key() -> SecretKey {
SecretKey::new(*b"0123456789abcdef")
}
fn bench_single_row(path: &std::path::Path) -> f64 {
let mut t = Trusty::open(path, key()).expect("open");
// Warmup: one genesis so we are measuring mutations, not first-row setup.
t.append("acme", &json!({"warmup": true}), "s")
.expect("warmup");
let start = Instant::now();
for i in 0..N {
t.append("acme", &json!({"i": i}), "s").expect("append ok");
}
let elapsed = start.elapsed().as_secs_f64();
N as f64 / elapsed
}
fn bench_batch(path: &std::path::Path) -> f64 {
let mut t = Trusty::open(path, key()).expect("open");
t.append("acme", &json!({"warmup": true}), "s")
.expect("warmup");
let values: Vec<serde_json::Value> = (0..N).map(|i| json!({"i": i})).collect();
let specs: Vec<RowSpec> = values
.iter()
.map(|v| RowSpec {
entity_id: "acme",
data: v,
source_url: "s",
})
.collect();
let start = Instant::now();
t.append_batch(&specs).expect("batch ok");
let elapsed = start.elapsed().as_secs_f64();
N as f64 / elapsed
}
fn main() {
let p1 = tmp_db_path("single");
let p2 = tmp_db_path("batch");
println!("trusty-sqlite append benchmark (N = {N}, file-backed, WAL + FULL sync)");
println!("single-row db : {}", p1.display());
println!("batch db : {}", p2.display());
println!();
let single_rps = bench_single_row(&p1);
let batch_rps = bench_batch(&p2);
let speedup = batch_rps / single_rps;
println!("single-row append : {single_rps:>10.1} rows/sec");
println!("append_batch : {batch_rps:>10.1} rows/sec");
println!("speedup : {speedup:>10.2}x");
println!();
println!("(cleanup: rm {} {})", p1.display(), p2.display());
}