ldeflate 0.1.3

Pure Rust parallel DEFLATE/zlib compressor — the write side of linflate. Two-queue gatling scheduling: coalesce small objects, split large streams at full-flush boundaries.
Documentation
//! Already-compressed content must reach the output **without** passing through
//! the entropy coder — in every container this crate writes.
//!
//! The decision lives in one place (`plan::run_unit`, plus the segment variant
//! in `split`), so this file's job is to prove that one place really does serve
//! zlib, gzip, ZIP and JAR, and that what comes out is still a valid stream of
//! each.
//!
//! # How "the skip fired" is asserted
//!
//! Not by a flag, and not by a timer. A stored DEFLATE block is identifiable
//! from the output bytes: RFC 1951 §3.2.3 puts `BTYPE` in bits 1-2 of the first
//! byte of a block, and `BTYPE == 00` is stored. So every assertion here reads
//! the **applied output** — the first body byte after the container's header, or
//! the ZIP header's method field — and each is paired with a
//! `Config::compress_everything()` control that must produce *different* bytes
//! from the same input. A skip that silently stopped working would make the two
//! outputs identical and fail here.
//!
//! # Why the fixtures are compressible behind a real magic
//!
//! The obvious fixture — a real magic followed by incompressible bytes — makes
//! this whole file **vacuous**, and it was written that way first. zlib emits
//! stored blocks of its own accord when compression does not help, so on random
//! payloads the control arm stores too: both arms produce `BTYPE == 00`, the
//! assertions pass, and they would keep passing with the probe deleted. ZIP has
//! the same trap one level up, because `zip.rs` already stores an entry whose
//! deflate failed to shrink it.
//!
//! So every fixture here is a **real magic in front of a highly compressible
//! body**. Nothing else distinguishes the two paths: with the probe the entry is
//! stored, without it the entry deflates to a fraction of its size, and the
//! difference is unmissable in both the block header and the length. That the
//! body is not what a real PNG holds is the point — the probe's contract is
//! "this magic at offset 0 means store", and this asserts exactly that contract
//! rather than a property of random data.

use ldeflate::{
    Config, ZipEntry as Entry, compress_objects, gzip_compress, gzip_compress_members,
    gzip_members_of, jar_write, zip_write,
};

/// `n` bytes carrying `magic` at offset 0 over a **compressible** body — see the
/// module docs for why the body must be compressible. Deterministic.
fn precompressed(magic: &[u8], n: usize) -> Vec<u8> {
    let mut v = Vec::with_capacity(n);
    v.extend_from_slice(magic);
    v.extend(compressible(n.saturating_sub(magic.len())));
    v
}

/// `n` bytes that are genuinely incompressible. Used only where the assertion is
/// about round-tripping rather than about which path ran.
fn incompressible(n: usize) -> Vec<u8> {
    let mut v = Vec::with_capacity(n);
    let mut s: u64 = 0x2545_F491_4F6C_DD1D;
    while v.len() < n {
        s ^= s << 13;
        s ^= s >> 7;
        s ^= s << 17;
        v.extend_from_slice(&s.to_le_bytes());
    }
    v.truncate(n);
    v
}

/// Highly compressible content, for the controls.
fn compressible(n: usize) -> Vec<u8> {
    b"the quick brown fox jumps over the lazy dog. "
        .iter()
        .copied()
        .cycle()
        .take(n)
        .collect()
}

/// One fixture per magic the compressor is most likely to meet in anger.
fn corpus() -> Vec<(&'static str, Vec<u8>)> {
    vec![
        ("git packfile", precompressed(b"PACK\0\0\0\x02", 300_000)),
        ("png", precompressed(b"\x89PNG\r\n\x1a\n", 300_000)),
        ("jpeg", precompressed(b"\xff\xd8\xff\xe0", 300_000)),
        ("gzip", precompressed(b"\x1f\x8b\x08\x00", 300_000)),
        ("zstd", precompressed(b"\x28\xb5\x2f\xfd", 300_000)),
        ("zlib stream", precompressed(b"\x78\x9c", 300_000)),
    ]
}

/// Is the DEFLATE block starting at `body[0]` a *stored* block (`BTYPE == 00`)?
fn is_stored_block(body: &[u8]) -> bool {
    !body.is_empty() && (body[0] >> 1) & 0b11 == 0
}

