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

PragmaTwice 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 9c4112590 chore(scan): remove additional abstraction for subkey 
scanning (#3490)
9c4112590 is described below

commit 9c411259020ad46e6ed04575db6768e83e26e32f
Author: Twice <[email protected]>
AuthorDate: Sun May 17 18:25:15 2026 +0800

    chore(scan): remove additional abstraction for subkey scanning (#3490)
    
    These abstraction is for hash subkey scanning, but now we don't use it
    anymore. So better to remove them.
---
 src/storage/redis_db.cc | 37 +++++++++++++++++++++++++++-
 src/storage/redis_db.h  | 64 -------------------------------------------------
 2 files changed, 36 insertions(+), 65 deletions(-)

diff --git a/src/storage/redis_db.cc b/src/storage/redis_db.cc
index 1452d01ee..99b3d96a3 100644
--- a/src/storage/redis_db.cc
+++ b/src/storage/redis_db.cc
@@ -558,7 +558,42 @@ rocksdb::Status Database::KeyExist(engine::Context &ctx, 
const std::string &key)
 rocksdb::Status SubKeyScanner::Scan(engine::Context &ctx, RedisType type, 
const Slice &user_key,
                                     const std::string &cursor, uint64_t limit, 
const std::string &subkey_prefix,
                                     std::vector<std::string> *keys, 
std::vector<std::string> *values) {
-  return scanSubkeys<Metadata>(ctx, type, user_key, cursor, limit, 
subkey_prefix, keys, values);
+  uint64_t cnt = 0;
+  std::string ns_key = AppendNamespacePrefix(user_key);
+  Metadata metadata(type, false);
+  rocksdb::Status s = GetMetadata(ctx, {type}, ns_key, &metadata);
+  if (!s.ok()) return s;
+
+  auto iter = util::UniqueIterator(ctx, ctx.DefaultScanOptions());
+  std::string match_prefix_key =
+      InternalKey(ns_key, subkey_prefix, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+
+  std::string start_key;
+  if (!cursor.empty()) {
+    start_key = InternalKey(ns_key, cursor, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
+  } else {
+    start_key = match_prefix_key;
+  }
+  for (iter->Seek(start_key); iter->Valid(); iter->Next()) {
+    if (!cursor.empty() && iter->key() == start_key) {
+      // if cursor is not empty, then we need to skip start_key
+      // because we already return that key in the last scan
+      continue;
+    }
+    if (!iter->key().starts_with(match_prefix_key)) {
+      break;
+    }
+    InternalKey ikey(iter->key(), storage_->IsSlotIdEncoded());
+    keys->emplace_back(ikey.GetSubKey().ToString());
+    if (values != nullptr) {
+      values->emplace_back(iter->value().ToString());
+    }
+    cnt++;
+    if (limit > 0 && cnt >= limit) {
+      break;
+    }
+  }
+  return iter->status();
 }
 
 RedisType WriteBatchLogData::GetRedisType() const { return type_; }
diff --git a/src/storage/redis_db.h b/src/storage/redis_db.h
index 8986790a2..506dc250b 100644
--- a/src/storage/redis_db.h
+++ b/src/storage/redis_db.h
@@ -22,13 +22,11 @@
 
 #include <optional>
 #include <string>
-#include <type_traits>
 #include <utility>
 #include <variant>
 #include <vector>
 
 #include "cluster/cluster_defs.h"
-#include "common/db_util.h"
 #include "redis_metadata.h"
 #include "storage.h"
 
@@ -184,68 +182,6 @@ class SubKeyScanner : public redis::Database {
   rocksdb::Status Scan(engine::Context &ctx, RedisType type, const Slice 
&user_key, const std::string &cursor,
                        uint64_t limit, const std::string &subkey_prefix, 
std::vector<std::string> *keys,
                        std::vector<std::string> *values = nullptr);
-
- protected:
-  struct RawSubkeyValueAdapter {
-    template <typename MetadataT>
-    rocksdb::Status operator()(const MetadataT &, Slice *) const {
-      return rocksdb::Status::OK();
-    }
-  };
-
-  template <typename MetadataT>
-  static MetadataT createScanMetadata(RedisType type) {
-    if constexpr (std::is_same_v<MetadataT, Metadata>) {
-      return Metadata(type, false);
-    } else {
-      return MetadataT(false);
-    }
-  }
-
-  template <typename MetadataT, typename ValueAdapter = RawSubkeyValueAdapter>
-  rocksdb::Status scanSubkeys(engine::Context &ctx, RedisType type, const 
Slice &user_key, const std::string &cursor,
-                              uint64_t limit, const std::string 
&subkey_prefix, std::vector<std::string> *keys,
-                              std::vector<std::string> *values = nullptr, 
ValueAdapter value_adapter = {}) {
-    uint64_t cnt = 0;
-    std::string ns_key = AppendNamespacePrefix(user_key);
-    auto metadata = createScanMetadata<MetadataT>(type);
-    rocksdb::Status s = GetMetadata(ctx, {type}, ns_key, &metadata);
-    if (!s.ok()) return s;
-
-    auto iter = util::UniqueIterator(ctx, ctx.DefaultScanOptions());
-    std::string match_prefix_key =
-        InternalKey(ns_key, subkey_prefix, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
-
-    std::string start_key;
-    if (!cursor.empty()) {
-      start_key = InternalKey(ns_key, cursor, metadata.version, 
storage_->IsSlotIdEncoded()).Encode();
-    } else {
-      start_key = match_prefix_key;
-    }
-    for (iter->Seek(start_key); iter->Valid(); iter->Next()) {
-      if (!cursor.empty() && iter->key() == start_key) {
-        // if cursor is not empty, then we need to skip start_key
-        // because we already return that key in the last scan
-        continue;
-      }
-      if (!iter->key().starts_with(match_prefix_key)) {
-        break;
-      }
-      InternalKey ikey(iter->key(), storage_->IsSlotIdEncoded());
-      keys->emplace_back(ikey.GetSubKey().ToString());
-      if (values != nullptr) {
-        Slice value(iter->value());
-        s = value_adapter(metadata, &value);
-        if (!s.ok()) return s;
-        values->emplace_back(value.data(), value.size());
-      }
-      cnt++;
-      if (limit > 0 && cnt >= limit) {
-        break;
-      }
-    }
-    return iter->status();
-  }
 };
 
 class WriteBatchLogData {

Reply via email to