#![forbid(unsafe_code)]
use std::sync::Arc;
use std::time::Instant;
use crate::optimizer::policy::OptimizeOptions;
use crate::store::transaction::CrashHooks;
use crate::store::workers;
use crate::store::{NewEntry, Store, StoreConfig};
use tempfile::TempDir;
fn create_store(dir: &TempDir) -> Arc<Store> {
let cfg = StoreConfig {
segment_size: 128 * 1024 * 1024,
..Default::default()
};
Arc::new(Store::create(dir.path(), &cfg, [0x11; 16]).unwrap())
}
fn create_files(store: &Store, n: usize) -> Vec<u64> {
let mut inos = Vec::with_capacity(n);
for i in 0..n {
let ino = store
.create_entry(
store.current_root().root_dir_ino,
format!("f{i}").as_bytes(),
NewEntry::file(0o644, 1000, 1000),
&CrashHooks::none(),
)
.unwrap();
inos.push(ino);
}
inos
}
fn deterministic_noise(len: usize, seed: u64) -> Vec<u8> {
let mut out = Vec::with_capacity(len);
let mut state = seed;
for _ in 0..len {
state = state
.wrapping_mul(6364136223846793005)
.wrapping_add(1442695040888963407);
out.push((state >> 33) as u8);
}
out
}
fn stream_for(file_index: usize, range: u64) -> Vec<u8> {
let mut seed = 0x11e_0001u64;
seed ^= (file_index as u64).wrapping_mul(0x9e37_79b9_7f4a_7c15);
seed ^= range.wrapping_mul(0xbf58_476d_1ce4_e5b9);
deterministic_noise(65536 * 16, seed)
}
fn row<'a>(rows: &'a [crate::perf::TimingRow], name: &str) -> Option<&'a crate::perf::TimingRow> {
rows.iter().find(|r| r.phase == name)
}
fn write_latencies_us(results: &[crate::perf::RequestResult]) -> Vec<f64> {
let mut v: Vec<f64> = results
.iter()
.filter(|r| r.name == "epoch_write")
.map(|r| r.total_ns as f64 / 1e3)
.collect();
v.sort_unstable_by(|a, b| a.total_cmp(b));
v
}
fn percentile(sorted: &[f64], q: f64) -> f64 {
if sorted.is_empty() {
return 0.0;
}
sorted[((sorted.len() - 1) as f64 * q) as usize]
}
enum PoolPath {
Semaphore,
Pool(usize),
}
impl PoolPath {
fn label(&self) -> String {
match self {
PoolPath::Semaphore => "semaphore".into(),
PoolPath::Pool(n) => format!("pool-{n}"),
}
}
}
struct RunResult {
label: String,
writers: usize,
wall_ms: f64,
p50_us: f64,
p99_us: f64,
mean_us: f64,
max_us: f64,
useful_cpu_ms: f64,
queue_share_pct: f64,
peak_in_flight: usize,
max_consecutive: usize,
byte_exact: bool,
}
fn run_sweep(path: &PoolPath, writers: usize, files: usize, opts: OptimizeOptions) -> RunResult {
match path {
PoolPath::Semaphore => workers::POOL.disable(),
PoolPath::Pool(n) => workers::POOL.enable(*n, 8),
}
let dir = TempDir::new().unwrap();
let store = create_store(&dir);
let inos = create_files(&store, files);
if let PoolPath::Pool(_) = path {
workers::POOL.bind(&store);
store.enable_worker_pool();
}
let fg = store.foreground_policy();
let t0 = Instant::now();
std::thread::scope(|s| {
for w in 0..writers {
let store = Arc::clone(&store);
let inos = &inos;
s.spawn(move || {
let mut i = w;
while i < inos.len() {
for r in 0..4u64 {
let data = stream_for(i, r);
store
.epoch_write(
inos[i],
r * data.len() as u64,
&data,
opts,
fg,
&CrashHooks::none(),
)
.unwrap();
}
i += writers;
}
});
}
});
let wall_ms = t0.elapsed().as_secs_f64() * 1e3;
let mut byte_exact = true;
let ep = store.epoch();
for (i, ino) in inos.iter().enumerate() {
let mut expected = Vec::with_capacity(4 * 1024 * 1024);
for r in 0..4u64 {
expected.extend_from_slice(&stream_for(i, r));
}
match store.read_file_epoch(&ep, *ino, 0, expected.len() as u64) {
Ok(got) if got == expected => {}
_ => byte_exact = false,
}
}
drop(ep);
let rows = store.perf().snapshot();
let prepare = row(&rows, "prepare").map(|r| r.total_ms).unwrap_or(0.0);
let queue = row(&rows, "worker_queue_wait")
.map(|r| r.total_ms)
.unwrap_or(0.0);
let scope = row(&rows, "worker_scope_wall")
.map(|r| r.total_ms)
.unwrap_or(0.0);
let read_decode = row(&rows, "read_decode").map(|r| r.total_ms).unwrap_or(0.0);
let useful = row(&rows, "worker_useful_cpu")
.map(|r| r.total_ms)
.unwrap_or(0.0);
let lat = write_latencies_us(&store.perf().results());
let p50 = percentile(&lat, 0.50);
let p99 = percentile(&lat, 0.99);
let mean_us = lat.iter().sum::<f64>() / lat.len().max(1) as f64;
let max_us = lat.iter().copied().fold(0.0f64, f64::max);
let diag = workers::POOL.diagnostics();
let rec = store.perf().reconcile();
assert!(!rec.overlap, "{}: partition overlap", path.label());
assert!(
rec.residual_share < 0.15,
"{}: residual {:.1}% too large",
path.label(),
rec.residual_share * 100.0
);
assert!(
scope <= (prepare + read_decode) * 1.05,
"{}: pool round-trip ({scope:.1} ms) must not exceed prepare + read_decode ({:.1} ms) + 5%",
path.label(),
prepare + read_decode
);
RunResult {
label: path.label(),
writers,
wall_ms,
p50_us: p50,
p99_us: p99,
mean_us,
max_us,
useful_cpu_ms: useful,
queue_share_pct: if prepare > 0.0 {
queue / prepare * 100.0
} else {
0.0
},
peak_in_flight: diag.peak_in_flight,
max_consecutive: diag.max_consecutive_same_request,
byte_exact,
}
}
#[test]
fn pool_probe_gates() {
let _guard = workers::tests::POOL_LOCK
.lock()
.expect("pool test lock poisoned");
let files = if cfg!(debug_assertions) { 16 } else { 64 };
let opts = OptimizeOptions::default();
println!("\n==== Phase-11E fair-pool probe (release gates; {files} files) ====");
let sem_alone = run_sweep(&PoolPath::Semaphore, 1, files, opts);
let pool16_alone = run_sweep(&PoolPath::Pool(16), 1, files, opts);
let pool8_alone = run_sweep(&PoolPath::Pool(8), 1, files, opts);
let sem_16 = run_sweep(&PoolPath::Semaphore, 16, files, opts);
let pool16_16 = run_sweep(&PoolPath::Pool(16), 16, files, opts);
let pool8_16 = run_sweep(&PoolPath::Pool(8), 16, files, opts);
let pool4_16 = run_sweep(&PoolPath::Pool(4), 16, files, opts);
let sem_8 = run_sweep(&PoolPath::Semaphore, 8, files, opts);
let pool16_8 = run_sweep(&PoolPath::Pool(16), 8, files, opts);
let pool8_8 = run_sweep(&PoolPath::Pool(8), 8, files, opts);
workers::POOL.disable();
let slowdown =
|r: &RunResult, alone: f64| (r.p50_us / alone, r.p99_us / alone, r.max_us / alone);
let s16 = slowdown(&sem_16, sem_alone.mean_us);
let p16 = slowdown(&pool16_16, pool16_alone.mean_us);
let p8 = slowdown(&pool8_16, pool8_alone.mean_us);
let p4 = slowdown(&pool4_16, pool16_alone.mean_us);
let s8 = slowdown(&sem_8, sem_alone.mean_us);
let p16_8 = slowdown(&pool16_8, pool16_alone.mean_us);
let p8_8 = slowdown(&pool8_8, pool8_alone.mean_us);
println!(
"{:<12} {:>3} {:>8} {:>9} {:>9} {:>9} {:>9} {:>6} {:>6} {:>6} {:>7} {:>7} {:>7}",
"path",
"w",
"wall_ms",
"p50_us",
"p99_us",
"mean_us",
"cpu_ms",
"queue%",
"maxC",
"pkQ",
"med/x",
"p99/x",
"max/x"
);
for (r, slow) in [
(&sem_alone, (0.0f64, 0.0f64, 0.0f64)),
(&pool16_alone, (0.0f64, 0.0f64, 0.0f64)),
(&pool8_alone, (0.0f64, 0.0f64, 0.0f64)),
(&sem_16, s16),
(&pool16_16, p16),
(&pool8_16, p8),
(&pool4_16, p4),
(&sem_8, s8),
(&pool16_8, p16_8),
(&pool8_8, p8_8),
] {
println!(
"{:<12} {:>3} {:>8.0} {:>9.0} {:>9.0} {:>9.0} {:>9.0} {:>5.1}% {:>6} {:>6} {:>6.1}x {:>6.1}x {:>6.1}x {}",
r.label,
r.writers,
r.wall_ms,
r.p50_us,
r.p99_us,
r.mean_us,
r.useful_cpu_ms,
r.queue_share_pct,
r.max_consecutive,
r.peak_in_flight,
slow.0,
slow.1,
slow.2,
if r.byte_exact { "ok" } else { "MISMATCH" },
);
}
for r in [
&sem_alone,
&pool16_alone,
&pool8_alone,
&sem_16,
&pool16_16,
&pool8_16,
&pool4_16,
&sem_8,
&pool16_8,
&pool8_8,
] {
assert!(r.byte_exact, "{}: read-back mismatch", r.label);
}
for r in [&pool16_16, &pool8_16, &pool4_16, &pool16_8, &pool8_8] {
let bound = match r.label.as_str() {
"pool-16" => 16 * 8,
"pool-8" => 8 * 8,
"pool-4" => 4 * 8,
_ => unreachable!(),
};
assert!(
r.peak_in_flight <= bound.max(64),
"{}: queue depth {} exceeded the backpressure bound {bound} (+ the single-request floor)",
r.label,
r.peak_in_flight
);
}
if cfg!(not(debug_assertions)) {
let base_cpu = sem_16.useful_cpu_ms;
let sem_ratio = sem_16.p99_us / sem_16.p50_us;
let passes_16t = |r: &RunResult, slow: &(f64, f64, f64)| {
r.p99_us <= sem_16.p99_us * 0.60
&& r.p50_us <= sem_16.p50_us * 1.20
&& r.wall_ms <= sem_16.wall_ms * 1.03
&& r.useful_cpu_ms <= base_cpu * 1.05
&& r.p99_us / r.p50_us < sem_ratio
&& slow.2 < s16.2
};
let mut passers: Vec<(&str, &RunResult, (f64, f64, f64))> = Vec::new();
if passes_16t(&pool16_16, &p16) {
passers.push(("pool-16", &pool16_16, p16));
}
if passes_16t(&pool8_16, &p8) {
passers.push(("pool-8", &pool8_16, p8));
}
assert!(
!passers.is_empty(),
"16T adoption FAILED: neither pool-16 nor pool-8 passed ALL gates (semaphore: wall {:.1} ms, p50 {:.1} ms, p99 {:.1} ms, CPU {:.0} ms)",
sem_16.wall_ms,
sem_16.p50_us / 1e3,
sem_16.p99_us / 1e3,
sem_16.useful_cpu_ms
);
passers.sort_by_key(|(_, r, _)| r.p99_us as u64);
let (best_label, best, (best_p99_slow, _, best_max_slow)) = passers[0];
let pool_ratio = best.p99_us / best.p50_us;
println!("\n-- gate check: best 16-writer configuration = {best_label} --");
println!(
" p99 {:.1} ms (semaphore {:.1}; ratio {:.2}, gate <= 0.60)",
best.p99_us / 1e3,
sem_16.p99_us / 1e3,
best.p99_us / sem_16.p99_us
);
println!(
" p50 {:.1} ms (semaphore {:.1}; ratio {:.2}, gate <= 1.20)",
best.p50_us / 1e3,
sem_16.p50_us / 1e3,
best.p50_us / sem_16.p50_us
);
println!(
" wall {:.1} ms (semaphore {:.1}; ratio {:.2}, gate <= 1.03)",
best.wall_ms,
sem_16.wall_ms,
best.wall_ms / sem_16.wall_ms
);
let cpu_delta_pct = (best.useful_cpu_ms / base_cpu - 1.0) * 100.0;
println!(
" useful CPU {:.0} ms = {:.1}% (report: the +3% gate; hard assert: the +5% reject bar -> {:.0} ms; semaphore {:.0})",
best.useful_cpu_ms,
cpu_delta_pct,
base_cpu * 1.05,
base_cpu
);
println!(" p99/p50 ratio {pool_ratio:.2} (semaphore {sem_ratio:.2})");
println!(
" max slowdown {best_max_slow:.1}x (semaphore {:.1}x); p99 slowdown {best_p99_slow:.1}x (semaphore {:.1}x)",
s16.2, s16.1
);
let best_8 = if best_label == "pool-8" {
&pool8_8
} else {
&pool16_8
};
let cpu8_delta_pct = (best_8.useful_cpu_ms / sem_8.useful_cpu_ms - 1.0) * 100.0;
println!(
" 8T: p99 {:.1} ms (semaphore {:.1}; ratio {:.2}, gate <= 0.60) wall {:.1} ms (semaphore {:.1}) useful CPU {:.1}% (gate <= +7%; semaphore {:.0})",
best_8.p99_us / 1e3,
sem_8.p99_us / 1e3,
best_8.p99_us / sem_8.p99_us,
best_8.wall_ms,
sem_8.wall_ms,
cpu8_delta_pct,
sem_8.useful_cpu_ms
);
assert!(
best_8.p99_us <= sem_8.p99_us * 0.60,
"8T gate FAILED: {best_label} p99 {:.1} ms not < 0.6x semaphore ({:.1} ms)",
best_8.p99_us / 1e3,
sem_8.p99_us / 1e3
);
assert!(
best_8.wall_ms <= sem_8.wall_ms * 1.10,
"8T gate FAILED: {best_label} wall {:.1} ms > semaphore 8T +10% ({:.1} ms)",
best_8.wall_ms,
sem_8.wall_ms * 1.10
);
assert!(
best_8.useful_cpu_ms <= sem_8.useful_cpu_ms * 1.07,
"8T gate FAILED: {best_label} useful CPU {:.0} ms > semaphore 8T +7% ({:.0} ms)",
best_8.useful_cpu_ms,
sem_8.useful_cpu_ms * 1.07
);
println!("-- 11D adoption gates PASSED for {best_label} --");
} else {
println!("(debug smoke run: gates are release-only, per the 11D evidence rule)");
}
}