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 {