mirror of
https://github.com/facebook/rocksdb.git
synced 2026-07-07 14:47:40 +08:00
Make ParseCompressionNameForDisplay manager-aware (#14658)
Summary: Pull Request resolved: https://github.com/facebook/rocksdb/pull/14658 Follow up to D101463511. Add a hook and a manager-aware overload of so custom CompressionManagers can provide human-readable names for custom compression types while preserving the existing generic fallback when no compatible manager is available. Reviewed By: pdillinger Differential Revision: D102201365 fbshipit-source-id: 0c7456bb9db2e54927a4349d12c035fc8b5ad562
This commit is contained in:
committed by
meta-codesync[bot]
parent
d8fc727592
commit
3cdf942192
@@ -8,14 +8,17 @@
|
||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "db/db_test_util.h"
|
||||
#include "port/port.h"
|
||||
#include "port/stack_trace.h"
|
||||
#include "rocksdb/advanced_compression.h"
|
||||
#include "rocksdb/db.h"
|
||||
#include "rocksdb/types.h"
|
||||
#include "rocksdb/utilities/object_registry.h"
|
||||
#include "rocksdb/utilities/table_properties_collectors.h"
|
||||
#include "table/format.h"
|
||||
#include "table/meta_blocks.h"
|
||||
@@ -51,6 +54,42 @@ void VerifyTableProperties(DB* db, uint64_t expected_entries_size) {
|
||||
|
||||
VerifySstUniqueIds(props);
|
||||
}
|
||||
|
||||
class ParseCompressionDisplayNameManager : public CompressionManagerWrapper {
|
||||
public:
|
||||
static constexpr const char* kCompatibilityName =
|
||||
"ParseCompressionDisplayNameManager";
|
||||
|
||||
ParseCompressionDisplayNameManager()
|
||||
: CompressionManagerWrapper(GetBuiltinV2CompressionManager()) {}
|
||||
|
||||
const char* Name() const override { return kCompatibilityName; }
|
||||
const char* CompatibilityName() const override { return kCompatibilityName; }
|
||||
|
||||
std::string CompressionTypeToString(CompressionType type) const override {
|
||||
if (type == kCustomCompression8A) {
|
||||
return "CustomAlpha";
|
||||
}
|
||||
if (type == kCustomCompression8B) {
|
||||
return "CustomBeta";
|
||||
}
|
||||
return CompressionManagerWrapper::CompressionTypeToString(type);
|
||||
}
|
||||
|
||||
static void Register() {
|
||||
static std::once_flag loaded;
|
||||
std::call_once(loaded, []() {
|
||||
auto& library = *ObjectLibrary::Default();
|
||||
library.AddFactory<CompressionManager>(
|
||||
kCompatibilityName, [](const std::string& /*uri*/,
|
||||
std::unique_ptr<CompressionManager>* guard,
|
||||
std::string* /*errmsg*/) {
|
||||
*guard = std::make_unique<ParseCompressionDisplayNameManager>();
|
||||
return guard->get();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
class DBTablePropertiesTest : public DBTestBase,
|
||||
@@ -813,6 +852,8 @@ TEST_F(DBTablePropertiesTest, KeyLargestSmallestSeqno) {
|
||||
}
|
||||
|
||||
TEST_F(DBTablePropertiesTest, ParseCompressionNameForDisplay) {
|
||||
auto custom_mgr = std::make_shared<ParseCompressionDisplayNameManager>();
|
||||
|
||||
// Test empty string
|
||||
EXPECT_EQ("NoCompression", ParseCompressionNameForDisplay(""));
|
||||
|
||||
@@ -835,10 +876,9 @@ TEST_F(DBTablePropertiesTest, ParseCompressionNameForDisplay) {
|
||||
EXPECT_EQ("LZ4", ParseCompressionNameForDisplay("zstd;04;"));
|
||||
EXPECT_EQ("LZ4", ParseCompressionNameForDisplay("lz4;04;"));
|
||||
|
||||
// Test lowercase hex
|
||||
EXPECT_EQ("ZSTD", ParseCompressionNameForDisplay("test;07;"));
|
||||
EXPECT_EQ("LZ4", ParseCompressionNameForDisplay("test;04;"));
|
||||
EXPECT_EQ("LZ4,ZSTD", ParseCompressionNameForDisplay("test;0407;"));
|
||||
// Test lowercase hex for reserved/custom values
|
||||
EXPECT_EQ("Reserved7F", ParseCompressionNameForDisplay("test;7f;"));
|
||||
EXPECT_EQ("Custom8A", ParseCompressionNameForDisplay("test;8a;"));
|
||||
|
||||
// Test multiple compression types
|
||||
EXPECT_EQ("LZ4,ZSTD", ParseCompressionNameForDisplay("test;0407;"));
|
||||
@@ -863,6 +903,16 @@ TEST_F(DBTablePropertiesTest, ParseCompressionNameForDisplay) {
|
||||
EXPECT_EQ("Custom80", ParseCompressionNameForDisplay("test;80;"));
|
||||
EXPECT_EQ("Reserved7F", ParseCompressionNameForDisplay("test;7F;"));
|
||||
EXPECT_EQ("CustomFE", ParseCompressionNameForDisplay("test;FE;"));
|
||||
EXPECT_EQ("CustomAlpha,CustomBeta",
|
||||
ParseCompressionNameForDisplay(
|
||||
"ParseCompressionDisplayNameManager;8A8B;", custom_mgr));
|
||||
EXPECT_EQ("CustomAlpha,LZ4,CustomBeta",
|
||||
ParseCompressionNameForDisplay(
|
||||
"ParseCompressionDisplayNameManager;8A048B;", custom_mgr));
|
||||
|
||||
ParseCompressionDisplayNameManager::Register();
|
||||
EXPECT_EQ("CustomAlpha", ParseCompressionNameForDisplay(
|
||||
"ParseCompressionDisplayNameManager;8A;"));
|
||||
|
||||
// Test DisableOption (0xFF) - filtered out
|
||||
EXPECT_EQ("NoCompression", ParseCompressionNameForDisplay("test;FF;"));
|
||||
|
||||
@@ -456,6 +456,13 @@ class CompressionManager
|
||||
// supported)
|
||||
virtual bool SupportsCompressionType(CompressionType type) const = 0;
|
||||
|
||||
// Return a human-readable name for the given compression type within this
|
||||
// CompressionManager's schema. The default implementation returns the
|
||||
// generic built-in name such as "Snappy", "ZSTD", "Reserved4F", or
|
||||
// "Custom8A". Override to provide more specific names for custom
|
||||
// compression types.
|
||||
virtual std::string CompressionTypeToString(CompressionType type) const;
|
||||
|
||||
// TODO: function to check compatibility with or sanitize CompressionOptions
|
||||
|
||||
// ************************* Compressor creation *********************** //
|
||||
@@ -656,6 +663,10 @@ class CompressionManagerWrapper : public CompressionManager {
|
||||
return wrapped_->SupportsCompressionType(type);
|
||||
}
|
||||
|
||||
std::string CompressionTypeToString(CompressionType type) const override {
|
||||
return wrapped_->CompressionTypeToString(type);
|
||||
}
|
||||
|
||||
std::unique_ptr<Compressor> GetCompressorForSST(
|
||||
const FilterBuildingContext& context, const CompressionOptions& opts,
|
||||
CompressionType preferred) override {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
namespace ROCKSDB_NAMESPACE {
|
||||
|
||||
class InternalTblPropColl;
|
||||
class CompressionManager;
|
||||
|
||||
// -- Table Properties
|
||||
// Other than basic table properties, each table may also have the user
|
||||
@@ -446,17 +447,26 @@ struct TableProperties {
|
||||
};
|
||||
|
||||
// Parse TableProperties::compression_name into human-readable format.
|
||||
// Thread-safe: pure utility function with no shared state.
|
||||
// Thread-safe, but not purely local: the single-argument overload may consult
|
||||
// globally registered CompressionManagers via ObjectLibrary using the stored
|
||||
// compatibility name, and the two-argument overload consults the supplied
|
||||
// CompressionManager first before falling back to that lookup.
|
||||
// For format_version >= 7: "<compatibility_name>;<hex_codes>;" -> "ZSTD",
|
||||
// "LZ4", etc. For older versions (no semicolon): returns as-is (e.g., "ZSTD",
|
||||
// "Snappy", "kZSTD" are preserved with their original names). Returns
|
||||
// "NoCompression" for an empty input, an empty hex field such as
|
||||
// "BuiltinV2;;", or when all parsed entries are filtered out as
|
||||
// NoCompression/DisableOption. Returns "Unknown" for malformed format_version
|
||||
// >= 7 metadata, including a missing second semicolon, odd-length hex payload,
|
||||
// or invalid hex characters. If multiple compression types are present,
|
||||
// returns a comma-separated list in input order.
|
||||
// "Snappy", "kZSTD" are preserved with their original names). This means the
|
||||
// single-argument overload can now return manager-specific names for custom
|
||||
// compression types when a compatible CompressionManager is registered
|
||||
// globally; otherwise, reserved/custom values fall back to generic names such
|
||||
// as "Reserved7F" or "Custom8A". Returns "NoCompression" for an empty input,
|
||||
// an empty hex field such as "BuiltinV2;;", or when all parsed entries are
|
||||
// filtered out as NoCompression/DisableOption. Returns "Unknown" for malformed
|
||||
// format_version >= 7 metadata, including a missing second semicolon,
|
||||
// odd-length hex payload, or invalid hex characters. If multiple compression
|
||||
// types are present, returns a comma-separated list in input order.
|
||||
std::string ParseCompressionNameForDisplay(const std::string& compression_name);
|
||||
std::string ParseCompressionNameForDisplay(
|
||||
const std::string& compression_name,
|
||||
std::shared_ptr<CompressionManager> compression_manager);
|
||||
|
||||
// Extra properties
|
||||
// Below is a list of non-basic properties that are collected by database
|
||||
|
||||
@@ -38,6 +38,40 @@ void AppendProperty(std::string& props, const std::string& key,
|
||||
const std::string& kv_delim) {
|
||||
AppendProperty(props, key, std::to_string(value), prop_delim, kv_delim);
|
||||
}
|
||||
|
||||
std::shared_ptr<CompressionManager> ResolveCompressionManagerForDisplay(
|
||||
Slice compatibility_name,
|
||||
const std::shared_ptr<CompressionManager>& compression_manager) {
|
||||
std::shared_ptr<CompressionManager> mgr_to_use;
|
||||
if (compression_manager) {
|
||||
mgr_to_use = compression_manager->FindCompatibleCompressionManager(
|
||||
compatibility_name);
|
||||
}
|
||||
if (mgr_to_use == nullptr) {
|
||||
ConfigOptions strict;
|
||||
strict.ignore_unknown_options = false;
|
||||
strict.ignore_unsupported_options = false;
|
||||
Status s = CompressionManager::CreateFromString(
|
||||
strict, compatibility_name.ToString(), &mgr_to_use);
|
||||
if (!s.ok()) {
|
||||
mgr_to_use.reset();
|
||||
}
|
||||
}
|
||||
return mgr_to_use;
|
||||
}
|
||||
|
||||
std::string CompressionTypeDisplayName(
|
||||
CompressionType compression_type,
|
||||
const std::shared_ptr<CompressionManager>& compression_manager) {
|
||||
if (compression_manager) {
|
||||
std::string name =
|
||||
compression_manager->CompressionTypeToString(compression_type);
|
||||
if (!name.empty()) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return CompressionTypeToString(compression_type);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string TableProperties::ToString(const std::string& prop_delim,
|
||||
@@ -618,6 +652,15 @@ void TEST_SetRandomTableProperties(TableProperties* props) {
|
||||
|
||||
std::string ParseCompressionNameForDisplay(
|
||||
const std::string& compression_name) {
|
||||
// The single-argument overload intentionally consults globally registered
|
||||
// CompressionManagers, keyed by the encoded compatibility name, so custom
|
||||
// managers can contribute display names without an explicit manager handle.
|
||||
return ParseCompressionNameForDisplay(compression_name, nullptr);
|
||||
}
|
||||
|
||||
std::string ParseCompressionNameForDisplay(
|
||||
const std::string& compression_name,
|
||||
std::shared_ptr<CompressionManager> compression_manager) {
|
||||
// Empty = no compression
|
||||
if (compression_name.empty()) {
|
||||
return "NoCompression";
|
||||
@@ -637,6 +680,10 @@ std::string ParseCompressionNameForDisplay(
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
Slice compatibility_name(compression_name.data(), first_semicolon);
|
||||
auto mgr_to_use = ResolveCompressionManagerForDisplay(compatibility_name,
|
||||
compression_manager);
|
||||
|
||||
// Extract hex codes
|
||||
std::string hex_codes = compression_name.substr(
|
||||
first_semicolon + 1, second_semicolon - first_semicolon - 1);
|
||||
@@ -660,10 +707,8 @@ std::string ParseCompressionNameForDisplay(
|
||||
return "Unknown";
|
||||
}
|
||||
auto ct = static_cast<CompressionType>(val);
|
||||
std::string name = CompressionTypeToString(ct);
|
||||
// Filter out NoCompression
|
||||
if (name != "NoCompression" && name != "DisableOption") {
|
||||
types.push_back(name);
|
||||
if (ct != kNoCompression && ct != kDisableCompressionOption) {
|
||||
types.push_back(CompressionTypeDisplayName(ct, mgr_to_use));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
Added public utility API `ParseCompressionNameForDisplay()` to convert `TableProperties::compression_name` into a human-readable compression name for both legacy and format_version 7+ SST metadata.
|
||||
Added public utility APIs `ParseCompressionNameForDisplay()` to convert `TableProperties::compression_name` into a human-readable compression name for both legacy and format_version 7+ SST metadata, including custom `CompressionManager`-provided display names for custom compression types.
|
||||
|
||||
@@ -1876,6 +1876,11 @@ Status CompressionManager::CreateFromString(
|
||||
return status;
|
||||
}
|
||||
|
||||
std::string CompressionManager::CompressionTypeToString(
|
||||
CompressionType type) const {
|
||||
return ROCKSDB_NAMESPACE::CompressionTypeToString(type);
|
||||
}
|
||||
|
||||
std::shared_ptr<CompressionManager>
|
||||
CompressionManager::FindCompatibleCompressionManager(Slice compatibility_name) {
|
||||
if (compatibility_name.compare(CompatibilityName()) == 0) {
|
||||
|
||||
Reference in New Issue
Block a user