From 816de565e5deb84b6cbfee7d05aa4d6c490d8896 Mon Sep 17 00:00:00 2001 From: xiaobiaozhao Date: Sun, 9 Jul 2023 15:04:26 +0000 Subject: [PATCH 01/10] feat: enable dynamin compression --- src/config/config.cc | 5 +++++ src/config/config.h | 1 + src/storage/storage.cc | 23 ++++++++++++++++++++ tests/gocase/unit/config/config_test.go | 28 +++++++++++++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/src/config/config.cc b/src/config/config.cc index e278aebf862..1c830b636ae 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -601,6 +601,11 @@ void Config::initFieldCallback() { {"rocksdb.level0_slowdown_writes_trigger", set_cf_option_cb}, {"rocksdb.level0_stop_writes_trigger", set_cf_option_cb}, {"rocksdb.level0_file_num_compaction_trigger", set_cf_option_cb}, + {"rocksdb.compression", + [](Server *srv, const std::string &k, const std::string &v) -> Status { + if (!srv) return Status::OK(); + return srv->storage->SetOptionForAllColumnFamilies(TrimRocksDbPrefix(k), v); + }}, #ifdef ENABLE_OPENSSL {"tls-cert-file", set_tls_option}, {"tls-key-file", set_tls_option}, diff --git a/src/config/config.h b/src/config/config.h index 3eabc3bed05..b9ef433a941 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -39,6 +39,7 @@ namespace engine { class Storage; } +extern ConfigEnum compression_types[]; constexpr const uint32_t PORT_LIMIT = 65535; enum SupervisedMode { kSupervisedNone = 0, kSupervisedAutoDetect, kSupervisedSystemd, kSupervisedUpStart }; diff --git a/src/storage/storage.cc b/src/storage/storage.cc index 68bbe119edf..401e0ac08b9 100644 --- a/src/storage/storage.cc +++ b/src/storage/storage.cc @@ -183,6 +183,29 @@ rocksdb::Options Storage::InitRocksDBOptions() { } Status Storage::SetOptionForAllColumnFamilies(const std::string &key, const std::string &value) { + if ("compression" == key) { + std::unordered_map compression_map = {{"no", "kNoCompression"}, + {"snappy", "kSnappyCompression"}, + {"lz4", "kLZ4Compression"}, + {"zstd", "kZSTD"}, + {"zlib", "kZlibCompression"}}; + if (compression_map.find(value) == compression_map.end()) { + return {Status::NotOK, "Invalid compression type"}; + } + + std::string compression_levels = "kNoCompression:kNoCompression"; + for (size_t i = 2; i < db_->GetOptions().compression_per_level.size(); i++) { + compression_levels += ":"; + compression_levels += compression_map[value]; + } + + for (auto &cf_handle : cf_handles_) { + auto s = db_->SetOptions(cf_handle, {{"compression_per_level", compression_levels}}); + if (!s.ok()) return {Status::NotOK, s.ToString()}; + } + return Status::OK(); + } + for (auto &cf_handle : cf_handles_) { auto s = db_->SetOptions(cf_handle, {{key, value}}); if (!s.ok()) return {Status::NotOK, s.ToString()}; diff --git a/tests/gocase/unit/config/config_test.go b/tests/gocase/unit/config/config_test.go index 1642b763963..1c23509965f 100644 --- a/tests/gocase/unit/config/config_test.go +++ b/tests/gocase/unit/config/config_test.go @@ -108,3 +108,31 @@ func TestSetConfigBackupDir(t *testing.T) { require.True(t, hasCompactionFiles(newBackupDir)) require.True(t, hasCompactionFiles(originBackupDir)) } + +func TestSetConfigCompression(t *testing.T) { + configs := map[string]string{} + srv := util.StartServer(t, configs) + defer srv.Close() + + ctx := context.Background() + rdb := srv.NewClient() + defer func() { require.NoError(t, rdb.Close()) }() + require.NoError(t, rdb.Do(ctx, "SET", "foo", "bar").Err()) + + require.Equal(t, "bar", rdb.Get(ctx, "foo").Val()) + r := rdb.Do(ctx, "CONFIG", "GET", "rocksdb.compression") + rList := r.Val().([]interface{}) + require.EqualValues(t, rList[1], "no") + + require.NoError(t, rdb.Do(ctx, "CONFIG", "SET", "rocksdb.compression", "lz4").Err()) + require.Equal(t, "bar", rdb.Get(ctx, "foo").Val()) + r = rdb.Do(ctx, "CONFIG", "GET", "rocksdb.compression") + rList = r.Val().([]interface{}) + require.EqualValues(t, rList[1], "lz4") + + require.NoError(t, rdb.Do(ctx, "CONFIG", "SET", "rocksdb.compression", "zstd").Err()) + require.Equal(t, "bar", rdb.Get(ctx, "foo").Val()) + r = rdb.Do(ctx, "CONFIG", "GET", "rocksdb.compression") + rList = r.Val().([]interface{}) + require.EqualValues(t, rList[1], "zstd") +} From 9bb7535bd0af9460a271a8d1698f9b0f7113c002 Mon Sep 17 00:00:00 2001 From: xiaobiaozhao Date: Tue, 11 Jul 2023 14:51:01 +0000 Subject: [PATCH 02/10] refactor: make single function --- src/storage/event_listener.cc | 21 +---------- src/storage/storage.cc | 71 +++++++++++++++++++++++++---------- src/storage/storage.h | 3 ++ 3 files changed, 55 insertions(+), 40 deletions(-) diff --git a/src/storage/event_listener.cc b/src/storage/event_listener.cc index fa9b7c0a88d..f8e0fbe01f4 100644 --- a/src/storage/event_listener.cc +++ b/src/storage/event_listener.cc @@ -40,25 +40,6 @@ std::string StallConditionType2String(const rocksdb::WriteStallCondition type) { return "unknown"; } -std::string CompressType2String(const rocksdb::CompressionType type) { - std::map compression_type_string_map = { - {rocksdb::kNoCompression, "no"}, - {rocksdb::kSnappyCompression, "snappy"}, - {rocksdb::kZlibCompression, "zlib"}, - {rocksdb::kBZip2Compression, "zip2"}, - {rocksdb::kLZ4Compression, "lz4"}, - {rocksdb::kLZ4HCCompression, "lz4hc"}, - {rocksdb::kXpressCompression, "xpress"}, - {rocksdb::kZSTD, "zstd"}, - {rocksdb::kZSTDNotFinalCompression, "zstd_not_final"}, - {rocksdb::kDisableCompressionOption, "disable"}}; - auto iter = compression_type_string_map.find(type); - if (iter == compression_type_string_map.end()) { - return "unknown"; - } - return iter->second; -} - bool IsDiskQuotaExceeded(const rocksdb::Status &bg_error) { // EDQUOT: Disk quota exceeded (POSIX.1-2001) std::string exceeded_quota_str = "Disk quota exceeded"; @@ -70,7 +51,7 @@ bool IsDiskQuotaExceeded(const rocksdb::Status &bg_error) { void EventListener::OnCompactionCompleted(rocksdb::DB *db, const rocksdb::CompactionJobInfo &ci) { LOG(INFO) << "[event_listener/compaction_completed] column family: " << ci.cf_name << ", compaction reason: " << static_cast(ci.compaction_reason) - << ", output compression type: " << CompressType2String(ci.compression) + << ", output compression type: " << storage_->CompressType2String(ci.compression) << ", base input level(files): " << ci.base_input_level << "(" << ci.input_files.size() << ")" << ", output level(files): " << ci.output_level << "(" << ci.output_files.size() << ")" << ", input bytes: " << ci.stats.total_input_bytes << ", output bytes:" << ci.stats.total_output_bytes diff --git a/src/storage/storage.cc b/src/storage/storage.cc index 401e0ac08b9..cb5aceecd2e 100644 --- a/src/storage/storage.cc +++ b/src/storage/storage.cc @@ -182,28 +182,59 @@ rocksdb::Options Storage::InitRocksDBOptions() { return options; } -Status Storage::SetOptionForAllColumnFamilies(const std::string &key, const std::string &value) { - if ("compression" == key) { - std::unordered_map compression_map = {{"no", "kNoCompression"}, - {"snappy", "kSnappyCompression"}, - {"lz4", "kLZ4Compression"}, - {"zstd", "kZSTD"}, - {"zlib", "kZlibCompression"}}; - if (compression_map.find(value) == compression_map.end()) { - return {Status::NotOK, "Invalid compression type"}; - } +std::string Storage::CompressType2String(const rocksdb::CompressionType &type) { + std::map compression_type_string_map = { + {rocksdb::kNoCompression, "no"}, + {rocksdb::kSnappyCompression, "snappy"}, + {rocksdb::kZlibCompression, "zlib"}, + {rocksdb::kBZip2Compression, "zip2"}, + {rocksdb::kLZ4Compression, "lz4"}, + {rocksdb::kLZ4HCCompression, "lz4hc"}, + {rocksdb::kXpressCompression, "xpress"}, + {rocksdb::kZSTD, "zstd"}, + {rocksdb::kZSTDNotFinalCompression, "zstd_not_final"}, + {rocksdb::kDisableCompressionOption, "disable"}}; + auto iter = compression_type_string_map.find(type); + if (iter == compression_type_string_map.end()) { + return "unknown"; + } + return iter->second; +} - std::string compression_levels = "kNoCompression:kNoCompression"; - for (size_t i = 2; i < db_->GetOptions().compression_per_level.size(); i++) { - compression_levels += ":"; - compression_levels += compression_map[value]; - } +std::string Storage::CompressString2CompressionString(const std::string &type) { + std::unordered_map compression_map = {{"no", "kNoCompression"}, + {"snappy", "kSnappyCompression"}, + {"lz4", "kLZ4Compression"}, + {"zstd", "kZSTD"}, + {"zlib", "kZlibCompression"}}; + auto iter = compression_map.find(type); + if (iter == compression_map.end()) { + return "unknown"; + } + return iter->second; +} - for (auto &cf_handle : cf_handles_) { - auto s = db_->SetOptions(cf_handle, {{"compression_per_level", compression_levels}}); - if (!s.ok()) return {Status::NotOK, s.ToString()}; - } - return Status::OK(); +Status Storage::SetCompressionOption(const std::string &key, const std::string &value) { + std::string compression_string = CompressString2CompressionString(value); + if ("unknown" == compression_string) { + return {Status::NotOK, "Invalid compression type"}; + } + std::string compression_levels = "kNoCompression:kNoCompression"; + for (size_t i = 2; i < db_->GetOptions().compression_per_level.size(); i++) { + compression_levels += ":"; + compression_levels += compression_string; + } + + for (auto &cf_handle : cf_handles_) { + auto s = db_->SetOptions(cf_handle, {{"compression_per_level", compression_levels}}); + if (!s.ok()) return {Status::NotOK, s.ToString()}; + } + return Status::OK(); +} + +Status Storage::SetOptionForAllColumnFamilies(const std::string &key, const std::string &value) { + if ("compression" == key) { + return SetCompressionOption(key, value); } for (auto &cf_handle : cf_handles_) { diff --git a/src/storage/storage.h b/src/storage/storage.h index 866eefb4d48..083aabac78c 100644 --- a/src/storage/storage.h +++ b/src/storage/storage.h @@ -79,6 +79,7 @@ class Storage { Status SetOptionForAllColumnFamilies(const std::string &key, const std::string &value); Status SetOption(const std::string &key, const std::string &value); Status SetDBOption(const std::string &key, const std::string &value); + Status SetCompressionOption(const std::string &key, const std::string &value); Status CreateColumnFamilies(const rocksdb::Options &options); Status CreateBackup(); void DestroyBackup(); @@ -176,6 +177,8 @@ class Storage { Status ShiftReplId(); std::string GetReplIdFromWalBySeq(rocksdb::SequenceNumber seq); std::string GetReplIdFromDbEngine(); + std::string CompressType2String(const rocksdb::CompressionType &type); + std::string CompressString2CompressionString(const std::string &type); private: std::unique_ptr db_ = nullptr; From 46eb2ea3d3ce8e23ec5c6a700bd136e5cef98533 Mon Sep 17 00:00:00 2001 From: xiaobiaozhao Date: Wed, 12 Jul 2023 17:49:15 +0000 Subject: [PATCH 03/10] feat: update --- src/config/config.cc | 2 +- src/config/config.h | 1 - src/storage/event_listener.cc | 2 +- src/storage/storage.cc | 42 ++++++++++++------------- src/storage/storage.h | 4 +-- tests/gocase/unit/config/config_test.go | 2 ++ 6 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/config/config.cc b/src/config/config.cc index 1c830b636ae..fb1ab7eb663 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -604,7 +604,7 @@ void Config::initFieldCallback() { {"rocksdb.compression", [](Server *srv, const std::string &k, const std::string &v) -> Status { if (!srv) return Status::OK(); - return srv->storage->SetOptionForAllColumnFamilies(TrimRocksDbPrefix(k), v); + return srv->storage->SetCompressionOption(TrimRocksDbPrefix(k), v); }}, #ifdef ENABLE_OPENSSL {"tls-cert-file", set_tls_option}, diff --git a/src/config/config.h b/src/config/config.h index b9ef433a941..3eabc3bed05 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -39,7 +39,6 @@ namespace engine { class Storage; } -extern ConfigEnum compression_types[]; constexpr const uint32_t PORT_LIMIT = 65535; enum SupervisedMode { kSupervisedNone = 0, kSupervisedAutoDetect, kSupervisedSystemd, kSupervisedUpStart }; diff --git a/src/storage/event_listener.cc b/src/storage/event_listener.cc index f8e0fbe01f4..ea4ed2b4e8d 100644 --- a/src/storage/event_listener.cc +++ b/src/storage/event_listener.cc @@ -51,7 +51,7 @@ bool IsDiskQuotaExceeded(const rocksdb::Status &bg_error) { void EventListener::OnCompactionCompleted(rocksdb::DB *db, const rocksdb::CompactionJobInfo &ci) { LOG(INFO) << "[event_listener/compaction_completed] column family: " << ci.cf_name << ", compaction reason: " << static_cast(ci.compaction_reason) - << ", output compression type: " << storage_->CompressType2String(ci.compression) + << ", output compression type: " << engine::Storage::CompressType2String(ci.compression) << ", base input level(files): " << ci.base_input_level << "(" << ci.input_files.size() << ")" << ", output level(files): " << ci.output_level << "(" << ci.output_files.size() << ")" << ", input bytes: " << ci.stats.total_input_bytes << ", output bytes:" << ci.stats.total_output_bytes diff --git a/src/storage/storage.cc b/src/storage/storage.cc index cb5aceecd2e..6949428dcab 100644 --- a/src/storage/storage.cc +++ b/src/storage/storage.cc @@ -56,6 +56,23 @@ const int64_t kIORateLimitMaxMb = 1024000; using rocksdb::Slice; +const static std::map compression_sort_long_string_map = {{"no", "kNoCompression"}, + {"snappy", "kSnappyCompression"}, + {"lz4", "kLZ4Compression"}, + {"zstd", "kZSTD"}, + {"zlib", "kZlibCompression"}}; +const static std::map compression_type_string_map = { + {rocksdb::kNoCompression, "no"}, + {rocksdb::kSnappyCompression, "snappy"}, + {rocksdb::kZlibCompression, "zlib"}, + {rocksdb::kBZip2Compression, "zip2"}, + {rocksdb::kLZ4Compression, "lz4"}, + {rocksdb::kLZ4HCCompression, "lz4hc"}, + {rocksdb::kXpressCompression, "xpress"}, + {rocksdb::kZSTD, "zstd"}, + {rocksdb::kZSTDNotFinalCompression, "zstd_not_final"}, + {rocksdb::kDisableCompressionOption, "disable"}}; + Storage::Storage(Config *config) : backup_creating_time_(util::GetTimeStamp()), env_(rocksdb::Env::Default()), config_(config), lock_mgr_(16) { Metadata::InitVersionCounter(); @@ -183,17 +200,6 @@ rocksdb::Options Storage::InitRocksDBOptions() { } std::string Storage::CompressType2String(const rocksdb::CompressionType &type) { - std::map compression_type_string_map = { - {rocksdb::kNoCompression, "no"}, - {rocksdb::kSnappyCompression, "snappy"}, - {rocksdb::kZlibCompression, "zlib"}, - {rocksdb::kBZip2Compression, "zip2"}, - {rocksdb::kLZ4Compression, "lz4"}, - {rocksdb::kLZ4HCCompression, "lz4hc"}, - {rocksdb::kXpressCompression, "xpress"}, - {rocksdb::kZSTD, "zstd"}, - {rocksdb::kZSTDNotFinalCompression, "zstd_not_final"}, - {rocksdb::kDisableCompressionOption, "disable"}}; auto iter = compression_type_string_map.find(type); if (iter == compression_type_string_map.end()) { return "unknown"; @@ -202,13 +208,8 @@ std::string Storage::CompressType2String(const rocksdb::CompressionType &type) { } std::string Storage::CompressString2CompressionString(const std::string &type) { - std::unordered_map compression_map = {{"no", "kNoCompression"}, - {"snappy", "kSnappyCompression"}, - {"lz4", "kLZ4Compression"}, - {"zstd", "kZSTD"}, - {"zlib", "kZlibCompression"}}; - auto iter = compression_map.find(type); - if (iter == compression_map.end()) { + auto iter = compression_sort_long_string_map.find(type); + if (iter == compression_sort_long_string_map.end()) { return "unknown"; } return iter->second; @@ -220,6 +221,7 @@ Status Storage::SetCompressionOption(const std::string &key, const std::string & return {Status::NotOK, "Invalid compression type"}; } std::string compression_levels = "kNoCompression:kNoCompression"; + // only compress levels >= 2 for (size_t i = 2; i < db_->GetOptions().compression_per_level.size(); i++) { compression_levels += ":"; compression_levels += compression_string; @@ -233,10 +235,6 @@ Status Storage::SetCompressionOption(const std::string &key, const std::string & } Status Storage::SetOptionForAllColumnFamilies(const std::string &key, const std::string &value) { - if ("compression" == key) { - return SetCompressionOption(key, value); - } - for (auto &cf_handle : cf_handles_) { auto s = db_->SetOptions(cf_handle, {{key, value}}); if (!s.ok()) return {Status::NotOK, s.ToString()}; diff --git a/src/storage/storage.h b/src/storage/storage.h index 083aabac78c..1723f54e17b 100644 --- a/src/storage/storage.h +++ b/src/storage/storage.h @@ -177,8 +177,8 @@ class Storage { Status ShiftReplId(); std::string GetReplIdFromWalBySeq(rocksdb::SequenceNumber seq); std::string GetReplIdFromDbEngine(); - std::string CompressType2String(const rocksdb::CompressionType &type); - std::string CompressString2CompressionString(const std::string &type); + static std::string CompressType2String(const rocksdb::CompressionType &type); + static std::string CompressString2CompressionString(const std::string &type); private: std::unique_ptr db_ = nullptr; diff --git a/tests/gocase/unit/config/config_test.go b/tests/gocase/unit/config/config_test.go index 1c23509965f..cec4c0f12c2 100644 --- a/tests/gocase/unit/config/config_test.go +++ b/tests/gocase/unit/config/config_test.go @@ -135,4 +135,6 @@ func TestSetConfigCompression(t *testing.T) { r = rdb.Do(ctx, "CONFIG", "GET", "rocksdb.compression") rList = r.Val().([]interface{}) require.EqualValues(t, rList[1], "zstd") + + require.ErrorContains(t, rdb.Do(ctx, "CONFIG", "SET", "rocksdb.compression", "undefine").Err(), "invalid enum option") } From f094e20faa53e605b49cef52bbe1e8bfbfd4db22 Mon Sep 17 00:00:00 2001 From: git-hulk Date: Thu, 13 Jul 2023 21:24:29 +0800 Subject: [PATCH 04/10] Refactor the config set compression type callback --- src/config/config.cc | 78 ++++++++++++++++--------- src/config/config_type.h | 10 ++-- src/storage/event_listener.cc | 11 +++- src/storage/storage.cc | 60 +++---------------- src/storage/storage.h | 11 +++- tests/gocase/unit/config/config_test.go | 29 ++++----- 6 files changed, 92 insertions(+), 107 deletions(-) diff --git a/src/config/config.cc b/src/config/config.cc index fb1ab7eb663..1e92fc45b76 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -45,40 +45,35 @@ constexpr const char *errBlobDbNotEnabled = "Must set rocksdb.enable_blob_files constexpr const char *errLevelCompactionDynamicLevelBytesNotSet = "Must set rocksdb.level_compaction_dynamic_level_bytes yes first."; -ConfigEnum compression_types[] = { - {"no", rocksdb::CompressionType::kNoCompression}, {"snappy", rocksdb::CompressionType::kSnappyCompression}, - {"lz4", rocksdb::CompressionType::kLZ4Compression}, {"zstd", rocksdb::CompressionType::kZSTD}, - {"zlib", rocksdb::CompressionType::kZlibCompression}, {nullptr, 0}}; - -ConfigEnum supervised_modes[] = {{"no", kSupervisedNone}, - {"auto", kSupervisedAutoDetect}, - {"upstart", kSupervisedUpStart}, - {"systemd", kSupervisedSystemd}, - {nullptr, 0}}; - -ConfigEnum log_levels[] = {{"info", google::INFO}, - {"warning", google::WARNING}, - {"error", google::ERROR}, - {"fatal", google::FATAL}, - {nullptr, 0}}; +std::vector supervised_modes{ + {"no", kSupervisedNone}, + {"auto", kSupervisedAutoDetect}, + {"upstart", kSupervisedUpStart}, + {"systemd", kSupervisedSystemd}, +}; + +std::vector log_levels{ + {"info", google::INFO}, + {"warning", google::WARNING}, + {"error", google::ERROR}, + {"fatal", google::FATAL}, +}; std::string TrimRocksDbPrefix(std::string s) { if (strncasecmp(s.data(), "rocksdb.", 8) != 0) return s; return s.substr(8, s.size() - 8); } -int ConfigEnumGetValue(ConfigEnum *ce, const char *name) { - while (ce->name != nullptr) { - if (strcasecmp(ce->name, name) == 0) return ce->val; - ce++; +int ConfigEnumGetValue(const std::vector &enums, const char *name) { + for (const auto &e : enums) { + if (strcasecmp(e.name, name) == 0) return e.val; } return INT_MIN; } -const char *ConfigEnumGetName(ConfigEnum *ce, int val) { - while (ce->name != nullptr) { - if (ce->val == val) return ce->name; - ce++; +const char *ConfigEnumGetName(const std::vector &enums, int val) { + for (const auto &e : enums) { + if (e.val == val) return e.name; } return nullptr; } @@ -92,6 +87,11 @@ Config::Config() { FieldWrapper(std::string name, bool readonly, ConfigField *field) : name(std::move(name)), readonly(readonly), field(field) {} }; + + std::vector compression_types; + for (const auto &e : *engine::GetCompressionOptions()) { + compression_types.push_back({e.name, e.type}); + } FieldWrapper fields[] = { {"daemonize", true, new YesNoField(&daemonize, false)}, {"bind", true, new StringField(&binds_str_, "")}, @@ -328,6 +328,30 @@ void Config::initFieldCallback() { if (!srv) return Status::OK(); // srv is nullptr when load config from file return srv->storage->SetOptionForAllColumnFamilies(TrimRocksDbPrefix(k), v); }; + auto set_compression_type_cb = [](Server *srv, const std::string &k, const std::string &v) -> Status { + if (!srv) return Status::OK(); + + std::string compression_option = ""; + for (auto &option : *engine::GetCompressionOptions()) { + if (option.name == v) { + compression_option = option.val; + break; + } + } + if (compression_option.empty()) { + return {Status::NotOK, "Invalid compression type"}; + } + + // For the first two levels, it may contain the frequently accessed data, + // so it'd be better to use uncompressed data to save the CPU. + std::string compression_levels = "kNoCompression:kNoCompression"; + auto db = srv->storage->GetDB(); + for (size_t i = 2; i < db->GetOptions().compression_per_level.size(); i++) { + compression_levels += ":"; + compression_levels += compression_option; + } + return srv->storage->SetOptionForAllColumnFamilies("compression_per_level", compression_levels); + }; #ifdef ENABLE_OPENSSL auto set_tls_option = [](Server *srv, const std::string &k, const std::string &v) { if (!srv) return Status::OK(); // srv is nullptr when load config from file @@ -601,11 +625,7 @@ void Config::initFieldCallback() { {"rocksdb.level0_slowdown_writes_trigger", set_cf_option_cb}, {"rocksdb.level0_stop_writes_trigger", set_cf_option_cb}, {"rocksdb.level0_file_num_compaction_trigger", set_cf_option_cb}, - {"rocksdb.compression", - [](Server *srv, const std::string &k, const std::string &v) -> Status { - if (!srv) return Status::OK(); - return srv->storage->SetCompressionOption(TrimRocksDbPrefix(k), v); - }}, + {"rocksdb.compression", set_compression_type_cb}, #ifdef ENABLE_OPENSSL {"tls-cert-file", set_tls_option}, {"tls-key-file", set_tls_option}, diff --git a/src/config/config_type.h b/src/config/config_type.h index 12e78a6dbd2..3c010490a10 100644 --- a/src/config/config_type.h +++ b/src/config/config_type.h @@ -53,8 +53,8 @@ struct ConfigEnum { enum ConfigType { SingleConfig, MultiConfig }; -int ConfigEnumGetValue(ConfigEnum *ce, const char *name); -const char *ConfigEnumGetName(ConfigEnum *ce, int val); +int ConfigEnumGetValue(const std::vector &enums, const char *name); +const char *ConfigEnumGetName(const std::vector &enums, int val); class ConfigField { public: @@ -186,7 +186,9 @@ class YesNoField : public ConfigField { class EnumField : public ConfigField { public: - EnumField(int *receiver, ConfigEnum *enums, int e) : receiver_(receiver), enums_(enums) { *receiver_ = e; } + EnumField(int *receiver, const std::vector &enums, int e) : receiver_(receiver), enums_(enums) { + *receiver_ = e; + } ~EnumField() override = default; std::string ToString() override { return ConfigEnumGetName(enums_, *receiver_); } Status ToNumber(int64_t *n) override { @@ -204,5 +206,5 @@ class EnumField : public ConfigField { private: int *receiver_; - ConfigEnum *enums_ = nullptr; + std::vector enums_; }; diff --git a/src/storage/event_listener.cc b/src/storage/event_listener.cc index ea4ed2b4e8d..a43795f9d7c 100644 --- a/src/storage/event_listener.cc +++ b/src/storage/event_listener.cc @@ -40,6 +40,15 @@ std::string StallConditionType2String(const rocksdb::WriteStallCondition type) { return "unknown"; } +std::string CompressType2String(const rocksdb::CompressionType type) { + for (const auto &option : *engine::GetCompressionOptions()) { + if (option.type == type) { + return option.name; + } + } + return "unknown"; +} + bool IsDiskQuotaExceeded(const rocksdb::Status &bg_error) { // EDQUOT: Disk quota exceeded (POSIX.1-2001) std::string exceeded_quota_str = "Disk quota exceeded"; @@ -51,7 +60,7 @@ bool IsDiskQuotaExceeded(const rocksdb::Status &bg_error) { void EventListener::OnCompactionCompleted(rocksdb::DB *db, const rocksdb::CompactionJobInfo &ci) { LOG(INFO) << "[event_listener/compaction_completed] column family: " << ci.cf_name << ", compaction reason: " << static_cast(ci.compaction_reason) - << ", output compression type: " << engine::Storage::CompressType2String(ci.compression) + << ", output compression type: " << CompressType2String(ci.compression) << ", base input level(files): " << ci.base_input_level << "(" << ci.input_files.size() << ")" << ", output level(files): " << ci.output_level << "(" << ci.output_files.size() << ")" << ", input bytes: " << ci.stats.total_input_bytes << ", output bytes:" << ci.stats.total_output_bytes diff --git a/src/storage/storage.cc b/src/storage/storage.cc index 6949428dcab..2729273ce42 100644 --- a/src/storage/storage.cc +++ b/src/storage/storage.cc @@ -54,24 +54,17 @@ constexpr const char *kReplicationIdKey = "replication_id_"; const int64_t kIORateLimitMaxMb = 1024000; +const static std::vector compressionOptions = { + {rocksdb::kNoCompression, "no", "kNoCompression"}, + {rocksdb::kSnappyCompression, "snappy", "kSnappyCompression"}, + {rocksdb::kZlibCompression, "zlib", "kZlibCompression"}, + {rocksdb::kLZ4Compression, "lz4", "kLZ4Compression"}, + {rocksdb::kZSTD, "zstd", "kZSTD"}, +}; + using rocksdb::Slice; -const static std::map compression_sort_long_string_map = {{"no", "kNoCompression"}, - {"snappy", "kSnappyCompression"}, - {"lz4", "kLZ4Compression"}, - {"zstd", "kZSTD"}, - {"zlib", "kZlibCompression"}}; -const static std::map compression_type_string_map = { - {rocksdb::kNoCompression, "no"}, - {rocksdb::kSnappyCompression, "snappy"}, - {rocksdb::kZlibCompression, "zlib"}, - {rocksdb::kBZip2Compression, "zip2"}, - {rocksdb::kLZ4Compression, "lz4"}, - {rocksdb::kLZ4HCCompression, "lz4hc"}, - {rocksdb::kXpressCompression, "xpress"}, - {rocksdb::kZSTD, "zstd"}, - {rocksdb::kZSTDNotFinalCompression, "zstd_not_final"}, - {rocksdb::kDisableCompressionOption, "disable"}}; +const std::vector *GetCompressionOptions() { return &compressionOptions; } Storage::Storage(Config *config) : backup_creating_time_(util::GetTimeStamp()), env_(rocksdb::Env::Default()), config_(config), lock_mgr_(16) { @@ -199,41 +192,6 @@ rocksdb::Options Storage::InitRocksDBOptions() { return options; } -std::string Storage::CompressType2String(const rocksdb::CompressionType &type) { - auto iter = compression_type_string_map.find(type); - if (iter == compression_type_string_map.end()) { - return "unknown"; - } - return iter->second; -} - -std::string Storage::CompressString2CompressionString(const std::string &type) { - auto iter = compression_sort_long_string_map.find(type); - if (iter == compression_sort_long_string_map.end()) { - return "unknown"; - } - return iter->second; -} - -Status Storage::SetCompressionOption(const std::string &key, const std::string &value) { - std::string compression_string = CompressString2CompressionString(value); - if ("unknown" == compression_string) { - return {Status::NotOK, "Invalid compression type"}; - } - std::string compression_levels = "kNoCompression:kNoCompression"; - // only compress levels >= 2 - for (size_t i = 2; i < db_->GetOptions().compression_per_level.size(); i++) { - compression_levels += ":"; - compression_levels += compression_string; - } - - for (auto &cf_handle : cf_handles_) { - auto s = db_->SetOptions(cf_handle, {{"compression_per_level", compression_levels}}); - if (!s.ok()) return {Status::NotOK, s.ToString()}; - } - return Status::OK(); -} - Status Storage::SetOptionForAllColumnFamilies(const std::string &key, const std::string &value) { for (auto &cf_handle : cf_handles_) { auto s = db_->SetOptions(cf_handle, {{key, value}}); diff --git a/src/storage/storage.h b/src/storage/storage.h index 1723f54e17b..d2d7b8a6092 100644 --- a/src/storage/storage.h +++ b/src/storage/storage.h @@ -64,6 +64,14 @@ constexpr const char *kPropagateScriptCommand = "script"; constexpr const char *kLuaFunctionPrefix = "lua_f_"; +struct CompressionOption { + rocksdb::CompressionType type; + const char *name; + const char *val; +}; + +const std::vector *GetCompressionOptions(); + class Storage { public: explicit Storage(Config *config); @@ -79,7 +87,6 @@ class Storage { Status SetOptionForAllColumnFamilies(const std::string &key, const std::string &value); Status SetOption(const std::string &key, const std::string &value); Status SetDBOption(const std::string &key, const std::string &value); - Status SetCompressionOption(const std::string &key, const std::string &value); Status CreateColumnFamilies(const rocksdb::Options &options); Status CreateBackup(); void DestroyBackup(); @@ -177,8 +184,6 @@ class Storage { Status ShiftReplId(); std::string GetReplIdFromWalBySeq(rocksdb::SequenceNumber seq); std::string GetReplIdFromDbEngine(); - static std::string CompressType2String(const rocksdb::CompressionType &type); - static std::string CompressString2CompressionString(const std::string &type); private: std::unique_ptr db_ = nullptr; diff --git a/tests/gocase/unit/config/config_test.go b/tests/gocase/unit/config/config_test.go index cec4c0f12c2..2bca988af60 100644 --- a/tests/gocase/unit/config/config_test.go +++ b/tests/gocase/unit/config/config_test.go @@ -109,7 +109,7 @@ func TestSetConfigBackupDir(t *testing.T) { require.True(t, hasCompactionFiles(originBackupDir)) } -func TestSetConfigCompression(t *testing.T) { +func TestConfigSetCompression(t *testing.T) { configs := map[string]string{} srv := util.StartServer(t, configs) defer srv.Close() @@ -119,22 +119,13 @@ func TestSetConfigCompression(t *testing.T) { defer func() { require.NoError(t, rdb.Close()) }() require.NoError(t, rdb.Do(ctx, "SET", "foo", "bar").Err()) - require.Equal(t, "bar", rdb.Get(ctx, "foo").Val()) - r := rdb.Do(ctx, "CONFIG", "GET", "rocksdb.compression") - rList := r.Val().([]interface{}) - require.EqualValues(t, rList[1], "no") - - require.NoError(t, rdb.Do(ctx, "CONFIG", "SET", "rocksdb.compression", "lz4").Err()) - require.Equal(t, "bar", rdb.Get(ctx, "foo").Val()) - r = rdb.Do(ctx, "CONFIG", "GET", "rocksdb.compression") - rList = r.Val().([]interface{}) - require.EqualValues(t, rList[1], "lz4") - - require.NoError(t, rdb.Do(ctx, "CONFIG", "SET", "rocksdb.compression", "zstd").Err()) - require.Equal(t, "bar", rdb.Get(ctx, "foo").Val()) - r = rdb.Do(ctx, "CONFIG", "GET", "rocksdb.compression") - rList = r.Val().([]interface{}) - require.EqualValues(t, rList[1], "zstd") - - require.ErrorContains(t, rdb.Do(ctx, "CONFIG", "SET", "rocksdb.compression", "undefine").Err(), "invalid enum option") + configKey := "rocksdb.compression" + supportedCompressions := []string{"no", "snappy", "zlib", "lz4", "zstd"} + for _, compression := range supportedCompressions { + require.NoError(t, rdb.ConfigSet(ctx, configKey, compression).Err()) + vals, err := rdb.ConfigGet(ctx, configKey).Result() + require.NoError(t, err) + require.EqualValues(t, compression, vals[configKey]) + } + require.ErrorContains(t, rdb.ConfigSet(ctx, configKey, "unsupported").Err(), "invalid enum option") } From 679bbc496ca8994a3c9744f7808032ac81ee59f1 Mon Sep 17 00:00:00 2001 From: git-hulk Date: Fri, 14 Jul 2023 19:48:30 +0800 Subject: [PATCH 05/10] Fix tidy error --- src/config/config_type.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/config/config_type.h b/src/config/config_type.h index 3c010490a10..ab1cb9bc832 100644 --- a/src/config/config_type.h +++ b/src/config/config_type.h @@ -186,8 +186,9 @@ class YesNoField : public ConfigField { class EnumField : public ConfigField { public: - EnumField(int *receiver, const std::vector &enums, int e) : receiver_(receiver), enums_(enums) { + EnumField(int *receiver, std::vector &enums, int e) : receiver_(receiver), enums_(std::move(enums)){ *receiver_ = e; + } ~EnumField() override = default; std::string ToString() override { return ConfigEnumGetName(enums_, *receiver_); } From b56e3d712d3131889ebd670b90621abf75df3bfb Mon Sep 17 00:00:00 2001 From: git-hulk Date: Fri, 14 Jul 2023 20:29:30 +0800 Subject: [PATCH 06/10] Change char * to the string in ConfigEnum --- src/config/config.cc | 14 +++++++------- src/config/config_type.h | 11 +++++------ src/storage/event_listener.cc | 2 +- src/storage/storage.cc | 2 +- src/storage/storage.h | 6 +++--- 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/config/config.cc b/src/config/config.cc index 1e92fc45b76..f2128e1d1db 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -64,18 +64,18 @@ std::string TrimRocksDbPrefix(std::string s) { return s.substr(8, s.size() - 8); } -int ConfigEnumGetValue(const std::vector &enums, const char *name) { +int ConfigEnumGetValue(const std::vector &enums, const std::string &name) { for (const auto &e : enums) { - if (strcasecmp(e.name, name) == 0) return e.val; + if (strcasecmp(e.name.c_str(), name.c_str()) == 0) return e.val; } return INT_MIN; } -const char *ConfigEnumGetName(const std::vector &enums, int val) { +std::string ConfigEnumGetName(const std::vector &enums, int val) { for (const auto &e : enums) { if (e.val == val) return e.name; } - return nullptr; + return {}; } Config::Config() { @@ -89,7 +89,7 @@ Config::Config() { }; std::vector compression_types; - for (const auto &e : *engine::GetCompressionOptions()) { + for (const auto &e : engine::GetCompressionOptions()) { compression_types.push_back({e.name, e.type}); } FieldWrapper fields[] = { @@ -331,8 +331,8 @@ void Config::initFieldCallback() { auto set_compression_type_cb = [](Server *srv, const std::string &k, const std::string &v) -> Status { if (!srv) return Status::OK(); - std::string compression_option = ""; - for (auto &option : *engine::GetCompressionOptions()) { + std::string compression_option; + for (auto &option : engine::GetCompressionOptions()) { if (option.name == v) { compression_option = option.val; break; diff --git a/src/config/config_type.h b/src/config/config_type.h index ab1cb9bc832..4a4a8d7e0b1 100644 --- a/src/config/config_type.h +++ b/src/config/config_type.h @@ -47,14 +47,14 @@ using UInt32Field = IntegerField; using Int64Field = IntegerField; struct ConfigEnum { - const char *name; + const std::string name; const int val; }; enum ConfigType { SingleConfig, MultiConfig }; -int ConfigEnumGetValue(const std::vector &enums, const char *name); -const char *ConfigEnumGetName(const std::vector &enums, int val); +int ConfigEnumGetValue(const std::vector &enums, const std::string &name); +std::string ConfigEnumGetName(const std::vector &enums, int val); class ConfigField { public: @@ -186,9 +186,8 @@ class YesNoField : public ConfigField { class EnumField : public ConfigField { public: - EnumField(int *receiver, std::vector &enums, int e) : receiver_(receiver), enums_(std::move(enums)){ + EnumField(int *receiver, std::vector &enums, int e) : receiver_(receiver), enums_(std::move(enums)) { *receiver_ = e; - } ~EnumField() override = default; std::string ToString() override { return ConfigEnumGetName(enums_, *receiver_); } @@ -197,7 +196,7 @@ class EnumField : public ConfigField { return Status::OK(); } Status Set(const std::string &v) override { - int e = ConfigEnumGetValue(enums_, v.c_str()); + int e = ConfigEnumGetValue(enums_, v); if (e == INT_MIN) { return {Status::NotOK, "invalid enum option"}; } diff --git a/src/storage/event_listener.cc b/src/storage/event_listener.cc index a43795f9d7c..a479f760f65 100644 --- a/src/storage/event_listener.cc +++ b/src/storage/event_listener.cc @@ -41,7 +41,7 @@ std::string StallConditionType2String(const rocksdb::WriteStallCondition type) { } std::string CompressType2String(const rocksdb::CompressionType type) { - for (const auto &option : *engine::GetCompressionOptions()) { + for (const auto &option : engine::GetCompressionOptions()) { if (option.type == type) { return option.name; } diff --git a/src/storage/storage.cc b/src/storage/storage.cc index 2729273ce42..2a257a909c4 100644 --- a/src/storage/storage.cc +++ b/src/storage/storage.cc @@ -64,7 +64,7 @@ const static std::vector compressionOptions = { using rocksdb::Slice; -const std::vector *GetCompressionOptions() { return &compressionOptions; } +const std::vector GetCompressionOptions() { return compressionOptions; } Storage::Storage(Config *config) : backup_creating_time_(util::GetTimeStamp()), env_(rocksdb::Env::Default()), config_(config), lock_mgr_(16) { diff --git a/src/storage/storage.h b/src/storage/storage.h index d2d7b8a6092..fc6e020493d 100644 --- a/src/storage/storage.h +++ b/src/storage/storage.h @@ -66,11 +66,11 @@ constexpr const char *kLuaFunctionPrefix = "lua_f_"; struct CompressionOption { rocksdb::CompressionType type; - const char *name; - const char *val; + const std::string name; + const std::string val; }; -const std::vector *GetCompressionOptions(); +const std::vector GetCompressionOptions(); class Storage { public: From f2b0428066cda9a7dd0bd8ceb0ca83984623420d Mon Sep 17 00:00:00 2001 From: git-hulk Date: Fri, 14 Jul 2023 20:35:30 +0800 Subject: [PATCH 07/10] Fix tidy warning --- src/storage/storage.cc | 2 +- src/storage/storage.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storage/storage.cc b/src/storage/storage.cc index 2a257a909c4..0dd65071a07 100644 --- a/src/storage/storage.cc +++ b/src/storage/storage.cc @@ -64,7 +64,7 @@ const static std::vector compressionOptions = { using rocksdb::Slice; -const std::vector GetCompressionOptions() { return compressionOptions; } +std::vector GetCompressionOptions() { return compressionOptions; } Storage::Storage(Config *config) : backup_creating_time_(util::GetTimeStamp()), env_(rocksdb::Env::Default()), config_(config), lock_mgr_(16) { diff --git a/src/storage/storage.h b/src/storage/storage.h index fc6e020493d..579bb08a7b9 100644 --- a/src/storage/storage.h +++ b/src/storage/storage.h @@ -70,7 +70,7 @@ struct CompressionOption { const std::string val; }; -const std::vector GetCompressionOptions(); +std::vector GetCompressionOptions(); class Storage { public: From 0c6de890e6d54a96a4dd159eabf59be9f14b03d1 Mon Sep 17 00:00:00 2001 From: hulk Date: Sun, 16 Jul 2023 14:33:31 +0800 Subject: [PATCH 08/10] Update src/config/config_type.h Co-authored-by: Twice --- src/config/config_type.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/config_type.h b/src/config/config_type.h index 4a4a8d7e0b1..852907de6a7 100644 --- a/src/config/config_type.h +++ b/src/config/config_type.h @@ -186,7 +186,7 @@ class YesNoField : public ConfigField { class EnumField : public ConfigField { public: - EnumField(int *receiver, std::vector &enums, int e) : receiver_(receiver), enums_(std::move(enums)) { + EnumField(int *receiver, std::vector enums, int e) : receiver_(receiver), enums_(std::move(enums)) { *receiver_ = e; } ~EnumField() override = default; From f2615e13c5e19d7a11cfa79cad9dc433f337aa97 Mon Sep 17 00:00:00 2001 From: git-hulk Date: Sun, 16 Jul 2023 15:03:09 +0800 Subject: [PATCH 09/10] Fix review comments --- src/config/config.cc | 18 ++---------------- src/config/config_type.h | 24 +++++++++++++++--------- src/storage/event_listener.cc | 2 +- src/storage/storage.cc | 10 ---------- src/storage/storage.h | 8 +++++++- 5 files changed, 25 insertions(+), 37 deletions(-) diff --git a/src/config/config.cc b/src/config/config.cc index f2128e1d1db..20ba6b4fffe 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -64,20 +64,6 @@ std::string TrimRocksDbPrefix(std::string s) { return s.substr(8, s.size() - 8); } -int ConfigEnumGetValue(const std::vector &enums, const std::string &name) { - for (const auto &e : enums) { - if (strcasecmp(e.name.c_str(), name.c_str()) == 0) return e.val; - } - return INT_MIN; -} - -std::string ConfigEnumGetName(const std::vector &enums, int val) { - for (const auto &e : enums) { - if (e.val == val) return e.name; - } - return {}; -} - Config::Config() { struct FieldWrapper { std::string name; @@ -89,7 +75,7 @@ Config::Config() { }; std::vector compression_types; - for (const auto &e : engine::GetCompressionOptions()) { + for (const auto &e : engine::CompressionOptions) { compression_types.push_back({e.name, e.type}); } FieldWrapper fields[] = { @@ -332,7 +318,7 @@ void Config::initFieldCallback() { if (!srv) return Status::OK(); std::string compression_option; - for (auto &option : engine::GetCompressionOptions()) { + for (auto &option : engine::CompressionOptions) { if (option.name == v) { compression_option = option.val; break; diff --git a/src/config/config_type.h b/src/config/config_type.h index 852907de6a7..5c11af65301 100644 --- a/src/config/config_type.h +++ b/src/config/config_type.h @@ -53,9 +53,6 @@ struct ConfigEnum { enum ConfigType { SingleConfig, MultiConfig }; -int ConfigEnumGetValue(const std::vector &enums, const std::string &name); -std::string ConfigEnumGetName(const std::vector &enums, int val); - class ConfigField { public: ConfigField() = default; @@ -190,18 +187,27 @@ class EnumField : public ConfigField { *receiver_ = e; } ~EnumField() override = default; - std::string ToString() override { return ConfigEnumGetName(enums_, *receiver_); } + + std::string ToString() override { + for (const auto &e : enums_) { + if (e.val == *receiver_) return e.name; + } + return {}; + } + Status ToNumber(int64_t *n) override { *n = *receiver_; return Status::OK(); } + Status Set(const std::string &v) override { - int e = ConfigEnumGetValue(enums_, v); - if (e == INT_MIN) { - return {Status::NotOK, "invalid enum option"}; + for (const auto &e : enums_) { + if (strcasecmp(e.name.c_str(), v.c_str()) == 0) { + *receiver_ = e.val; + return Status::OK(); + } } - *receiver_ = e; - return Status::OK(); + return {Status::NotOK, "invalid enum option"}; } private: diff --git a/src/storage/event_listener.cc b/src/storage/event_listener.cc index a479f760f65..46f399fc029 100644 --- a/src/storage/event_listener.cc +++ b/src/storage/event_listener.cc @@ -41,7 +41,7 @@ std::string StallConditionType2String(const rocksdb::WriteStallCondition type) { } std::string CompressType2String(const rocksdb::CompressionType type) { - for (const auto &option : engine::GetCompressionOptions()) { + for (const auto &option : engine::CompressionOptions) { if (option.type == type) { return option.name; } diff --git a/src/storage/storage.cc b/src/storage/storage.cc index 0dd65071a07..68bbe119edf 100644 --- a/src/storage/storage.cc +++ b/src/storage/storage.cc @@ -54,18 +54,8 @@ constexpr const char *kReplicationIdKey = "replication_id_"; const int64_t kIORateLimitMaxMb = 1024000; -const static std::vector compressionOptions = { - {rocksdb::kNoCompression, "no", "kNoCompression"}, - {rocksdb::kSnappyCompression, "snappy", "kSnappyCompression"}, - {rocksdb::kZlibCompression, "zlib", "kZlibCompression"}, - {rocksdb::kLZ4Compression, "lz4", "kLZ4Compression"}, - {rocksdb::kZSTD, "zstd", "kZSTD"}, -}; - using rocksdb::Slice; -std::vector GetCompressionOptions() { return compressionOptions; } - Storage::Storage(Config *config) : backup_creating_time_(util::GetTimeStamp()), env_(rocksdb::Env::Default()), config_(config), lock_mgr_(16) { Metadata::InitVersionCounter(); diff --git a/src/storage/storage.h b/src/storage/storage.h index 579bb08a7b9..1b8c2f407df 100644 --- a/src/storage/storage.h +++ b/src/storage/storage.h @@ -70,7 +70,13 @@ struct CompressionOption { const std::string val; }; -std::vector GetCompressionOptions(); +inline const std::vector CompressionOptions = { + {rocksdb::kNoCompression, "no", "kNoCompression"}, + {rocksdb::kSnappyCompression, "snappy", "kSnappyCompression"}, + {rocksdb::kZlibCompression, "zlib", "kZlibCompression"}, + {rocksdb::kLZ4Compression, "lz4", "kLZ4Compression"}, + {rocksdb::kZSTD, "zstd", "kZSTD"}, +}; class Storage { public: From 6240eb0729d0de345bd4a7bc31b9bbf768bbc602 Mon Sep 17 00:00:00 2001 From: git-hulk Date: Sun, 16 Jul 2023 15:38:37 +0800 Subject: [PATCH 10/10] Fix tidy warning --- src/config/config.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/config/config.cc b/src/config/config.cc index 20ba6b4fffe..24db89b1c5c 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -75,6 +75,7 @@ Config::Config() { }; std::vector compression_types; + compression_types.reserve(engine::CompressionOptions.size()); for (const auto &e : engine::CompressionOptions) { compression_types.push_back({e.name, e.type}); }