ljar — guide
Class:
guide· Function:ljar. Build, run, tune. The shape is inljar-design.md; the why inljar-reasoning.md. The ZIP-superset twin islzip-parallel-guide.md.
Build
CARGO_TARGET_DIR=/mnt/work4t/cargo-target/zoomies cargo build --release -p ljar
Binary lands at target/release/ljar.
Run
ljar app.jar # extract every entry into ./ (each its own file)
ljar app.jar -o out/ # extract into a target dir
ljar app.jar --filter pom.xml # only entries whose name contains the needle
Any file jar/zip wrote decodes — ljar reads the stock ZIP container (JAR ⊂ ZIP). Entries are extracted to independent files by the parallel writer (gatling::parwrite::extract_entries_unordered, ljar/src/bin/ljar.rs:146); a --filter excludes non-matching entries at the Central Directory level, so they are never read or inflated.
Tune
- Worker count defaults to physical cores; the balanced fan-out self-dispatches with no barrier, so a skewed archive still fills every core (heaviest entry claimed first).
- Streaming decode holds only one 64-entry batch of output live at a time (
BATCH_SIZE,ljar/src/reader.rs:20) — peak RAM stays bounded on huge JARs.
Library
// in-memory decode (parallel; streams internally above 10 MB):
let entries = ljar::decompress_jar(&bytes)?; // ljar/src/lib.rs:65
// only entries containing a needle (filtered before inflate):
let poms = ljar::decompress_jar_filter(&bytes, "pom.xml")?; // ljar/src/lib.rs:83
// stream any Read+Seek without loading the file into RAM:
let f = std::fs::File::open("app.jar")?;
let entries: Vec<_> = ljar::decompress_jar_stream(f)?; // ljar/src/lib.rs:98
Bench
Driven by nornir through the shared harness — see decompressors-guide.md. HEAVY only (no smoke): nornir bench run znippy-zoomies, then nornir docs book znippy-zoomies to fill the A/B/C mashup.