compression_codecs/zstd/params.rs
1//! This module contains zstd-specific types for async-compression.
2
3use compression_core::Level;
4
5/// A compression parameter for zstd. This is a stable wrapper around zstd's own `CParameter`
6/// type, to abstract over different versions of the zstd library.
7///
8/// See the [zstd documentation](https://facebook.github.io/zstd/zstd_manual.html) for more
9/// information on these parameters.
10#[derive(Copy, Clone, Debug, PartialEq, Eq)]
11pub struct CParameter(libzstd::stream::raw::CParameter);
12
13impl From<CParameter> for libzstd::stream::raw::CParameter {
14 fn from(value: CParameter) -> Self {
15 value.0
16 }
17}
18
19impl CParameter {
20 pub fn quality(level: Level) -> i32 {
21 let (fastest, best) = libzstd::compression_level_range().into_inner();
22
23 // NOTE: zstd's "fastest" level is -131072 which can create outputs larger than inputs.
24 // This library chooses a "fastest" level which has a more-or-less equivalent compression
25 // ratio to gzip's fastest mode. We still allow precise levels to go negative.
26 // See discussion in https://github.com/Nullus157/async-compression/issues/352
27 const OUR_FASTEST: i32 = 1;
28
29 match level {
30 Level::Fastest => OUR_FASTEST,
31 Level::Best => best,
32 Level::Precise(quality) => quality.clamp(fastest, best),
33 _ => libzstd::DEFAULT_COMPRESSION_LEVEL,
34 }
35 }
36
37 /// Window size in bytes (as a power of two)
38 pub fn window_log(value: u32) -> Self {
39 Self(libzstd::stream::raw::CParameter::WindowLog(value))
40 }
41
42 /// Size of the initial probe table in 4-byte entries (as a power of two)
43 pub fn hash_log(value: u32) -> Self {
44 Self(libzstd::stream::raw::CParameter::HashLog(value))
45 }
46
47 /// Size of the multi-probe table in 4-byte entries (as a power of two)
48 pub fn chain_log(value: u32) -> Self {
49 Self(libzstd::stream::raw::CParameter::ChainLog(value))
50 }
51
52 /// Number of search attempts (as a power of two)
53 pub fn search_log(value: u32) -> Self {
54 Self(libzstd::stream::raw::CParameter::SearchLog(value))
55 }
56
57 /// Minimum size of matches searched for
58 pub fn min_match(value: u32) -> Self {
59 Self(libzstd::stream::raw::CParameter::MinMatch(value))
60 }
61
62 /// Strategy-dependent length modifier
63 pub fn target_length(value: u32) -> Self {
64 Self(libzstd::stream::raw::CParameter::TargetLength(value))
65 }
66
67 /// Enable long-distance matching mode to look for and emit long-distance references.
68 ///
69 /// This increases the default window size.
70 pub fn enable_long_distance_matching(value: bool) -> Self {
71 Self(libzstd::stream::raw::CParameter::EnableLongDistanceMatching(value))
72 }
73
74 /// Size of the long-distance matching table (as a power of two)
75 pub fn ldm_hash_log(value: u32) -> Self {
76 Self(libzstd::stream::raw::CParameter::LdmHashLog(value))
77 }
78
79 /// Minimum size of long-distance matches searched for
80 pub fn ldm_min_match(value: u32) -> Self {
81 Self(libzstd::stream::raw::CParameter::LdmMinMatch(value))
82 }
83
84 /// Size of each bucket in the LDM hash table for collision resolution (as a power of two)
85 pub fn ldm_bucket_size_log(value: u32) -> Self {
86 Self(libzstd::stream::raw::CParameter::LdmBucketSizeLog(value))
87 }
88
89 /// Frequency of using the LDM hash table (as a power of two)
90 pub fn ldm_hash_rate_log(value: u32) -> Self {
91 Self(libzstd::stream::raw::CParameter::LdmHashRateLog(value))
92 }
93
94 /// Emit the size of the content (default: true).
95 pub fn content_size_flag(value: bool) -> Self {
96 Self(libzstd::stream::raw::CParameter::ContentSizeFlag(value))
97 }
98
99 /// Emit a checksum (default: false).
100 pub fn checksum_flag(value: bool) -> Self {
101 Self(libzstd::stream::raw::CParameter::ChecksumFlag(value))
102 }
103
104 /// Emit a dictionary ID when using a custom dictionary (default: true).
105 pub fn dict_id_flag(value: bool) -> Self {
106 Self(libzstd::stream::raw::CParameter::DictIdFlag(value))
107 }
108
109 /// Number of threads to spawn.
110 ///
111 /// If set to 0, compression functions will block; if set to 1 or more, compression will
112 /// run in background threads and `flush` pushes bytes through the compressor.
113 ///
114 /// # Panics
115 ///
116 /// This parameter requires feature `zstdmt` to be enabled, otherwise it will cause a panic
117 /// when used in `ZstdEncoder::with_quality_and_params()` calls.
118 //
119 // TODO: make this a normal feature guarded fn on next breaking release
120 #[cfg_attr(docsrs, doc(cfg(feature = "zstdmt")))]
121 pub fn nb_workers(value: u32) -> Self {
122 Self(libzstd::stream::raw::CParameter::NbWorkers(value))
123 }
124
125 /// Number of bytes given to each worker.
126 ///
127 /// If set to 0, zstd selects a job size based on compression parameters.
128 pub fn job_size(value: u32) -> Self {
129 Self(libzstd::stream::raw::CParameter::JobSize(value))
130 }
131
132 pub(crate) fn as_zstd(&self) -> libzstd::stream::raw::CParameter {
133 self.0
134 }
135}
136
137/// A decompression parameter for zstd. This is a stable wrapper around zstd's own `DParameter`
138/// type, to abstract over different versions of the zstd library.
139///
140/// See the [zstd documentation](https://facebook.github.io/zstd/zstd_manual.html) for more
141/// information on these parameters.
142#[derive(Copy, Clone, Debug, PartialEq, Eq)]
143pub struct DParameter(libzstd::stream::raw::DParameter);
144
145impl DParameter {
146 /// Maximum window size in bytes (as a power of two)
147 pub fn window_log_max(value: u32) -> Self {
148 Self(libzstd::stream::raw::DParameter::WindowLogMax(value))
149 }
150
151 pub(crate) fn as_zstd(&self) -> libzstd::stream::raw::DParameter {
152 self.0
153 }
154}