Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dynamic key range generator with multiple range output #1541

Merged
merged 3 commits into from
Jul 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions src/commands/commander.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ struct CommandKeyRange {

using CommandKeyRangeGen = std::function<CommandKeyRange(const std::vector<std::string> &)>;

using CommandKeyRangeVecGen = std::function<std::vector<CommandKeyRange>(const std::vector<std::string> &)>;

struct CommandAttributes {
std::string name;

Expand All @@ -129,6 +131,9 @@ struct CommandAttributes {
// if key_range.first_key == -1, key_range_gen is used instead
CommandKeyRangeGen key_range_gen;

// if key_range.first_key == -2, key_range_vec_gen is used instead
CommandKeyRangeVecGen key_range_vec_gen;

CommanderFactory factory;

bool IsWrite() const { return (flags & kCmdWrite) != 0; }
Expand Down Expand Up @@ -186,6 +191,7 @@ auto MakeCmdAttr(const std::string &name, int arity, const std::string &descript
ParseCommandFlags(description, name),
{first_key, last_key, key_step},
{},
{},
[]() -> std::unique_ptr<Commander> { return std::unique_ptr<Commander>(new T()); }};

if ((first_key > 0 && key_step <= 0) || (first_key > 0 && last_key >= 0 && last_key < first_key)) {
Expand All @@ -198,13 +204,23 @@ auto MakeCmdAttr(const std::string &name, int arity, const std::string &descript

template <typename T>
auto MakeCmdAttr(const std::string &name, int arity, const std::string &description, const CommandKeyRangeGen &gen) {
CommandAttributes attr{name,
arity,
description,
ParseCommandFlags(description, name),
{-1, 0, 0},
gen,
[]() -> std::unique_ptr<Commander> { return std::unique_ptr<Commander>(new T()); }};
CommandAttributes attr{
name, arity,
description, ParseCommandFlags(description, name),
{-1, 0, 0}, gen,
{}, []() -> std::unique_ptr<Commander> { return std::unique_ptr<Commander>(new T()); }};

return attr;
}

template <typename T>
auto MakeCmdAttr(const std::string &name, int arity, const std::string &description,
const CommandKeyRangeVecGen &vec_gen) {
CommandAttributes attr{
name, arity,
description, ParseCommandFlags(description, name),
{-2, 0, 0}, {},
vec_gen, []() -> std::unique_ptr<Commander> { return std::unique_ptr<Commander>(new T()); }};

return attr;
}
Expand Down
11 changes: 10 additions & 1 deletion src/server/server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1683,12 +1683,21 @@ void Server::UpdateWatchedKeysFromArgs(const std::vector<std::string> &args, con
if (attr.IsWrite() && watched_key_size_ > 0) {
if (attr.key_range.first_key > 0) {
updateWatchedKeysFromRange(args, attr.key_range);
} else if (attr.key_range.first_key < 0) {
} else if (attr.key_range.first_key == -1) {
redis::CommandKeyRange range = attr.key_range_gen(args);

if (range.first_key > 0) {
updateWatchedKeysFromRange(args, range);
}
} else if (attr.key_range.first_key == -2) {
std::vector<redis::CommandKeyRange> vec_range = attr.key_range_vec_gen(args);

for (const auto &range : vec_range) {
if (range.first_key > 0) {
updateWatchedKeysFromRange(args, range);
}
}

} else {
// support commands like flushdb (write flag && key range {0,0,0})
updateAllWatchedKeys();
Expand Down