Skip to content

Commit

Permalink
add scan substring,suffix
Browse files Browse the repository at this point in the history
  • Loading branch information
root authored and root committed Apr 4, 2024
1 parent a59eac9 commit f8d7f35
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/commands/cmd_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ class CommandScan : public CommandScanBase {

std::vector<std::string> keys;
std::string end_key;
auto s = redis_db.Scan(key_name, limit_, prefix_, &keys, &end_key);
auto s = redis_db.Scan(key_name, limit_, prefix_, &keys, &end_key,pm_);
if (!s.ok()) {
return {Status::RedisExecErr, s.ToString()};
}
Expand Down
18 changes: 15 additions & 3 deletions src/commands/scan_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,23 @@ class CommandScanBase : public Commander {
Status ParseMatchAndCountParam(const std::string &type, std::string value) {
if (type == "match") {
prefix_ = std::move(value);
if (!prefix_.empty() && prefix_[prefix_.size() - 1] == '*') {
prefix_ = prefix_.substr(0, prefix_.size() - 1);
if (!prefix_.empty() && (prefix_[prefix_.size() - 1] == '*' || prefix_[0] == '*')) {
if(prefix_.size()>=2&&prefix_[prefix_.size() - 1] == '*' && prefix_[0] == '*'){
prefix_ = prefix_.substr(1, prefix_.size() - 2);
pm_ = 2;
}
else if (prefix_[prefix_.size() - 1] == '*') {
prefix_ = prefix_.substr(0, prefix_.size() - 1);
pm_ = 0;
}
else if (prefix_[0] == '*') {
prefix_ = prefix_.substr(1, prefix_.size() - 1);
pm_ = 1;
}
return Status::OK();
}

return {Status::RedisParseErr, "only keys prefix match was supported"};
return {Status::RedisParseErr, "It only supports matching three types: string prefix, string suffix, and substring. "};
} else if (type == "count") {
auto parse_result = ParseInt<int>(value, 10);
if (!parse_result) {
Expand Down Expand Up @@ -83,6 +94,7 @@ class CommandScanBase : public Commander {
std::string cursor_;
std::string prefix_;
int limit_ = 20;
int pm_ = 0;
};

class CommandSubkeyScanBase : public CommandScanBase {
Expand Down
30 changes: 16 additions & 14 deletions src/storage/redis_db.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "redis_db.h"

#include <cassert>
#include <ctime>
#include <map>
#include <utility>
Expand All @@ -29,6 +30,7 @@
#include "db_util.h"
#include "parse_util.h"
#include "rocksdb/iterator.h"
#include "rocksdb/slice.h"
#include "rocksdb/status.h"
#include "server/server.h"
#include "storage/iterator.h"
Expand Down Expand Up @@ -322,8 +324,8 @@ rocksdb::Status Database::Keys(const std::string &prefix, std::vector<std::strin
return rocksdb::Status::OK();
}

rocksdb::Status Database::Scan(const std::string &cursor, uint64_t limit, const std::string &prefix,
std::vector<std::string> *keys, std::string *end_cursor) {
rocksdb::Status Database::Scan(const std::string &cursor, uint64_t limit, const std::string &fix,
std::vector<std::string> *keys, std::string *end_cursor,const int pm) {
end_cursor->clear();
uint64_t cnt = 0;
uint16_t slot_start = 0;
Expand All @@ -336,15 +338,12 @@ rocksdb::Status Database::Scan(const std::string &cursor, uint64_t limit, const
auto iter = util::UniqueIterator(storage_, read_options, metadata_cf_handle_);

std::string ns_cursor = AppendNamespacePrefix(cursor);
ns_prefix = ComposeNamespaceKey(namespace_, "", false);
if (storage_->IsSlotIdEncoded()) {
slot_start = cursor.empty() ? 0 : GetSlotIdFromKey(cursor);
ns_prefix = ComposeNamespaceKey(namespace_, "", false);
if (!prefix.empty()) {
if (!fix.empty()) {
PutFixed16(&ns_prefix, slot_start);
ns_prefix.append(prefix);
}
} else {
ns_prefix = AppendNamespacePrefix(prefix);
}

if (!cursor.empty()) {
Expand All @@ -361,8 +360,13 @@ rocksdb::Status Database::Scan(const std::string &cursor, uint64_t limit, const
uint16_t slot_id = slot_start;
while (true) {
for (; iter->Valid() && cnt < limit; iter->Next()) {
if (!ns_prefix.empty() && !iter->key().starts_with(ns_prefix)) {
break;
if (!ns_prefix.empty()) {
if(!iter->key().starts_with(ns_prefix))break;
auto key_view = iter->key().ToStringView();
auto sub_key_view = static_cast<Slice>(key_view.substr(ns_prefix.size(),key_view.size()-ns_prefix.size()));
if(pm==0&&!sub_key_view.starts_with(fix))continue;
else if(pm==1&&!sub_key_view.ends_with(fix))continue;
else if(pm==2&&sub_key_view.ToStringView().find(fix)==std::string::npos)continue;
}
Metadata metadata(kRedisNone, false);
auto s = metadata.Decode(iter->value());
Expand All @@ -373,7 +377,7 @@ rocksdb::Status Database::Scan(const std::string &cursor, uint64_t limit, const
keys->emplace_back(user_key);
cnt++;
}
if (!storage_->IsSlotIdEncoded() || prefix.empty()) {
if (!storage_->IsSlotIdEncoded() || fix.empty()) {
if (!keys->empty() && cnt >= limit) {
end_cursor->append(user_key);
}
Expand All @@ -393,22 +397,20 @@ rocksdb::Status Database::Scan(const std::string &cursor, uint64_t limit, const
if (keys->empty()) {
if (iter->Valid()) {
std::tie(std::ignore, user_key) = ExtractNamespaceKey<std::string>(iter->key(), storage_->IsSlotIdEncoded());
auto res = std::mismatch(prefix.begin(), prefix.end(), user_key.begin());
if (res.first == prefix.end()) {
auto res = std::mismatch(fix.begin(), fix.end(), user_key.begin());
if (res.first == fix.end()) {
keys->emplace_back(user_key);
}

end_cursor->append(user_key);
}
} else {
end_cursor->append(user_key);
}
break;
}

ns_prefix = ComposeNamespaceKey(namespace_, "", false);
PutFixed16(&ns_prefix, slot_id);
ns_prefix.append(prefix);
iter->Seek(ns_prefix);
}
return rocksdb::Status::OK();
Expand Down
2 changes: 1 addition & 1 deletion src/storage/redis_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class Database {
[[nodiscard]] rocksdb::Status Keys(const std::string &prefix, std::vector<std::string> *keys = nullptr,
KeyNumStats *stats = nullptr);
[[nodiscard]] rocksdb::Status Scan(const std::string &cursor, uint64_t limit, const std::string &prefix,
std::vector<std::string> *keys, std::string *end_cursor = nullptr);
std::vector<std::string> *keys, std::string *end_cursor = nullptr,int pm = 0);
[[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,
Expand Down

0 comments on commit f8d7f35

Please sign in to comment.