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(); }