This is an automated email from the ASF dual-hosted git repository.

twice pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks.git


The following commit(s) were added to refs/heads/unstable by this push:
     new ec523ccec feat: Add support for dictionary compression settings (#3425)
ec523ccec is described below

commit ec523ccec1fe77bde23b942bba1bdef1542448e9
Author: nagisa-kunhah <[email protected]>
AuthorDate: Thu Apr 9 13:04:31 2026 +0800

    feat: Add support for dictionary compression settings (#3425)
    
    issue: #3409
    
    ---------
    
    Co-authored-by: 纪华裕 <[email protected]>
    Co-authored-by: Twice <[email protected]>
---
 kvrocks.conf                            | 13 +++++++++++++
 src/config/config.cc                    |  4 ++++
 src/config/config.h                     |  2 ++
 src/storage/storage.cc                  |  2 ++
 tests/cppunit/config_test.cc            | 28 ++++++++++++++++++++++++++++
 tests/cppunit/storage_test.cc           | 26 ++++++++++++++++++++++++++
 tests/gocase/unit/config/config_test.go |  6 +++++-
 7 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/kvrocks.conf b/kvrocks.conf
index 12add2d19..12b019ca1 100644
--- a/kvrocks.conf
+++ b/kvrocks.conf
@@ -923,6 +923,19 @@ rocksdb.compression snappy
 #   compression library as mentioned above)
 rocksdb.compression_level 32767
 
+# Maximum per-SST dictionary size for block compression. Set to 0 to disable
+# dictionary compression.
+#
+# Default: 0
+rocksdb.compression_max_dict_bytes 0
+
+# Maximum amount of training data used by the ZSTD dictionary trainer. This is
+# most useful when rocksdb.compression is set to zstd and 
rocksdb.compression_max_dict_bytes
+# is non-zero.
+#
+# Default: 0
+rocksdb.compression_zstd_max_train_bytes 0
+
 # If non-zero, we perform bigger reads when doing compaction. If you're
 # running RocksDB on spinning disks, you should set this to at least 2MB.
 # That way RocksDB's compaction is doing sequential instead of random reads.
diff --git a/src/config/config.cc b/src/config/config.cc
index e7bf980ce..416eabd9a 100644
--- a/src/config/config.cc
+++ b/src/config/config.cc
@@ -254,6 +254,10 @@ Config::Config() {
        new EnumField<rocksdb::CompressionType>(&rocks_db.compression, 
compression_types,
                                                
rocksdb::CompressionType::kNoCompression)},
       {"rocksdb.compression_level", true, new 
IntField(&rocks_db.compression_level, 32767, INT_MIN, INT_MAX)},
+      {"rocksdb.compression_max_dict_bytes", true,
+       new UInt32Field(&rocks_db.compression_max_dict_bytes, 0, 0, 
UINT32_MAX)},
+      {"rocksdb.compression_zstd_max_train_bytes", true,
+       new UInt32Field(&rocks_db.compression_zstd_max_train_bytes, 0, 0, 
UINT32_MAX)},
       {"rocksdb.compression_start_level", false,
        new IntField(&rocks_db.compression_start_level, 2, 0, 
KVROCKS_MAX_LSM_LEVEL - 1)},
       {"rocksdb.block_size", true, new IntField(&rocks_db.block_size, 16384, 
0, INT_MAX)},
diff --git a/src/config/config.h b/src/config/config.h
index 675bbd34c..159fb83b5 100644
--- a/src/config/config.h
+++ b/src/config/config.h
@@ -236,6 +236,8 @@ struct Config {
     rocksdb::CompressionType compression;
     int compression_start_level;
     int compression_level;
+    uint32_t compression_max_dict_bytes;
+    uint32_t compression_zstd_max_train_bytes;
     bool disable_auto_compactions;
     bool enable_blob_files;
     int min_blob_size;
diff --git a/src/storage/storage.cc b/src/storage/storage.cc
index ca0f17daa..288524eb0 100644
--- a/src/storage/storage.cc
+++ b/src/storage/storage.cc
@@ -178,6 +178,8 @@ rocksdb::Options Storage::InitRocksDBOptions() {
   options.write_buffer_size = config_->rocks_db.write_buffer_size * MiB;
   options.num_levels = KVROCKS_MAX_LSM_LEVEL;
   options.compression_opts.level = config_->rocks_db.compression_level;
+  options.compression_opts.max_dict_bytes = 
config_->rocks_db.compression_max_dict_bytes;
+  options.compression_opts.zstd_max_train_bytes = 
config_->rocks_db.compression_zstd_max_train_bytes;
   options.compression_per_level.resize(options.num_levels);
   options.wal_compression = config_->rocks_db.wal_compression;
   for (int i = 0; i < options.num_levels; ++i) {
diff --git a/tests/cppunit/config_test.cc b/tests/cppunit/config_test.cc
index b7d931be4..3c78a48f0 100644
--- a/tests/cppunit/config_test.cc
+++ b/tests/cppunit/config_test.cc
@@ -134,6 +134,8 @@ TEST(Config, GetAndSet) {
       {"rocksdb.row_cache_size", "100"},
       {"rocksdb.rate_limiter_auto_tuned", "yes"},
       {"rocksdb.compression_level", "32767"},
+      {"rocksdb.compression_max_dict_bytes", "16384"},
+      {"rocksdb.compression_zstd_max_train_bytes", "262144"},
       {"rocksdb.wal_compression", "no"},
       {"histogram-bucket-boundaries", "10,100,1000,10000"},
 
@@ -189,6 +191,32 @@ TEST(Config, Rewrite) {
   unlink(path);
 }
 
+TEST(Config, LoadRocksDBDictionaryCompressionOptions) {
+  const char *path = "test.conf";
+  unlink(path);
+
+  std::ofstream output_file(path, std::ios::out);
+  output_file << "rocksdb.compression_max_dict_bytes 16384"
+              << "\n";
+  output_file << "rocksdb.compression_zstd_max_train_bytes 262144"
+              << "\n";
+  output_file.close();
+
+  Config config;
+  ASSERT_TRUE(config.Load(CLIOptions(path)).IsOK());
+  ASSERT_EQ(config.rocks_db.compression_max_dict_bytes, 16384U);
+  ASSERT_EQ(config.rocks_db.compression_zstd_max_train_bytes, 262144U);
+
+  ASSERT_TRUE(config.Rewrite({}).IsOK());
+
+  Config rewritten_config;
+  ASSERT_TRUE(rewritten_config.Load(CLIOptions(path)).IsOK());
+  ASSERT_EQ(rewritten_config.rocks_db.compression_max_dict_bytes, 16384U);
+  ASSERT_EQ(rewritten_config.rocks_db.compression_zstd_max_train_bytes, 
262144U);
+
+  unlink(path);
+}
+
 TEST(Config, ParseConfigLine) {
   ASSERT_EQ(*ParseConfigLine(""), ConfigKV{});
   ASSERT_EQ(*ParseConfigLine("# hello"), ConfigKV{});
diff --git a/tests/cppunit/storage_test.cc b/tests/cppunit/storage_test.cc
index 96fffd335..3b403e376 100644
--- a/tests/cppunit/storage_test.cc
+++ b/tests/cppunit/storage_test.cc
@@ -22,8 +22,10 @@
 #include <gtest/gtest.h>
 #include <status.h>
 #include <storage/storage.h>
+#include <unistd.h>
 
 #include <filesystem>
+#include <fstream>
 
 TEST(Storage, CreateBackup) {
   std::error_code ec;
@@ -103,3 +105,27 @@ TEST(Storage, ReadOnlyTransactions) {
   std::filesystem::remove_all(config.db_dir, ec);
   ASSERT_TRUE(!ec);
 }
+
+TEST(Storage, RocksDBDictionaryCompressionOptions) {
+  const char *path = "test_storage_options.conf";
+  unlink(path);
+
+  std::ofstream output_file(path, std::ios::out);
+  output_file << "rocksdb.compression_max_dict_bytes 16384\n";
+  output_file << "rocksdb.compression_zstd_max_train_bytes 262144\n";
+  output_file.close();
+
+  Config config;
+  ASSERT_TRUE(config.Load(CLIOptions(path)).IsOK());
+  config.db_dir = "test_storage_options_dir";
+
+  auto storage = std::make_unique<engine::Storage>(&config);
+  auto s = storage->Open();
+  ASSERT_TRUE(s.IsOK());
+
+  const auto options = storage->GetDB()->GetOptions();
+  EXPECT_EQ(options.compression_opts.max_dict_bytes, 16384U);
+  EXPECT_EQ(options.compression_opts.zstd_max_train_bytes, 262144U);
+
+  unlink(path);
+}
diff --git a/tests/gocase/unit/config/config_test.go 
b/tests/gocase/unit/config/config_test.go
index 1dcb4f8a5..b9e087e9b 100644
--- a/tests/gocase/unit/config/config_test.go
+++ b/tests/gocase/unit/config/config_test.go
@@ -123,10 +123,14 @@ func TestConfigSetCompression(t *testing.T) {
        require.NoError(t, rdb.Do(ctx, "SET", "foo", "bar").Err())
 
        configKey := "rocksdb.compression"
+       vals, err := rdb.ConfigGet(ctx, configKey).Result()
+       require.NoError(t, err)
+       require.EqualValues(t, "no", vals[configKey])
+
        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()
+               vals, err = rdb.ConfigGet(ctx, configKey).Result()
                require.NoError(t, err)
                require.EqualValues(t, compression, vals[configKey])
        }

Reply via email to