compress: fix compressor initialization order by making namespace_prefix a function

Fixes a race condition where COMPRESSOR_NAME in zstd.cc could be
initialized before compressor::namespace_prefix due to undefined
global variable initialization order across translation units. This
was causing ZstdCompressor to be unregistered in release builds,
making it impossible to create tables with Zstd compression.

Replace the global namespace_prefix variable with a function that
returns the fully qualified compressor name. This ensures proper
initialization order and fixes the registration of the ZstdCompressor.

Fixes scylladb/scylladb#22444
Signed-off-by: Kefu Chai <kefu.chai@scylladb.com>

Closes scylladb/scylladb#22451
This commit is contained in:
Kefu Chai
2025-01-22 18:04:26 +08:00
committed by Avi Kivity
parent 1151062b2a
commit 4a268362b9
4 changed files with 10 additions and 8 deletions

View File

@@ -14,7 +14,9 @@
#include "exceptions/exceptions.hh"
#include "utils/class_registrator.hh"
const sstring compressor::namespace_prefix = "org.apache.cassandra.io.compress.";
sstring compressor::make_name(std::string_view short_name) {
return seastar::format("org.apache.cassandra.io.compress.{}", short_name);
}
class lz4_processor: public compressor {
public:
@@ -66,7 +68,7 @@ compressor::ptr_type compressor::create(const sstring& name, const opt_getter& o
return {};
}
qualified_name qn(namespace_prefix, name);
qualified_name qn(make_name(""), name);
for (auto& c : { lz4, snappy, deflate }) {
if (c->name() == static_cast<const sstring&>(qn)) {
@@ -91,9 +93,9 @@ shared_ptr<compressor> compressor::create(const std::map<sstring, sstring>& opti
return {};
}
thread_local const shared_ptr<compressor> compressor::lz4 = ::make_shared<lz4_processor>(namespace_prefix + "LZ4Compressor");
thread_local const shared_ptr<compressor> compressor::snappy = ::make_shared<snappy_processor>(namespace_prefix + "SnappyCompressor");
thread_local const shared_ptr<compressor> compressor::deflate = ::make_shared<deflate_processor>(namespace_prefix + "DeflateCompressor");
thread_local const shared_ptr<compressor> compressor::lz4 = ::make_shared<lz4_processor>(make_name("LZ4Compressor"));
thread_local const shared_ptr<compressor> compressor::snappy = ::make_shared<snappy_processor>(make_name("SnappyCompressor"));
thread_local const shared_ptr<compressor> compressor::deflate = ::make_shared<deflate_processor>(make_name("DeflateCompressor"));
const sstring compression_parameters::SSTABLE_COMPRESSION = "sstable_compression";
const sstring compression_parameters::CHUNK_LENGTH_KB = "chunk_length_in_kb";

View File

@@ -69,7 +69,7 @@ public:
static thread_local const ptr_type snappy;
static thread_local const ptr_type deflate;
static const sstring namespace_prefix;
static sstring make_name(std::string_view short_name);
};
template<typename BaseType, typename... Args>

View File

@@ -295,7 +295,7 @@ size_t local_compression::compress_max_size(size_t input_len) const {
void compression::set_compressor(compressor_ptr c) {
if (c) {
unqualified_name uqn(compressor::namespace_prefix, c->name());
unqualified_name uqn(compressor::make_name(""), c->name());
const sstring& cn = uqn;
name.value = bytes(cn.begin(), cn.end());
for (auto& [k, v] : c->options()) {

View File

@@ -20,7 +20,7 @@
#include <concepts>
static const sstring COMPRESSION_LEVEL = "compression_level";
static const sstring COMPRESSOR_NAME = compressor::namespace_prefix + "ZstdCompressor";
static const sstring COMPRESSOR_NAME = compressor::make_name("ZstdCompressor");
static const size_t DCTX_SIZE = ZSTD_estimateDCtxSize();
class zstd_processor : public compressor {