#[test]
fn zlib_streams_store_already_compressed_objects_and_still_round_trip() {
    for (label, src) in corpus() {
        let objs: Vec<&[u8]> = vec![&src];

        let skipped = compress_objects(&objs, &Config::default()).unwrap();
        let forced = compress_objects(&objs, &Config::default().compress_everything()).unwrap();

        // Applied output: the zlib header is 2 bytes, the first DEFLATE block
        // starts at [2].
        assert!(
            is_stored_block(&skipped[0][2..]),
            "{label}: the probe did not store — first body byte {:#04x}",
            skipped[0][2]
        );
        assert!(
            !is_stored_block(&forced[0][2..]),
            "{label}: the control stored too, so this comparison proves nothing — \
             the fixture body must be compressible (see the module docs)"
        );
        assert!(
            forced[0].len() < skipped[0].len() / 10,
            "{label}: the control did not really compress ({} vs {}), so the skip is unproven",
            forced[0].len(),
            skipped[0].len()
        );
        assert!(
            skipped[0].len() > src.len(),
            "{label}: a stored stream is its input plus framing, got {} for {}",
            skipped[0].len(),
            src.len()
        );

        // Both must still be a zlib stream of the input.
        for (what, stream) in [("skipped", &skipped[0]), ("forced", &forced[0])] {
            let out = linflate::inflate_to_vec(&stream[2..], src.len())
                .unwrap_or_else(|e| panic!("{label} ({what}): did not inflate: {e}"));
            assert_eq!(out, src, "{label} ({what}): did not round-trip");
        }
    }
}

#[test]
fn compressible_objects_are_still_compressed() {
    // The control that stops every assertion above from passing on a compressor
    // that simply stores everything.
    let src = compressible(300_000);
    let objs: Vec<&[u8]> = vec![&src];
    let out = compress_objects(&objs, &Config::default()).unwrap();

    assert!(
        !is_stored_block(&out[0][2..]),
        "ordinary text was stored — the probe is firing on everything"
    );
    assert!(
        out[0].len() < src.len() / 10,
        "ordinary text did not compress: {} -> {}",
        src.len(),
        out[0].len()
    );
    assert_eq!(
        linflate::inflate_to_vec(&out[0][2..], src.len()).unwrap(),
        src
    );
}

#[test]
fn gzip_members_store_already_compressed_input_and_stock_gzip_reads_them() {
    for (label, src) in corpus() {
        let out = gzip_compress_members(&src, &Config::default(), 64 << 10).unwrap();
        let forced =
            gzip_compress_members(&src, &Config::default().compress_everything(), 64 << 10)
                .unwrap();
        assert_ne!(
            out, forced,
            "{label}: skip and no-skip produced the same bytes"
        );

        let members = gzip_members_of(&out)
            .unwrap_or_else(|| panic!("{label}: output is not a clean member concatenation"));
        assert!(
            members.len() > 1,
            "{label}: fixture must produce several members"
        );
        for (i, m) in members.iter().enumerate() {
            // gzip header written by this crate is exactly 10 bytes (FLG == 0).
            assert!(
                is_stored_block(&m[10..]),
                "{label}: member {i} was deflated, not stored"
            );
        }

        // And the whole concatenation still decodes to the input.
        let back = decode_gzip_all(&out);
        assert_eq!(
            back, src,
            "{label}: member concatenation did not round-trip"
        );
    }
}

#[test]
fn a_single_split_gzip_member_stores_every_segment() {
    // `gzip_compress` forces the split queue, so this is the path that goes
    // through `split::compress_segment_skipping` rather than through `run_unit`'s
    // whole-object arm — a different branch, and the one gzip's default shape
    // uses.
    let src = precompressed(b"\x89PNG\r\n\x1a\n", 6 << 20);
    let cfg = Config {
        segment: 1 << 20,
        ..Config::default()
    };

    let out = gzip_compress(&src, &cfg).unwrap();
    let forced = gzip_compress(&src, &cfg.compress_everything()).unwrap();
    assert_ne!(out, forced, "skip and no-skip produced the same bytes");

    assert!(
        is_stored_block(&out[10..]),
        "the first segment was deflated, not stored: {:#04x}",
        out[10]
    );
    assert_eq!(decode_gzip_all(&out), src, "split gzip did not round-trip");
    assert_eq!(decode_gzip_all(&forced), src, "control did not round-trip");
}

