Skip to content

Commit 03516c2

Browse files
authored
chore: factor out CompressorImpl into separate files (#4319)
Signed-off-by: Roman Gershman <roman@dragonflydb.io>
1 parent 8237d8f commit 03516c2

File tree

5 files changed

+141
-93
lines changed

5 files changed

+141
-93
lines changed

src/server/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ add_library(dragonfly_lib bloom_family.cc
5050
list_family.cc main_service.cc memory_cmd.cc rdb_load.cc rdb_save.cc replica.cc
5151
protocol_client.cc
5252
snapshot.cc script_mgr.cc server_family.cc
53+
detail/compressor.cc
5354
detail/decompress.cc
5455
detail/save_stages_controller.cc
5556
detail/snapshot_storage.cc

src/server/detail/compressor.cc

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright 2024, DragonflyDB authors. All rights reserved.
2+
// See LICENSE for licensing terms.
3+
//
4+
5+
#include "server/detail/compressor.h"
6+
7+
#include <absl/flags/flag.h>
8+
#include <lz4frame.h>
9+
#include <zstd.h>
10+
11+
#include "base/logging.h"
12+
13+
ABSL_FLAG(int, compression_level, 2, "The compression level to use on zstd/lz4 compression");
14+
15+
namespace dfly::detail {
16+
17+
using namespace std;
18+
19+
class ZstdCompressor : public CompressorImpl {
20+
public:
21+
ZstdCompressor() {
22+
cctx_ = ZSTD_createCCtx();
23+
}
24+
~ZstdCompressor() {
25+
ZSTD_freeCCtx(cctx_);
26+
}
27+
28+
io::Result<io::Bytes> Compress(io::Bytes data);
29+
30+
private:
31+
ZSTD_CCtx* cctx_;
32+
base::PODArray<uint8_t> compr_buf_;
33+
};
34+
35+
io::Result<io::Bytes> ZstdCompressor::Compress(io::Bytes data) {
36+
size_t buf_size = ZSTD_compressBound(data.size());
37+
if (compr_buf_.capacity() < buf_size) {
38+
compr_buf_.reserve(buf_size);
39+
}
40+
size_t compressed_size = ZSTD_compressCCtx(cctx_, compr_buf_.data(), compr_buf_.capacity(),
41+
data.data(), data.size(), compression_level_);
42+
43+
if (ZSTD_isError(compressed_size)) {
44+
LOG(ERROR) << "ZSTD_compressCCtx failed with error " << ZSTD_getErrorName(compressed_size);
45+
return nonstd::make_unexpected(make_error_code(errc::operation_not_supported));
46+
}
47+
compressed_size_total_ += compressed_size;
48+
uncompressed_size_total_ += data.size();
49+
return io::Bytes(compr_buf_.data(), compressed_size);
50+
}
51+
52+
class Lz4Compressor : public CompressorImpl {
53+
public:
54+
Lz4Compressor() {
55+
lz4_pref_.compressionLevel = compression_level_;
56+
}
57+
58+
~Lz4Compressor() {
59+
}
60+
61+
// compress a string of data
62+
io::Result<io::Bytes> Compress(io::Bytes data);
63+
64+
private:
65+
LZ4F_preferences_t lz4_pref_ = LZ4F_INIT_PREFERENCES;
66+
};
67+
68+
io::Result<io::Bytes> Lz4Compressor::Compress(io::Bytes data) {
69+
lz4_pref_.frameInfo.contentSize = data.size();
70+
size_t buf_size = LZ4F_compressFrameBound(data.size(), &lz4_pref_);
71+
if (compr_buf_.capacity() < buf_size) {
72+
compr_buf_.reserve(buf_size);
73+
}
74+
75+
size_t frame_size = LZ4F_compressFrame(compr_buf_.data(), compr_buf_.capacity(), data.data(),
76+
data.size(), &lz4_pref_);
77+
if (LZ4F_isError(frame_size)) {
78+
LOG(ERROR) << "LZ4F_compressFrame failed with error " << LZ4F_getErrorName(frame_size);
79+
return nonstd::make_unexpected(make_error_code(errc::operation_not_supported));
80+
}
81+
compressed_size_total_ += frame_size;
82+
uncompressed_size_total_ += data.size();
83+
return io::Bytes(compr_buf_.data(), frame_size);
84+
}
85+
86+
CompressorImpl::CompressorImpl() {
87+
compression_level_ = absl::GetFlag(FLAGS_compression_level);
88+
}
89+
90+
CompressorImpl::~CompressorImpl() {
91+
VLOG(1) << "compressed size: " << compressed_size_total_;
92+
VLOG(1) << "uncompressed size: " << uncompressed_size_total_;
93+
}
94+
95+
unique_ptr<CompressorImpl> CompressorImpl::CreateZstd() {
96+
return make_unique<ZstdCompressor>();
97+
}
98+
99+
unique_ptr<CompressorImpl> CompressorImpl::CreateLZ4() {
100+
return make_unique<Lz4Compressor>();
101+
}
102+
103+
} // namespace dfly::detail

src/server/detail/compressor.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2024, DragonflyDB authors. All rights reserved.
2+
// See LICENSE for licensing terms.
3+
//
4+
5+
#pragma once
6+
7+
#include <memory>
8+
9+
#include "base/pod_array.h"
10+
#include "io/io.h"
11+
12+
namespace dfly::detail {
13+
14+
class CompressorImpl {
15+
public:
16+
static std::unique_ptr<CompressorImpl> CreateZstd();
17+
static std::unique_ptr<CompressorImpl> CreateLZ4();
18+
19+
CompressorImpl();
20+
virtual ~CompressorImpl();
21+
virtual io::Result<io::Bytes> Compress(io::Bytes data) = 0;
22+
23+
protected:
24+
int compression_level_ = 1;
25+
size_t compressed_size_total_ = 0;
26+
size_t uncompressed_size_total_ = 0;
27+
base::PODArray<uint8_t> compr_buf_;
28+
};
29+
30+
} // namespace dfly::detail

src/server/rdb_save.cc

Lines changed: 3 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
#include <absl/cleanup/cleanup.h>
88
#include <absl/strings/str_cat.h>
99
#include <absl/strings/str_format.h>
10-
#include <lz4frame.h>
11-
#include <zstd.h>
1210

1311
#include <queue>
1412

@@ -50,7 +48,6 @@ ABSL_FLAG(dfly::CompressionMode, compression_mode, dfly::CompressionMode::MULTI_
5048
"set 1 for single entry lzf compression,"
5149
"set 2 for multi entry zstd compression on df snapshot and single entry on rdb snapshot,"
5250
"set 3 for multi entry lz4 compression on df snapshot and single entry on rdb snapshot");
53-
ABSL_FLAG(int, compression_level, 2, "The compression level to use on zstd/lz4 compression");
5451

5552
// TODO: to retire both flags in v1.27 (Jan 2025)
5653
ABSL_FLAG(bool, list_rdb_encode_v2, true,
@@ -228,89 +225,6 @@ uint8_t RdbObjectType(const PrimeValue& pv) {
228225
return 0; /* avoid warning */
229226
}
230227

231-
class CompressorImpl {
232-
public:
233-
CompressorImpl() {
234-
compression_level_ = absl::GetFlag(FLAGS_compression_level);
235-
}
236-
virtual ~CompressorImpl() {
237-
VLOG(1) << "compressed size: " << compressed_size_total_;
238-
VLOG(1) << "uncompressed size: " << uncompressed_size_total_;
239-
}
240-
virtual io::Result<io::Bytes> Compress(io::Bytes data) = 0;
241-
242-
protected:
243-
int compression_level_ = 1;
244-
size_t compressed_size_total_ = 0;
245-
size_t uncompressed_size_total_ = 0;
246-
base::PODArray<uint8_t> compr_buf_;
247-
};
248-
249-
class ZstdCompressor : public CompressorImpl {
250-
public:
251-
ZstdCompressor() {
252-
cctx_ = ZSTD_createCCtx();
253-
}
254-
~ZstdCompressor() {
255-
ZSTD_freeCCtx(cctx_);
256-
}
257-
258-
io::Result<io::Bytes> Compress(io::Bytes data);
259-
260-
private:
261-
ZSTD_CCtx* cctx_;
262-
base::PODArray<uint8_t> compr_buf_;
263-
};
264-
265-
io::Result<io::Bytes> ZstdCompressor::Compress(io::Bytes data) {
266-
size_t buf_size = ZSTD_compressBound(data.size());
267-
if (compr_buf_.capacity() < buf_size) {
268-
compr_buf_.reserve(buf_size);
269-
}
270-
size_t compressed_size = ZSTD_compressCCtx(cctx_, compr_buf_.data(), compr_buf_.capacity(),
271-
data.data(), data.size(), compression_level_);
272-
273-
if (ZSTD_isError(compressed_size)) {
274-
return make_unexpected(error_code{int(compressed_size), generic_category()});
275-
}
276-
compressed_size_total_ += compressed_size;
277-
uncompressed_size_total_ += data.size();
278-
return io::Bytes(compr_buf_.data(), compressed_size);
279-
}
280-
281-
class Lz4Compressor : public CompressorImpl {
282-
public:
283-
Lz4Compressor() {
284-
lz4_pref_.compressionLevel = compression_level_;
285-
}
286-
287-
~Lz4Compressor() {
288-
}
289-
290-
// compress a string of data
291-
io::Result<io::Bytes> Compress(io::Bytes data);
292-
293-
private:
294-
LZ4F_preferences_t lz4_pref_ = LZ4F_INIT_PREFERENCES;
295-
};
296-
297-
io::Result<io::Bytes> Lz4Compressor::Compress(io::Bytes data) {
298-
lz4_pref_.frameInfo.contentSize = data.size();
299-
size_t buf_size = LZ4F_compressFrameBound(data.size(), &lz4_pref_);
300-
if (compr_buf_.capacity() < buf_size) {
301-
compr_buf_.reserve(buf_size);
302-
}
303-
304-
size_t frame_size = LZ4F_compressFrame(compr_buf_.data(), compr_buf_.capacity(), data.data(),
305-
data.size(), &lz4_pref_);
306-
if (LZ4F_isError(frame_size)) {
307-
return make_unexpected(error_code{int(frame_size), generic_category()});
308-
}
309-
compressed_size_total_ += frame_size;
310-
uncompressed_size_total_ += data.size();
311-
return io::Bytes(compr_buf_.data(), frame_size);
312-
}
313-
314228
SerializerBase::SerializerBase(CompressionMode compression_mode)
315229
: compression_mode_(compression_mode), mem_buf_{4_KB}, tmp_buf_(nullptr) {
316230
}
@@ -1668,11 +1582,11 @@ void SerializerBase::AllocateCompressorOnce() {
16681582
return;
16691583
}
16701584
if (compression_mode_ == CompressionMode::MULTI_ENTRY_ZSTD) {
1671-
compressor_impl_.reset(new ZstdCompressor());
1585+
compressor_impl_ = detail::CompressorImpl::CreateZstd();
16721586
} else if (compression_mode_ == CompressionMode::MULTI_ENTRY_LZ4) {
1673-
compressor_impl_.reset(new Lz4Compressor());
1587+
compressor_impl_ = detail::CompressorImpl::CreateLZ4();
16741588
} else {
1675-
CHECK(false) << "Compressor allocation should not be done";
1589+
LOG(FATAL) << "Invalid compression mode " << unsigned(compression_mode_);
16761590
}
16771591
}
16781592

src/server/rdb_save.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ extern "C" {
1616
#include "io/io.h"
1717
#include "io/io_buf.h"
1818
#include "server/common.h"
19+
#include "server/detail/compressor.h"
1920
#include "server/journal/serializer.h"
2021
#include "server/journal/types.h"
2122
#include "server/table.h"
@@ -67,7 +68,8 @@ enum class SaveMode {
6768
RDB, // Save .rdb file. Expected to read all shards.
6869
};
6970

70-
enum class CompressionMode { NONE, SINGLE_ENTRY, MULTI_ENTRY_ZSTD, MULTI_ENTRY_LZ4 };
71+
enum class CompressionMode : uint8_t { NONE, SINGLE_ENTRY, MULTI_ENTRY_ZSTD, MULTI_ENTRY_LZ4 };
72+
7173
CompressionMode GetDefaultCompressionMode();
7274

7375
class RdbSaver {
@@ -147,8 +149,6 @@ class RdbSaver {
147149
CompressionMode compression_mode_;
148150
};
149151

150-
class CompressorImpl;
151-
152152
class SerializerBase {
153153
public:
154154
enum class FlushState { kFlushMidEntry, kFlushEndEntry };
@@ -196,7 +196,7 @@ class SerializerBase {
196196

197197
CompressionMode compression_mode_;
198198
io::IoBuf mem_buf_;
199-
std::unique_ptr<CompressorImpl> compressor_impl_;
199+
std::unique_ptr<detail::CompressorImpl> compressor_impl_;
200200

201201
static constexpr size_t kMinStrSizeToCompress = 256;
202202
static constexpr double kMinCompressionReductionPrecentage = 0.95;

0 commit comments

Comments
 (0)