Skip to content

add a deflate compressor; gzip now interops both directions#278

Merged
kacy merged 3 commits into
mainfrom
deflate-compress
Jul 8, 2026
Merged

add a deflate compressor; gzip now interops both directions#278
kacy merged 3 commits into
mainfrom
deflate-compress

Conversation

@kacy

@kacy kacy commented Jul 8, 2026

Copy link
Copy Markdown
Owner

summary

the other half of the deflate project: std.compress.deflate — greedy lz77 over hash chains (3-byte prefixes, 32k window, 258-byte matches, capped chain walks) encoded with the fixed huffman tables (~180 lines). the classic format trap — huffman codes transmit msb-first against an lsb-first writer — is handled by pre-reversing codes.

results

  • 200KB of source: 5.2× smaller
  • runs compress to ~⅓; pseudo-random input stays marginally under input (never balloons)
  • system gunzip reads pith's output byte-identical — proven by a new make gzip-interop-check in ci, completing the loop with the existing pith-reads-system-gzip fixture
  • pith round-trips its own output; empty/one-byte/run edge cases all pass

honest remainder

dynamic huffman trees on the write side would shave a few more percent — documented in limitations as the only refinement left.

what was tested

full suite green (all five golden/interop checks), fixed point byte-identical, seed refreshed, fmt + doc gates clean.

kacy added 3 commits July 8, 2026 11:36
std.compress.deflate closes the other half of the project: greedy
lz77 over hash chains (3-byte prefixes, 32k window, longest match up
to 258 bytes, capped chain walks) encoded with the fixed huffman
tables, so no tree serialization is needed. huffman codes transmit
msb-first against an lsb-first bit writer, so codes are written
pre-reversed — the one classic trap in the format.

gzip.compress now produces real compression: a 200KB source file
packs 5.2x smaller, runs compress to a third of their size, and
pseudo-random input stays marginally under its input size instead of
ballooning. system gunzip reads pith's output byte-identical, and a
new ci check proves that on every push, alongside the existing
pith-reads-system-gzip fixture. the interop regression also asserts
that compression actually shrinks.

limitations now states the true remaining refinement: dynamic huffman
trees on the write side would shave a few more percent.
the std test suite caught what the golden checks could not: is_valid
still validated through the old stored-blocks decompressor, so it
called the new compressor's output invalid. it now asks decompress,
and the dead stored-only path is gone. (local batteries now include
test-std-self-only — ci ran it; mine did not.)
@kacy kacy merged commit 66ccd87 into main Jul 8, 2026
2 checks passed
@kacy kacy deleted the deflate-compress branch July 8, 2026 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant