use std::env;
use zstd::zstd_safe::zstd_sys;
fn repeated_log_lines(len: usize) -> Vec<u8> {
const LINES: &[&str] = &[
"ts=2026-03-26T21:39:28Z level=INFO msg=\"flush memtable\" tenant=demo table=orders region=eu-west\n",
"ts=2026-03-26T21:39:29Z level=INFO msg=\"rotate segment\" tenant=demo table=orders region=eu-west\n",
"ts=2026-03-26T21:39:30Z level=INFO msg=\"compact level\" tenant=demo table=orders region=eu-west\n",
"ts=2026-03-26T21:39:31Z level=INFO msg=\"write block\" tenant=demo table=orders region=eu-west\n",
];
let mut bytes = Vec::with_capacity(len);
while bytes.len() < len {
for line in LINES {
if bytes.len() == len {
break;
}
let remaining = len - bytes.len();
bytes.extend_from_slice(&line.as_bytes()[..line.len().min(remaining)]);
}
}
bytes
}
fn resolve_input(spec: &str) -> Vec<u8> {
if let Some(rest) = spec.strip_prefix("logs") {
let n: usize = rest.parse().expect("logs<N>: N must be a byte count");
repeated_log_lines(n)
} else {
std::fs::read(spec).expect("read input file")
}
}
fn main() {
let args: Vec<String> = env::args().collect();
let level: i32 = args.get(1).and_then(|s| s.parse().ok()).unwrap_or(6);
let iters: u32 = args.get(2).and_then(|s| s.parse().ok()).unwrap_or(300_000);
let input_spec: &str = args.get(3).map(|s| s.as_str()).unwrap_or("logs4096");
let dict_path: &str = args.get(4).map(|s| s.as_str()).expect("dict path required");
let src = resolve_input(input_spec);
let dict = std::fs::read(dict_path).expect("read dict file");
let dst_cap = unsafe { zstd_sys::ZSTD_compressBound(src.len()) };
let mut dst: Vec<u8> = vec![0u8; dst_cap];
let cdict = unsafe {
zstd_sys::ZSTD_createCDict(dict.as_ptr() as *const core::ffi::c_void, dict.len(), level)
};
assert!(!cdict.is_null(), "ZSTD_createCDict failed");
let cctx = unsafe { zstd_sys::ZSTD_createCCtx() };
assert!(!cctx.is_null(), "ZSTD_createCCtx failed");
let mut sink: usize = 0;
for _ in 0..iters {
let rc = unsafe {
zstd_sys::ZSTD_compress_usingCDict(
cctx,
dst.as_mut_ptr() as *mut core::ffi::c_void,
dst_cap,
src.as_ptr() as *const core::ffi::c_void,
src.len(),
cdict,
)
};
assert_eq!(unsafe { zstd_sys::ZSTD_isError(rc) }, 0, "compress failed");
sink = sink.wrapping_add(rc);
core::hint::black_box(&dst);
}
unsafe {
zstd_sys::ZSTD_freeCCtx(cctx);
zstd_sys::ZSTD_freeCDict(cdict);
}
eprintln!(
"ffi encoded {} bytes x {} iters at level {} dict={}; last-out-sum={}",
src.len(),
iters,
level,
dict_path,
sink
);
}