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 a4982669 chore(storage): remove FindKeyRangeWithPrefix and fix 
DeleteRange (#2343)
a4982669 is described below

commit a4982669419a06b6e467372c32a72d91d7e8d55a
Author: Twice <[email protected]>
AuthorDate: Fri May 31 20:07:40 2024 +0900

    chore(storage): remove FindKeyRangeWithPrefix and fix DeleteRange (#2343)
---
 src/commands/cmd_server.cc | 14 ++---------
 src/common/string_util.cc  | 10 ++++++++
 src/common/string_util.h   |  1 +
 src/storage/redis_db.cc    | 59 ++++------------------------------------------
 src/storage/redis_db.h     |  3 ---
 src/storage/storage.cc     | 22 +++++++----------
 src/storage/storage.h      |  4 +++-
 7 files changed, 29 insertions(+), 84 deletions(-)

diff --git a/src/commands/cmd_server.cc b/src/commands/cmd_server.cc
index 7362e298..bde60fa5 100644
--- a/src/commands/cmd_server.cc
+++ b/src/commands/cmd_server.cc
@@ -874,18 +874,8 @@ class CommandCompact : public Commander {
     auto ns = conn->GetNamespace();
 
     if (ns != kDefaultNamespace) {
-      std::string prefix = ComposeNamespaceKey(ns, "", false);
-
-      redis::Database redis_db(srv->storage, conn->GetNamespace());
-      auto s = redis_db.FindKeyRangeWithPrefix(prefix, std::string(), 
&begin_key, &end_key);
-      if (!s.ok()) {
-        if (s.IsNotFound()) {
-          *output = redis::SimpleString("OK");
-          return Status::OK();
-        }
-
-        return {Status::RedisExecErr, s.ToString()};
-      }
+      begin_key = ComposeNamespaceKey(ns, "", false);
+      end_key = util::StringNext(begin_key);
     }
 
     Status s = srv->AsyncCompactDB(begin_key, end_key);
diff --git a/src/common/string_util.cc b/src/common/string_util.cc
index e9088042..4a4d79a8 100644
--- a/src/common/string_util.cc
+++ b/src/common/string_util.cc
@@ -377,4 +377,14 @@ std::string EscapeString(std::string_view s) {
   return str;
 }
 
+std::string StringNext(std::string s) {
+  for (auto iter = s.rbegin(); iter != s.rend(); ++iter) {
+    if (*iter != char(0xff)) {
+      (*iter)++;
+      break;
+    }
+  }
+  return s;
+}
+
 }  // namespace util
diff --git a/src/common/string_util.h b/src/common/string_util.h
index 45c4a31d..da345b30 100644
--- a/src/common/string_util.h
+++ b/src/common/string_util.h
@@ -38,6 +38,7 @@ std::vector<std::string> RegexMatch(const std::string &str, 
const std::string &r
 std::string StringToHex(std::string_view input);
 std::vector<std::string> TokenizeRedisProtocol(const std::string &value);
 std::string EscapeString(std::string_view s);
+std::string StringNext(std::string s);
 
 template <typename T, typename F>
 std::string StringJoin(
diff --git a/src/storage/redis_db.cc b/src/storage/redis_db.cc
index 3038a000..4f08490b 100644
--- a/src/storage/redis_db.cc
+++ b/src/storage/redis_db.cc
@@ -433,12 +433,9 @@ rocksdb::Status Database::RandomKey(const std::string 
&cursor, std::string *key)
 }
 
 rocksdb::Status Database::FlushDB() {
-  std::string begin_key, end_key;
-  std::string prefix = ComposeNamespaceKey(namespace_, "", false);
-  auto s = FindKeyRangeWithPrefix(prefix, std::string(), &begin_key, &end_key);
-  if (!s.ok()) {
-    return rocksdb::Status::OK();
-  }
+  auto begin_key = ComposeNamespaceKey(namespace_, "", false);
+  auto end_key = util::StringNext(begin_key);
+
   return storage_->DeleteRange(begin_key, end_key);
 }
 
@@ -456,7 +453,7 @@ rocksdb::Status Database::FlushAll() {
   if (!iter->Valid()) {
     return rocksdb::Status::OK();
   }
-  auto last_key = iter->key().ToString();
+  auto last_key = util::StringNext(iter->key().ToString());
   return storage_->DeleteRange(first_key, last_key);
 }
 
@@ -523,54 +520,6 @@ std::string Database::AppendNamespacePrefix(const Slice 
&user_key) {
   return ComposeNamespaceKey(namespace_, user_key, 
storage_->IsSlotIdEncoded());
 }
 
-rocksdb::Status Database::FindKeyRangeWithPrefix(const std::string &prefix, 
const std::string &prefix_end,
-                                                 std::string *begin, 
std::string *end,
-                                                 rocksdb::ColumnFamilyHandle 
*cf_handle) {
-  if (cf_handle == nullptr) {
-    cf_handle = metadata_cf_handle_;
-  }
-  if (prefix.empty()) {
-    return rocksdb::Status::NotFound();
-  }
-  begin->clear();
-  end->clear();
-
-  LatestSnapShot ss(storage_);
-  rocksdb::ReadOptions read_options = storage_->DefaultScanOptions();
-  read_options.snapshot = ss.GetSnapShot();
-  auto iter = util::UniqueIterator(storage_, read_options, cf_handle);
-  iter->Seek(prefix);
-  if (!iter->Valid() || !iter->key().starts_with(prefix)) {
-    return rocksdb::Status::NotFound();
-  }
-  *begin = iter->key().ToString();
-
-  // it's ok to increase the last char in prefix as the boundary of the prefix
-  // while we limit the namespace last char shouldn't be larger than 128.
-  std::string next_prefix;
-  if (!prefix_end.empty()) {
-    next_prefix = prefix_end;
-  } else {
-    next_prefix = prefix;
-    char last_char = next_prefix.back();
-    last_char++;
-    next_prefix.pop_back();
-    next_prefix.push_back(last_char);
-  }
-  iter->SeekForPrev(next_prefix);
-  int max_prev_limit = 128;  // prevent unpredicted long while loop
-  int i = 0;
-  // reversed seek the key til with prefix or end of the iterator
-  while (i++ < max_prev_limit && iter->Valid() && 
!iter->key().starts_with(prefix)) {
-    iter->Prev();
-  }
-  if (!iter->Valid() || !iter->key().starts_with(prefix)) {
-    return rocksdb::Status::NotFound();
-  }
-  *end = iter->key().ToString();
-  return rocksdb::Status::OK();
-}
-
 rocksdb::Status Database::ClearKeysOfSlot(const rocksdb::Slice &ns, int slot) {
   if (!storage_->IsSlotIdEncoded()) {
     return rocksdb::Status::Aborted("It is not in cluster mode");
diff --git a/src/storage/redis_db.h b/src/storage/redis_db.h
index 84579b10..12d9896b 100644
--- a/src/storage/redis_db.h
+++ b/src/storage/redis_db.h
@@ -134,9 +134,6 @@ class Database {
                                      RedisType type = kRedisNone);
   [[nodiscard]] rocksdb::Status RandomKey(const std::string &cursor, 
std::string *key);
   std::string AppendNamespacePrefix(const Slice &user_key);
-  [[nodiscard]] rocksdb::Status FindKeyRangeWithPrefix(const std::string 
&prefix, const std::string &prefix_end,
-                                                       std::string *begin, 
std::string *end,
-                                                       
rocksdb::ColumnFamilyHandle *cf_handle = nullptr);
   [[nodiscard]] rocksdb::Status ClearKeysOfSlot(const rocksdb::Slice &ns, int 
slot);
   [[nodiscard]] rocksdb::Status KeyExist(const std::string &key);
 
diff --git a/src/storage/storage.cc b/src/storage/storage.cc
index a25eb9c7..bbba44ce 100644
--- a/src/storage/storage.cc
+++ b/src/storage/storage.cc
@@ -677,20 +677,19 @@ rocksdb::Status Storage::Delete(const 
rocksdb::WriteOptions &options, rocksdb::C
   return Write(options, batch->GetWriteBatch());
 }
 
-rocksdb::Status Storage::DeleteRange(const std::string &first_key, const 
std::string &last_key) {
+rocksdb::Status Storage::DeleteRange(const rocksdb::WriteOptions &options, 
rocksdb::ColumnFamilyHandle *cf_handle,
+                                     Slice begin, Slice end) {
   auto batch = GetWriteBatchBase();
-  rocksdb::ColumnFamilyHandle *cf_handle = 
GetCFHandle(ColumnFamilyID::Metadata);
-  auto s = batch->DeleteRange(cf_handle, first_key, last_key);
+  auto s = batch->DeleteRange(cf_handle, begin, end);
   if (!s.ok()) {
     return s;
   }
 
-  s = batch->Delete(cf_handle, last_key);
-  if (!s.ok()) {
-    return s;
-  }
+  return Write(options, batch->GetWriteBatch());
+}
 
-  return Write(default_write_opts_, batch->GetWriteBatch());
+rocksdb::Status Storage::DeleteRange(Slice begin, Slice end) {
+  return DeleteRange(default_write_opts_, 
GetCFHandle(ColumnFamilyID::Metadata), begin, end);
 }
 
 rocksdb::Status Storage::FlushScripts(const rocksdb::WriteOptions &options, 
rocksdb::ColumnFamilyHandle *cf_handle) {
@@ -762,8 +761,8 @@ uint64_t Storage::GetTotalSize(const std::string &ns) {
     return sst_file_manager_->GetTotalSize();
   }
 
-  std::string begin_key, end_key;
-  std::string prefix = ComposeNamespaceKey(ns, "", false);
+  auto begin_key = ComposeNamespaceKey(ns, "", false);
+  auto end_key = util::StringNext(begin_key);
 
   redis::Database db(this, ns);
   uint64_t size = 0, total_size = 0;
@@ -775,9 +774,6 @@ uint64_t Storage::GetTotalSize(const std::string &ns) {
       continue;
     }
 
-    auto s = db.FindKeyRangeWithPrefix(prefix, std::string(), &begin_key, 
&end_key, cf_handle);
-    if (!s.ok()) continue;
-
     rocksdb::Range r(begin_key, end_key);
     db_->GetApproximateSizes(cf_handle, &r, 1, &size, include_both);
     total_size += size;
diff --git a/src/storage/storage.h b/src/storage/storage.h
index 579ccb72..7f31fc45 100644
--- a/src/storage/storage.h
+++ b/src/storage/storage.h
@@ -240,7 +240,9 @@ class Storage {
   rocksdb::ReadOptions DefaultMultiGetOptions() const;
   [[nodiscard]] rocksdb::Status Delete(const rocksdb::WriteOptions &options, 
rocksdb::ColumnFamilyHandle *cf_handle,
                                        const rocksdb::Slice &key);
-  [[nodiscard]] rocksdb::Status DeleteRange(const std::string &first_key, 
const std::string &last_key);
+  [[nodiscard]] rocksdb::Status DeleteRange(const rocksdb::WriteOptions 
&options,
+                                            rocksdb::ColumnFamilyHandle 
*cf_handle, Slice begin, Slice end);
+  [[nodiscard]] rocksdb::Status DeleteRange(Slice begin, Slice end);
   [[nodiscard]] rocksdb::Status FlushScripts(const rocksdb::WriteOptions 
&options,
                                              rocksdb::ColumnFamilyHandle 
*cf_handle);
   bool WALHasNewData(rocksdb::SequenceNumber seq) { return seq <= 
LatestSeqNumber(); }

Reply via email to