pub struct CompressionContext<M: Matcher = MatchGeneratorDriver> { /* private fields */ }Expand description
A reusable streaming compression context: the settings, the attached
dictionary, the match finder and its buffers, kept from one frame to the
next, with the output handed in on each call rather than owned. The
counterpart of upstream zstd’s ZSTD_CCtx driven by ZSTD_compressStream2.
Settings apply from the next frame on and must be made before its first
write; finish_frame closes the
frame and readies the context for another. A pledged size belongs to one
frame; every other setting, the dictionary included, stays until replaced.
A frame that fails leaves the context failed: every later call reports
that failure, and a new context is needed.
Reusing a context produces the same frames as a fresh
StreamingEncoder per frame, without rebuilding the match finder’s
tables or re-attaching the dictionary for each of them.
§Examples
use structured_zstd::encoding::{CompressionContext, CompressionLevel};
let mut context = CompressionContext::new(CompressionLevel::Default);
let mut frames = Vec::new();
for payload in [&b"first frame"[..], b"second frame"] {
let mut frame = Vec::new();
context.set_pledged_content_size(payload.len() as u64).unwrap();
context.write(&mut frame, payload).unwrap();
context.finish_frame(&mut frame).unwrap();
frames.push(frame);
}
use std::io::Read;
let mut decoder = structured_zstd::decoding::StreamingDecoder::new(&frames[1][..]).unwrap();
let mut decoded = Vec::new();
decoder.read_to_end(&mut decoded).unwrap();
assert_eq!(decoded, b"second frame");Implementations§
Source§impl CompressionContext<MatchGeneratorDriver>
impl CompressionContext<MatchGeneratorDriver>
Sourcepub fn new(compression_level: CompressionLevel) -> Self
pub fn new(compression_level: CompressionLevel) -> Self
Creates a context backed by the default match generator, compressing
at compression_level.
Sourcepub fn set_parameters(
&mut self,
params: &CompressionParameters,
) -> Result<(), Error>
pub fn set_parameters( &mut self, params: &CompressionParameters, ) -> Result<(), Error>
Configure fine-grained compression parameters (#27): resets the level to
the parameters’ level and installs the per-knob overrides (window / hash
/ chain / search logs, strategy, long-distance matching) applied at the
next frame. Mirrors FrameCompressor::set_parameters.
Must be called before the frame’s first write. Only the
built-in MatchGeneratorDriver exposes the override knobs, so this
lives on the default-matcher impl.
Source§impl<M: Matcher> CompressionContext<M>
impl<M: Matcher> CompressionContext<M>
Sourcepub fn new_with_matcher(matcher: M, compression_level: CompressionLevel) -> Self
pub fn new_with_matcher(matcher: M, compression_level: CompressionLevel) -> Self
Creates a context with an explicitly provided matcher implementation.
This constructor is primarily intended for tests and advanced callers that need custom match-window behavior.
Sourcepub fn set_compression_level(
&mut self,
level: CompressionLevel,
) -> Result<(), Error>
pub fn set_compression_level( &mut self, level: CompressionLevel, ) -> Result<(), Error>
Compress the next frames at level, with the level’s own tuning: any
parameter override installed by
set_parameters is dropped, as
FrameCompressor::set_compression_level
drops it. Must be called before the frame’s first write.
§Examples
use structured_zstd::encoding::{CompressionContext, CompressionLevel};
let mut context = CompressionContext::new(CompressionLevel::Fastest);
context.set_compression_level(CompressionLevel::Better).unwrap();
let mut frame = Vec::new();
context.write(&mut frame, b"compressed at the new level").unwrap();
context.finish_frame(&mut frame).unwrap();Sourcepub fn set_target_block_size(
&mut self,
target: Option<u32>,
) -> Result<(), Error>
pub fn set_target_block_size( &mut self, target: Option<u32>, ) -> Result<(), Error>
Set an upper bound on each physical block’s payload (semantics of
upstream ZSTD_c_targetCBlockSize): every block carries at most
target payload bytes, +3-byte block header on the wire — the
upstream knob is likewise a convergence target for block sizing,
not a cap on header-inclusive wire bytes. Clamped to
[MIN_TARGET_BLOCK_SIZE, MAX_BLOCK_SIZE]; mirrors
FrameCompressor::set_target_block_size. Must be set before the
frame’s first write.
Sourcepub fn set_content_checksum(&mut self, emit: bool) -> Result<(), Error>
pub fn set_content_checksum(&mut self, emit: bool) -> Result<(), Error>
Enable or disable the trailing XXH64 content checksum
(upstream ZSTD_c_checksumFlag). Default false, matching the
upstream library default (ZSTD_c_checksumFlag = 0). Must be called
before the frame’s first write; once the frame header
is emitted the flag is fixed, so a late change returns an error rather
than producing a header/trailer mismatch. Without the hash feature
no checksum is emitted regardless.
Sourcepub fn set_magicless(&mut self, magicless: bool) -> Result<(), Error>
pub fn set_magicless(&mut self, magicless: bool) -> Result<(), Error>
Enable or disable magicless frame format (ZSTD_f_zstd1_magicless).
When set to true, the frame header omits the 4-byte magic number
prefix. Must be called BEFORE the frame’s first write
call; calling it after the frame header has already been emitted
returns an error so the caller can’t be misled into thinking they
produced a magicless stream.
Sourcepub fn set_pledged_content_size(&mut self, size: u64) -> Result<(), Error>
pub fn set_pledged_content_size(&mut self, size: u64) -> Result<(), Error>
Pledge the total uncompressed content size of the next frame.
When set, the frame header will include a Frame_Content_Size field.
This enables decoders to pre-allocate output buffers.
The pledged size is also forwarded as a source-size hint to the
matcher so small inputs can use smaller matching tables.
Must be called before the frame’s first write;
calling it after the frame header has already been emitted returns an
error. The pledge ends with the frame.
Sourcepub fn set_content_size_flag(&mut self, emit: bool) -> Result<(), Error>
pub fn set_content_size_flag(&mut self, emit: bool) -> Result<(), Error>
Control whether the pledged size is written into the header’s
Frame_Content_Size field (upstream ZSTD_c_contentSizeFlag,
default on). With the flag off the header omits the field, but a
pledge set via set_pledged_content_size
is still enforced against the bytes actually written. Must be
called before the frame’s first write.
Sourcepub fn set_source_size_hint(&mut self, size: u64) -> Result<(), Error>
pub fn set_source_size_hint(&mut self, size: u64) -> Result<(), Error>
Provide a hint about the total uncompressed size of each frame.
Unlike set_pledged_content_size,
this does not enforce that exactly size bytes are written; it
may reduce matcher tables, advertised frame window, and block sizing
for small inputs. A parameter, like upstream ZSTD_c_srcSizeHint: it
applies to every frame until replaced. Must be called before the
frame’s first write.
Sourcepub fn set_dictionary_from_bytes(
&mut self,
raw_dictionary: &[u8],
) -> Result<(), Error>
pub fn set_dictionary_from_bytes( &mut self, raw_dictionary: &[u8], ) -> Result<(), Error>
Attach a dictionary blob to each frame (upstream zstd
ZSTD_CCtx_loadDictionary on a streaming context, which loads in
ZSTD_dct_auto mode): a blob prefixed with
DICTIONARY_MAGIC is a serialized
dictionary, anything else is raw content. The dictionary primes the
match-finder and seeds the first block’s entropy tables + repeat
offsets; a serialized one’s ID is written into the frame header, while
raw content has none to write, so the decoder must be given the same
bytes explicitly. Must be called before the frame’s first
write; repeat offsets must be non-zero.
Sourcepub fn set_dictionary_id_flag(&mut self, emit: bool) -> Result<(), Error>
pub fn set_dictionary_id_flag(&mut self, emit: bool) -> Result<(), Error>
Whether the frame header records the attached dictionary’s ID
(upstream ZSTD_c_dictIDFlag semantics; default true).
Mirrors FrameCompressor::set_dictionary_id_flag.
Decoders can still decode such frames by supplying the dictionary
explicitly.
Sourcepub fn set_encoder_dictionary(
&mut self,
dict: EncoderDictionary,
) -> Result<(), Error>
pub fn set_encoder_dictionary( &mut self, dict: EncoderDictionary, ) -> Result<(), Error>
Attach an already-parsed EncoderDictionary to each frame. See
set_dictionary_from_bytes; must be
called before the frame’s first write. The entropy tables it seeds were
built when it was prepared, so attaching builds nothing.
Sourcepub fn dictionary(&self) -> Option<&EncoderDictionary>
pub fn dictionary(&self) -> Option<&EncoderDictionary>
The dictionary each frame is compressed with, if one is attached.
§Examples
use structured_zstd::encoding::{CompressionContext, CompressionLevel, EncoderDictionary};
let dictionary = EncoderDictionary::from_serialized_or_raw_content(b"some shared history").unwrap();
let mut context = CompressionContext::new(CompressionLevel::Default);
assert!(context.dictionary().is_none());
context.set_encoder_dictionary(dictionary).unwrap();
assert!(context.dictionary().is_some());Sourcepub fn heap_size(&self) -> usize
pub fn heap_size(&self) -> usize
Total heap bytes this context’s allocations hold, excluding the inline
struct: match-finder tables / history / recycled buffers, retained
Huffman tables, the staging pending / encoded_scratch buffers, the
retained dictionary content, and its entropy tables. Mirrors
FrameCompressor::heap_size so a context can report its true
footprint through ZSTD_sizeof_CCtx.
Sourcepub fn write<D: Write + ?Sized>(
&mut self,
drain: &mut D,
buf: &[u8],
) -> Result<usize, Error>
pub fn write<D: Write + ?Sized>( &mut self, drain: &mut D, buf: &[u8], ) -> Result<usize, Error>
Compress buf into the frame in progress, starting one (and writing
its header to drain) if none is. Full blocks are compressed as they
fill and written to drain; the rest stays buffered for the next call,
flush or finish_frame.
Returns how much of buf was taken, which is all of it unless a pledge
set with set_pledged_content_size
allows less.
Sourcepub fn flush<D: Write + ?Sized>(&mut self, drain: &mut D) -> Result<(), Error>
pub fn flush<D: Write + ?Sized>(&mut self, drain: &mut D) -> Result<(), Error>
Emit the buffered partial block as a non-last block and flush drain.
Sourcepub fn finish_frame<D: Write + ?Sized>(
&mut self,
drain: &mut D,
) -> Result<(), Error>
pub fn finish_frame<D: Write + ?Sized>( &mut self, drain: &mut D, ) -> Result<(), Error>
Close the frame in progress into drain: its last block, then its
checksum when enabled. A frame nothing was written to is still a valid
empty frame. The context is then ready for the next frame, with every
setting and the dictionary as they were and the pledge cleared.
Sourcepub fn abandon_frame(&mut self)
pub fn abandon_frame(&mut self)
Drop the frame in progress without closing it (upstream
ZSTD_CCtx_reset(ZSTD_reset_session_only)): its buffered input and its
pledge go, and the next write starts a new frame. The
settings, the dictionary and every allocation stay. What the frame
already wrote to its drain stays there, an unfinished frame.
This is the way on from a finish_frame refused
for a pledge the frame did not meet, when the rest of the input is not
coming; writing it and finishing again completes the frame instead.
§Examples
use structured_zstd::encoding::{CompressionContext, CompressionLevel};
let mut context = CompressionContext::new(CompressionLevel::Default);
let mut unfinished = Vec::new();
context.set_pledged_content_size(100).unwrap();
context.write(&mut unfinished, b"only part of it").unwrap();
assert!(context.finish_frame(&mut unfinished).is_err());
context.abandon_frame();
let mut frame = Vec::new();
context.write(&mut frame, b"a frame of its own").unwrap();
context.finish_frame(&mut frame).unwrap();