Skip to content

Commit 5d097a7

Browse files
author
Shmiwy
authored
refactor(storage): support zstd compression in block (#2960)
* refactor(storage): support zstd compression in block Signed-off-by: Shmiwy <[email protected]> * refactor(storage): support zstd compression in block Signed-off-by: Shmiwy <[email protected]> * refactor(storage): support zstd compression in block Signed-off-by: Shmiwy <[email protected]>
1 parent f9c548e commit 5d097a7

File tree

4 files changed

+43
-7
lines changed

4 files changed

+43
-7
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/storage/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ tracing = { version = "0.1" }
7070
twox-hash = "1"
7171
value-encoding = { path = "../utils/value-encoding" }
7272
workspace-hack = { version = "0.1", path = "../workspace-hack" }
73+
zstd = "0.11.2"
7374

7475
[target.'cfg(target_os = "linux")'.dependencies]
7576
procinfo = { git = "https://github.com/tikv/procinfo-rs", rev = "6599eb9dca74229b2c1fcc44118bef7eff127128" }

src/storage/src/hummock/sstable/block.rs

+35-7
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use std::io::{Read, Write};
1717
use std::ops::Range;
1818

1919
use bytes::{Buf, BufMut, Bytes, BytesMut};
20-
use lz4::Decoder;
2120
use risingwave_hummock_sdk::VersionedComparator;
21+
use {lz4, zstd};
2222

2323
use super::utils::{
2424
bytes_diff, var_u32_len, xxhash64_verify, BufExt, BufMutExt, CompressionAlgorithm,
@@ -45,17 +45,25 @@ impl Block {
4545

4646
// Decompress.
4747
let compression = CompressionAlgorithm::decode(&mut &buf[buf.len() - 9..buf.len() - 8])?;
48+
let compressed_data = &buf[..buf.len() - 9];
4849
let buf = match compression {
4950
CompressionAlgorithm::None => buf.slice(..buf.len() - 9),
5051
CompressionAlgorithm::Lz4 => {
51-
let mut decoder = Decoder::new(buf.reader())
52-
.map_err(HummockError::decode_error)
53-
.unwrap();
52+
let mut decoder = lz4::Decoder::new(compressed_data.reader())
53+
.map_err(HummockError::decode_error)?;
5454
let mut decoded = Vec::with_capacity(DEFAULT_BLOCK_SIZE);
5555
decoder
5656
.read_to_end(&mut decoded)
57-
.map_err(HummockError::decode_error)
58-
.unwrap();
57+
.map_err(HummockError::decode_error)?;
58+
Bytes::from(decoded)
59+
}
60+
CompressionAlgorithm::Zstd => {
61+
let mut decoder = zstd::Decoder::new(compressed_data.reader())
62+
.map_err(HummockError::decode_error)?;
63+
let mut decoded = Vec::with_capacity(DEFAULT_BLOCK_SIZE);
64+
decoder
65+
.read_to_end(&mut decoded)
66+
.map_err(HummockError::decode_error)?;
5967
Bytes::from(decoded)
6068
}
6169
};
@@ -298,6 +306,21 @@ impl BlockBuilder {
298306
result.map_err(HummockError::encode_error).unwrap();
299307
writer.into_inner()
300308
}
309+
CompressionAlgorithm::Zstd => {
310+
let mut encoder =
311+
zstd::Encoder::new(BytesMut::with_capacity(self.buf.len()).writer(), 4)
312+
.map_err(HummockError::encode_error)
313+
.unwrap();
314+
encoder
315+
.write(&self.buf[..])
316+
.map_err(HummockError::encode_error)
317+
.unwrap();
318+
let writer = encoder
319+
.finish()
320+
.map_err(HummockError::encode_error)
321+
.unwrap();
322+
writer.into_inner()
323+
}
301324
};
302325
self.compression_algorithm.encode(&mut buf);
303326
let checksum = xxhash64_checksum(&buf);
@@ -354,8 +377,13 @@ mod tests {
354377

355378
#[test]
356379
fn test_compressed_block_enc_dec() {
380+
inner_test_compressed(CompressionAlgorithm::Lz4);
381+
inner_test_compressed(CompressionAlgorithm::Zstd);
382+
}
383+
384+
fn inner_test_compressed(algo: CompressionAlgorithm) {
357385
let options = BlockBuilderOptions {
358-
compression_algorithm: CompressionAlgorithm::Lz4,
386+
compression_algorithm: algo,
359387
..Default::default()
360388
};
361389
let mut builder = BlockBuilder::new(options);

src/storage/src/hummock/sstable/utils.rs

+6
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,15 @@ pub fn get_length_prefixed_slice(buf: &mut &[u8]) -> Vec<u8> {
154154
pub enum CompressionAlgorithm {
155155
None,
156156
Lz4,
157+
Zstd,
157158
}
158159

159160
impl CompressionAlgorithm {
160161
pub fn encode(&self, buf: &mut impl BufMut) {
161162
let v = match self {
162163
Self::None => 0,
163164
Self::Lz4 => 1,
165+
Self::Zstd => 2,
164166
};
165167
buf.put_u8(v);
166168
}
@@ -169,6 +171,7 @@ impl CompressionAlgorithm {
169171
match buf.get_u8() {
170172
0 => Ok(Self::None),
171173
1 => Ok(Self::Lz4),
174+
2 => Ok(Self::Zstd),
172175
_ => Err(HummockError::decode_error(
173176
"not valid compression algorithm",
174177
)),
@@ -181,6 +184,7 @@ impl From<CompressionAlgorithm> for u8 {
181184
match ca {
182185
CompressionAlgorithm::None => 0,
183186
CompressionAlgorithm::Lz4 => 1,
187+
CompressionAlgorithm::Zstd => 2,
184188
}
185189
}
186190
}
@@ -190,6 +194,7 @@ impl From<CompressionAlgorithm> for u64 {
190194
match ca {
191195
CompressionAlgorithm::None => 0,
192196
CompressionAlgorithm::Lz4 => 1,
197+
CompressionAlgorithm::Zstd => 2,
193198
}
194199
}
195200
}
@@ -201,6 +206,7 @@ impl TryFrom<u8> for CompressionAlgorithm {
201206
match v {
202207
0 => Ok(Self::None),
203208
1 => Ok(Self::Lz4),
209+
2 => Ok(Self::Zstd),
204210
_ => Err(HummockError::decode_error(
205211
"not valid compression algorithm",
206212
)),

0 commit comments

Comments
 (0)