Skip to content

Add Zstd "in-place" encoding plugin - #31

Open
gsmecher wants to merge 4 commits into
ketiltrout:masterfrom
gsmecher:zstd
Open

Add Zstd "in-place" encoding plugin#31
gsmecher wants to merge 4 commits into
ketiltrout:masterfrom
gsmecher:zstd

Conversation

@gsmecher

Copy link
Copy Markdown
Contributor

On-line compression (that is, concurrent, reader-visible updates to a compressed dirfile) is a useful and unserved operating point for getdata: network bandwidth is cheap, the SSDs needed to sustain these rates aren't bottomless, and clients like kst rely on low-latency refresh. However, current compression plug-ins are "out-of-place", meaning data isn't visible to readers until the writer has flushed or closed the dirfile -- this doesn't help for interactive uses.

Zstd is an in-place plug-in that compresses in configurable blocks and maintains the existing "read-while-writing" behaviour that RAW fields give. Zstd has a few technical attributes (decompressed size in frame header at the beginning of the frame; skippable metadata frames; frame scans without decompression; checksums) that make it particularly well-suited to this scheme.

The main design quirk in this implementation is the maintenance of an in-memory "seek table" that's built up with a linear frame scan when a file is opened. This frame scan takes ~seconds on multi-GB compressed fields but does grow linearly. It could be improved in a future revision with a journal-type scheme. Another alternative is a "chunking" scheme at the getdata (not encoding) layer that spreads fields across multiple files; this would address similar limitations for other plug-ins as well. Both of these approaches are out-of-scope for now.

Also included are

  • extensions to the "fuzzer" tests that exercise append and mid-stream modifications,
  • pwrite/pread detection to combine lseek()/write() system calls where available, and
  • extension of the encoding open() call to pass in /ENCODING configuration settings.

@gsmecher
gsmecher force-pushed the zstd branch 2 times, most recently from f4a724d to 4f986a6 Compare July 30, 2026 00:00
@gsmecher

Copy link
Copy Markdown
Contributor Author

(Updated to abstract most tests out of copy/paste duplicates of existing tests to the enc_* template framework. There are a few exceptions.)

@gsmecher

gsmecher commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

(adherence to c89 coding style - no mid-body variable declarations, plus a missing use_encdata when writing out zstd field definitions in a fragment)

gsmecher added 3 commits July 29, 2026 19:38
This allows each encoding's open() calls to parse these configuration
options and embed them within the gd_raw_file struct for use later on.
These structs are freed by the associated close().  Because other
encoding API calls are bracketed by open()/close() pairs, memory
ownership is clear. The exception is the encoding.name() call, which
occasionally happens with an unopened field (and hence already receives
the encoding string as a separate argument.)
…sent

Because seek()+read() and seek()+write() are common pairings, adding a
pread/pwrite alternative allows us to cut down on syscall volume.
This is an "in-place" encoding scheme - we are primarily interested in
supporting efficient streaming writes of compressed data (presently only
supported by RAW and SIE).
@gsmecher

Copy link
Copy Markdown
Contributor Author

This latest push

  • removes a fairly insane malloc/patch/write path with open-ended memory requirements for backwards writes;
  • renames and logically groups functions (consistency, readability);
  • removes the use of the "experimental" zstd API (to avoid an extraneous buffer copy which has been avoided another way), and
  • as a result, the zstd minimum version / manylinux version bump / ABI patch knock-on has been avoided.

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