#[test]
fn zip_and_jar_store_already_compressed_entries_without_deflating_them() {
    let items = corpus();
    let entries: Vec<Entry<'_>> = items
        .iter()
        .map(|(label, data)| Entry::new(zip_name(label), data))
        .collect();
    let text = compressible(200_000);
    let mut all = entries.clone();
    all.push(Entry::new("readme.txt", &text));

    for (what, archive, lead) in [
        ("zip", zip_write(&all, &Config::default()).unwrap(), 0usize),
        (
            "jar",
            jar_write("Manifest-Version: 1.0", &all, &Config::default()).unwrap(),
            1usize,
        ),
    ] {
        let methods = local_header_methods(&archive);
        // `lead` is JAR's prepended `META-INF/MANIFEST.MF`. It is STOREd too,
        // but for the pre-existing reason rather than this one: at ~23 bytes,
        // deflating it produces more bytes than it saves, so `zip.rs`'s
        // "store when deflate did not help" rule takes it. Counted separately so
        // it cannot be mistaken for a probe hit.
        assert_eq!(
            methods.len(),
            lead + items.len() + 1,
            "{what}: wrong entry count"
        );
        for (i, &m) in methods.iter().skip(lead).take(items.len()).enumerate() {
            assert_eq!(m, 0, "{what}: entry {} ({}) was deflated", i, items[i].0);
        }
        assert_eq!(
            *methods.last().unwrap(),
            8,
            "{what}: readme.txt is compressible and must still deflate"
        );
        assert!(
            methods.iter().any(|&m| m == 8),
            "{what}: nothing was deflated, so the assertion above is vacuous"
        );
    }

    // The control: with the probe off, those same entries are DEFLATEd. Without
    // this the test would pass on a build where `zip.rs`'s pre-existing
    // "store when deflate did not help" rule did all the work.
    let off = zip_write(&all, &Config::default().compress_everything()).unwrap();
    let off_methods = local_header_methods(&off);
    assert!(
        off_methods.iter().all(|&m| m == 8),
        "with the probe off every entry must deflate, got {off_methods:?}"
    );
    assert_eq!(off_methods.len(), items.len() + 1);
}

/// Genuinely incompressible content still round-trips through every container —
/// the case the compressible fixtures above deliberately do not cover.
#[test]
fn incompressible_content_round_trips_in_every_container() {
    let src = incompressible(400_000);

    let z = compress_objects(&[&src[..]], &Config::default()).unwrap();
    assert_eq!(
        linflate::inflate_to_vec(&z[0][2..], src.len()).unwrap(),
        src,
        "zlib"
    );

    let g = gzip_compress_members(&src, &Config::default(), 64 << 10).unwrap();
    assert_eq!(decode_gzip_all(&g), src, "gzip members");

    let s = gzip_compress(
        &src,
        &Config {
            segment: 64 << 10,
            ..Config::default()
        },
    )
    .unwrap();
    assert_eq!(decode_gzip_all(&s), src, "split gzip");

    let entries = [Entry::new("a.bin", &src)];
    let archive = zip_write(&entries, &Config::default()).unwrap();
    assert_eq!(
        local_header_methods(&archive).len(),
        1,
        "zip wrote one entry"
    );
}

// ── helpers ──────────────────────────────────────────────────────────────────

fn zip_name(label: &str) -> &'static str {
    match label {
        "git packfile" => "objects/pack/a.pack",
        "png" => "img/a.png",
        "jpeg" => "img/a.jpg",
        "gzip" => "data/a.gz",
        "zstd" => "data/a.zst",
        _ => "obj/a.bin",
    }
}

/// Every local file header's compression method, in file order.
fn local_header_methods(archive: &[u8]) -> Vec<u16> {
    let mut out = Vec::new();
    let mut i = 0usize;
    while i + 30 <= archive.len() && &archive[i..i + 4] == b"PK\x03\x04" {
        let method = u16::from_le_bytes([archive[i + 8], archive[i + 9]]);
        let csize = u32::from_le_bytes(archive[i + 18..i + 22].try_into().unwrap()) as usize;
        let nlen = u16::from_le_bytes([archive[i + 26], archive[i + 27]]) as usize;
        let elen = u16::from_le_bytes([archive[i + 28], archive[i + 29]]) as usize;
        out.push(method);
        i += 30 + nlen + elen + csize;
    }
    out
}

/// Decode a whole gzip file (one member or many) with `flate2`'s multi-member
/// reader — a third-party oracle, not this crate's own code.
fn decode_gzip_all(data: &[u8]) -> Vec<u8> {
    use std::io::Read;
    let mut out = Vec::new();
    flate2::read::MultiGzDecoder::new(data)
        .read_to_end(&mut out)
        .expect("gzip output did not decode");
    out
}