1
0
mirror of https://github.com/facebook/rocksdb.git synced 2026-10-23 08:09:02 +03:00

Remove obsolete compression code and some .h->.cc movement (#14325)

Summary:
In follow-up to https://github.com/facebook/rocksdb/issues/14315

Remove obsolete code replaced by new Compressor/Decompressor interface:
* OLD_CompressData and OLD_UncompressData
* Individual compression/decompression functions (Snappy_*, Zlib_*, BZip2_*, LZ4_*, LZ4HC_*, XPRESS_*, ZSTD_Compress, ZSTD_Uncompress)
* CompressionInfo and UncompressionInfo classes
* UncompressionDict class
* compression::PutDecompressedSizeInfo and GetDecompressedSizeInfo

The only small refactoring in this change that is not pure code removal or movement is in blob_file_builder_test.cc.

Move some function implementations etc. from compression.h to compression.cc:
* CompressionTypeToString, CompressionTypeFromString, CompressionOptionsToString
* ZSTD_TrainDictionary (both overloads), ZSTD_FinalizeDictionary
* DecompressorDict::Populate
* Most compression library includes

Also cleaned up other includes of compression.h, which caused some other files to need new includes.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/14325

Test Plan: existing tests

Reviewed By: hx235

Differential Revision: D93120580

Pulled By: pdillinger

fbshipit-source-id: ab5c50db7379c0387a8c0e379642c9ea2799eae5
This commit is contained in:
Peter Dillinger
2026-02-13 11:18:05 -08:00
committed by meta-codesync[bot]
parent c33a4989ad
commit 672389fd8c
10 changed files with 278 additions and 1319 deletions

View File

@@ -403,22 +403,19 @@ TEST_F(BlobFileBuilderTest, Compression) {
ASSERT_EQ(blob_file_addition.GetBlobFileNumber(), blob_file_number);
ASSERT_EQ(blob_file_addition.GetTotalBlobCount(), 1);
CompressionOptions opts;
CompressionContext context(kSnappyCompression, opts);
CompressionInfo info(opts, context, CompressionDict::GetEmptyDict(),
kSnappyCompression);
std::string compressed_value;
ASSERT_TRUE(Snappy_Compress(info, uncompressed_value.data(),
uncompressed_value.size(), &compressed_value));
auto compressor =
GetBuiltinV2CompressionManager()->GetCompressor({}, kSnappyCompression);
GrowableBuffer compressed_value;
ASSERT_OK(LegacyForceBuiltinCompression(*compressor, /*working_area=*/nullptr,
uncompressed_value,
&compressed_value));
ASSERT_EQ(blob_file_addition.GetTotalBlobBytes(),
BlobLogRecord::kHeaderSize + key_size + compressed_value.size());
// Verify the contents of the new blob file as well as the blob reference
std::vector<std::pair<std::string, std::string>> expected_key_value_pairs{
{key, compressed_value}};
{key, compressed_value.AsSlice().ToString()}};
std::vector<std::string> blob_indexes{blob_index};
VerifyBlobFile(blob_file_number, blob_file_path, column_family_id,

View File

@@ -25,6 +25,7 @@
#include "rocksdb/advanced_options.h"
#include "table/table_reader.h"
#include "table/unique_id_impl.h"
#include "test_util/sync_point.h"
#include "util/autovector.h"
namespace ROCKSDB_NAMESPACE {

1
env/env.cc vendored
View File

@@ -27,6 +27,7 @@
#include "rocksdb/utilities/object_registry.h"
#include "rocksdb/utilities/options_type.h"
#include "util/autovector.h"
#include "util/string_util.h"
namespace ROCKSDB_NAMESPACE {
namespace {

View File

@@ -30,6 +30,7 @@
#include "rocksdb/utilities/object_registry.h"
#include "rocksdb/utilities/options_type.h"
#include "util/cast_util.h"
#include "util/string_util.h"
// NOTE: in this file, many option flags that were deprecated
// and removed from the rest of the code have to be kept here

View File

@@ -74,28 +74,5 @@ using OnceType = intptr_t;
#define LEVELDB_ONCE_INIT 0
void InitOnce(port::OnceType*, void (*initializer)());
// ------------------ Compression -------------------
// Store the snappy compression of "input[0,input_length-1]" in *output.
// Returns false if snappy is not supported by this port.
bool Snappy_Compress(const char* input, size_t input_length,
std::string* output);
// If input[0,input_length-1] looks like a valid snappy compressed
// buffer, store the size of the uncompressed data in *result and
// return true. Else return false.
bool Snappy_GetUncompressedLength(const char* input, size_t length,
size_t* result);
// Attempt to snappy uncompress input[0,input_length-1] into *output.
// Returns true if successful, false if the input is invalid lightweight
// compressed data.
//
// REQUIRES: at least the first "n" bytes of output[] must be writable
// where "n" is the result of a successful call to
// Snappy_GetUncompressedLength.
bool Snappy_Uncompress(const char* input_data, size_t input_length,
char* output);
} // namespace port
} // namespace ROCKSDB_NAMESPACE

View File

@@ -18,7 +18,6 @@ struct BlockCacheLookupContext;
class FilePrefetchBuffer;
class GetContext;
struct ReadOptions;
struct UncompressionDict;
// Provides access to the uncompression dictionary regardless of whether
// it is owned by the reader or stored in the cache, or whether it is pinned

View File

@@ -29,6 +29,7 @@
#include "test_util/mock_time_env.h"
#include "test_util/sync_point.h"
#include "util/random.h"
#include "util/string_util.h"
#ifndef ROCKSDB_UNITTESTS_WITH_CUSTOM_OBJECTS_FROM_STATIC_LIBS
void RegisterCustomObjects(int /*argc*/, char** /*argv*/) {}

View File

@@ -26,6 +26,7 @@ int main() {
#include "test_util/testutil.h"
#include "tools/block_cache_analyzer/block_cache_trace_analyzer.h"
#include "trace_replay/block_cache_tracer.h"
#include "util/string_util.h"
namespace ROCKSDB_NAMESPACE {

View File

@@ -5,12 +5,156 @@
#include "util/compression.h"
#ifdef BZIP2
#include <bzlib.h>
#endif // BZIP2
#include <limits>
#ifdef LZ4
#include <lz4.h>
#include <lz4hc.h>
#if LZ4_VERSION_NUMBER < 10700 // < r129
#error "LZ4 support requires version >= 1.7.0 (lz4-devel)"
#endif // LZ4_VERSION_NUMBER < 10700
#endif // LZ4
#ifdef SNAPPY
#include <snappy-sinksource.h>
#include <snappy.h>
#endif // SNAPPY
#ifdef ZLIB
#include <zlib.h>
#endif // ZLIB
#include "options/options_helper.h"
#include "port/likely.h"
#include "rocksdb/convenience.h"
#include "rocksdb/utilities/object_registry.h"
#include "test_util/sync_point.h"
#include "util/cast_util.h"
#include "util/string_util.h"
namespace ROCKSDB_NAMESPACE {
// WART: does not match OptionsHelper::compression_type_string_map
std::string CompressionTypeToString(CompressionType compression_type) {
switch (compression_type) {
case kNoCompression:
return "NoCompression";
case kSnappyCompression:
return "Snappy";
case kZlibCompression:
return "Zlib";
case kBZip2Compression:
return "BZip2";
case kLZ4Compression:
return "LZ4";
case kLZ4HCCompression:
return "LZ4HC";
case kXpressCompression:
return "Xpress";
case kZSTD:
return "ZSTD";
case kDisableCompressionOption:
return "DisableOption";
default: {
bool is_custom = compression_type >= kFirstCustomCompression &&
compression_type <= kLastCustomCompression;
unsigned char c = lossless_cast<unsigned char>(compression_type);
return (is_custom ? "Custom" : "Reserved") +
ToBaseCharsString<16>(2, c, /*uppercase=*/true);
}
}
}
// WART: does not match OptionsHelper::compression_type_string_map
CompressionType CompressionTypeFromString(std::string compression_type_str) {
if (!compression_type_str.empty()) {
switch (compression_type_str[0]) {
case 'N':
if (compression_type_str == "NoCompression") {
return kNoCompression;
}
break;
case 'S':
if (compression_type_str == "Snappy") {
return kSnappyCompression;
}
break;
case 'Z':
if (compression_type_str == "ZSTD") {
return kZSTD;
}
if (compression_type_str == "Zlib") {
return kZlibCompression;
}
break;
case 'B':
if (compression_type_str == "BZip2") {
return kBZip2Compression;
}
break;
case 'L':
if (compression_type_str == "LZ4") {
return kLZ4Compression;
}
if (compression_type_str == "LZ4HC") {
return kLZ4HCCompression;
}
break;
case 'X':
if (compression_type_str == "Xpress") {
return kXpressCompression;
}
break;
default:;
}
}
// unrecognized
return kDisableCompressionOption;
}
std::string CompressionOptionsToString(
const CompressionOptions& compression_options) {
std::string result;
result.reserve(512);
result.append("window_bits=")
.append(std::to_string(compression_options.window_bits))
.append("; ");
result.append("level=")
.append(std::to_string(compression_options.level))
.append("; ");
result.append("strategy=")
.append(std::to_string(compression_options.strategy))
.append("; ");
result.append("max_dict_bytes=")
.append(std::to_string(compression_options.max_dict_bytes))
.append("; ");
result.append("zstd_max_train_bytes=")
.append(std::to_string(compression_options.zstd_max_train_bytes))
.append("; ");
// NOTE: parallel_threads is skipped because it doesn't really affect the file
// contents written, arguably doesn't belong in CompressionOptions
result.append("enabled=")
.append(std::to_string(compression_options.enabled))
.append("; ");
result.append("max_dict_buffer_bytes=")
.append(std::to_string(compression_options.max_dict_buffer_bytes))
.append("; ");
result.append("use_zstd_dict_trainer=")
.append(std::to_string(compression_options.use_zstd_dict_trainer))
.append("; ");
result.append("max_compressed_bytes_per_kb=")
.append(std::to_string(compression_options.max_compressed_bytes_per_kb))
.append("; ");
result.append("checksum=")
.append(std::to_string(compression_options.checksum))
.append("; ");
return result;
}
StreamingCompress* StreamingCompress::Create(CompressionType compression_type,
const CompressionOptions& opts,
uint32_t compress_format_version,
@@ -123,6 +267,123 @@ void ZSTDStreamingUncompress::Reset() {
#endif
}
void DecompressorDict::Populate(Decompressor& from_decompressor, Slice dict) {
if (UNLIKELY(dict.empty())) {
dict_str_ = {};
dict_allocation_ = {};
// Appropriately reject bad files with empty dictionary block.
// It is longstanding not to write an empty dictionary block:
// https://github.com/facebook/rocksdb/blame/10.2.fb/table/block_based/block_based_table_builder.cc#L1841
decompressor_ = std::make_unique<FailureDecompressor>(
Status::Corruption("Decompression dictionary is empty"));
} else {
Status s = from_decompressor.MaybeCloneForDict(dict, &decompressor_);
if (decompressor_ == nullptr) {
dict_str_ = {};
dict_allocation_ = {};
assert(!s.ok());
decompressor_ = std::make_unique<FailureDecompressor>(std::move(s));
} else {
assert(s.ok());
assert(decompressor_->GetSerializedDict() == dict);
}
}
memory_usage_ = sizeof(struct DecompressorDict);
memory_usage_ += dict_str_.size();
if (dict_allocation_) {
auto allocator = dict_allocation_.get_deleter().allocator;
if (allocator) {
memory_usage_ +=
allocator->UsableSize(dict_allocation_.get(), GetRawDict().size());
} else {
memory_usage_ += GetRawDict().size();
}
}
memory_usage_ += decompressor_->ApproximateOwnedMemoryUsage();
}
// ZSTD dictionary training implementations
std::string ZSTD_TrainDictionary(const std::string& samples,
const std::vector<size_t>& sample_lens,
size_t max_dict_bytes) {
#ifdef ZSTD
assert(samples.empty() == sample_lens.empty());
if (samples.empty()) {
return "";
}
std::string dict_data(max_dict_bytes, '\0');
size_t dict_len = ZDICT_trainFromBuffer(
&dict_data[0], max_dict_bytes, &samples[0], &sample_lens[0],
static_cast<unsigned>(sample_lens.size()));
if (ZDICT_isError(dict_len)) {
return "";
}
assert(dict_len <= max_dict_bytes);
dict_data.resize(dict_len);
return dict_data;
#else
assert(false);
(void)samples;
(void)sample_lens;
(void)max_dict_bytes;
return "";
#endif // ZSTD
}
std::string ZSTD_TrainDictionary(const std::string& samples,
size_t sample_len_shift,
size_t max_dict_bytes) {
#ifdef ZSTD
// skips potential partial sample at the end of "samples"
size_t num_samples = samples.size() >> sample_len_shift;
std::vector<size_t> sample_lens(num_samples, size_t(1) << sample_len_shift);
return ZSTD_TrainDictionary(samples, sample_lens, max_dict_bytes);
#else
assert(false);
(void)samples;
(void)sample_len_shift;
(void)max_dict_bytes;
return "";
#endif // ZSTD
}
std::string ZSTD_FinalizeDictionary(const std::string& samples,
const std::vector<size_t>& sample_lens,
size_t max_dict_bytes, int level) {
#ifdef ROCKSDB_ZDICT_FINALIZE
assert(samples.empty() == sample_lens.empty());
if (samples.empty()) {
return "";
}
if (level == CompressionOptions::kDefaultCompressionLevel) {
// NB: ZSTD_CLEVEL_DEFAULT is historically == 3
level = ZSTD_CLEVEL_DEFAULT;
}
std::string dict_data(max_dict_bytes, '\0');
size_t dict_len = ZDICT_finalizeDictionary(
dict_data.data(), max_dict_bytes, samples.data(),
std::min(static_cast<size_t>(samples.size()), max_dict_bytes),
samples.data(), sample_lens.data(),
static_cast<unsigned>(sample_lens.size()),
{level, 0 /* notificationLevel */, 0 /* dictID */});
if (ZDICT_isError(dict_len)) {
return "";
} else {
assert(dict_len <= max_dict_bytes);
dict_data.resize(dict_len);
return dict_data;
}
#else
assert(false);
(void)samples;
(void)sample_lens;
(void)max_dict_bytes;
(void)level;
return "";
#endif // ROCKSDB_ZDICT_FINALIZE
}
// ***********************************************************************
// BEGIN built-in implementation of customization interface
// ***********************************************************************

File diff suppressed because it is too large Load Diff