diff --git a/src/commands/cmd_bit.cc b/src/commands/cmd_bit.cc index 541bc38f691..42447d2f691 100644 --- a/src/commands/cmd_bit.cc +++ b/src/commands/cmd_bit.cc @@ -404,7 +404,7 @@ class CommandBitfield : public Commander { bool read_only_; }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("getbit", 3, "read-only", 1, 1, 1), +REDIS_REGISTER_COMMANDS(Bit, MakeCmdAttr("getbit", 3, "read-only", 1, 1, 1), MakeCmdAttr("setbit", 4, "write", 1, 1, 1), MakeCmdAttr("bitcount", -2, "read-only", 1, 1, 1), MakeCmdAttr("bitpos", -3, "read-only", 1, 1, 1), diff --git a/src/commands/cmd_bloom_filter.cc b/src/commands/cmd_bloom_filter.cc index bb2df94e2f5..8f2963755a4 100644 --- a/src/commands/cmd_bloom_filter.cc +++ b/src/commands/cmd_bloom_filter.cc @@ -387,7 +387,7 @@ class CommandBFCard : public Commander { } }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("bf.reserve", -4, "write", 1, 1, 1), +REDIS_REGISTER_COMMANDS(BloomFilter, MakeCmdAttr("bf.reserve", -4, "write", 1, 1, 1), MakeCmdAttr("bf.add", 3, "write", 1, 1, 1), MakeCmdAttr("bf.madd", -3, "write", 1, 1, 1), MakeCmdAttr("bf.insert", -4, "write", 1, 1, 1), diff --git a/src/commands/cmd_cluster.cc b/src/commands/cmd_cluster.cc index a043b6d4f82..958e261d97a 100644 --- a/src/commands/cmd_cluster.cc +++ b/src/commands/cmd_cluster.cc @@ -354,7 +354,8 @@ class CommandAsking : public Commander { } }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("cluster", -2, "cluster no-script", 0, 0, 0, GenerateClusterFlag), +REDIS_REGISTER_COMMANDS(Cluster, + MakeCmdAttr("cluster", -2, "cluster no-script", 0, 0, 0, GenerateClusterFlag), MakeCmdAttr("clusterx", -2, "cluster no-script", 0, 0, 0, GenerateClusterFlag), MakeCmdAttr("readonly", 1, "cluster no-multi", 0, 0, 0), MakeCmdAttr("readwrite", 1, "cluster no-multi", 0, 0, 0), diff --git a/src/commands/cmd_function.cc b/src/commands/cmd_function.cc index 1afab33d61e..7d831f80845 100644 --- a/src/commands/cmd_function.cc +++ b/src/commands/cmd_function.cc @@ -107,10 +107,9 @@ uint64_t GenerateFunctionFlags(uint64_t flags, const std::vector &a return flags; } -REDIS_REGISTER_COMMANDS(MakeCmdAttr("function", -2, "exclusive no-script", 0, 0, 0, - GenerateFunctionFlags), - MakeCmdAttr>("fcall", -3, "exclusive write no-script", GetScriptEvalKeyRange), - MakeCmdAttr>("fcall_ro", -3, "read-only ro-script no-script", - GetScriptEvalKeyRange)); +REDIS_REGISTER_COMMANDS( + Function, MakeCmdAttr("function", -2, "exclusive no-script", 0, 0, 0, GenerateFunctionFlags), + MakeCmdAttr>("fcall", -3, "exclusive write no-script", GetScriptEvalKeyRange), + MakeCmdAttr>("fcall_ro", -3, "read-only ro-script no-script", GetScriptEvalKeyRange)); } // namespace redis diff --git a/src/commands/cmd_geo.cc b/src/commands/cmd_geo.cc index 3ed2237d8a8..a95bd927cb7 100644 --- a/src/commands/cmd_geo.cc +++ b/src/commands/cmd_geo.cc @@ -700,7 +700,7 @@ class CommandGeoRadiusByMemberReadonly : public CommandGeoRadiusByMember { CommandGeoRadiusByMemberReadonly() = default; }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("geoadd", -5, "write", 1, 1, 1), +REDIS_REGISTER_COMMANDS(Geo, MakeCmdAttr("geoadd", -5, "write", 1, 1, 1), MakeCmdAttr("geodist", -4, "read-only", 1, 1, 1), MakeCmdAttr("geohash", -3, "read-only", 1, 1, 1), MakeCmdAttr("geopos", -3, "read-only", 1, 1, 1), diff --git a/src/commands/cmd_hash.cc b/src/commands/cmd_hash.cc index 677f131eb98..d21e4544e22 100644 --- a/src/commands/cmd_hash.cc +++ b/src/commands/cmd_hash.cc @@ -429,7 +429,7 @@ class CommandHRandField : public Commander { bool no_parameters_ = true; }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("hget", 3, "read-only", 1, 1, 1), +REDIS_REGISTER_COMMANDS(Hash, MakeCmdAttr("hget", 3, "read-only", 1, 1, 1), MakeCmdAttr("hincrby", 4, "write", 1, 1, 1), MakeCmdAttr("hincrbyfloat", 4, "write", 1, 1, 1), MakeCmdAttr("hset", -4, "write", 1, 1, 1), diff --git a/src/commands/cmd_hll.cc b/src/commands/cmd_hll.cc index 6cde3e61b71..d464e131a11 100644 --- a/src/commands/cmd_hll.cc +++ b/src/commands/cmd_hll.cc @@ -95,7 +95,7 @@ class CommandPfMerge final : public Commander { } }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("pfadd", -2, "write", 1, 1, 1), +REDIS_REGISTER_COMMANDS(HLL, MakeCmdAttr("pfadd", -2, "write", 1, 1, 1), MakeCmdAttr("pfcount", -2, "read-only", 1, -1, 1), MakeCmdAttr("pfmerge", -2, "write", 1, -1, 1), ); diff --git a/src/commands/cmd_json.cc b/src/commands/cmd_json.cc index cb84aa9d7a6..c861bf60964 100644 --- a/src/commands/cmd_json.cc +++ b/src/commands/cmd_json.cc @@ -705,7 +705,7 @@ class CommandJsonResp : public Commander { } }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("json.set", 4, "write", 1, 1, 1), +REDIS_REGISTER_COMMANDS(JSON, MakeCmdAttr("json.set", 4, "write", 1, 1, 1), MakeCmdAttr("json.get", -2, "read-only", 1, 1, 1), MakeCmdAttr("json.info", 2, "read-only", 1, 1, 1), MakeCmdAttr("json.type", -2, "read-only", 1, 1, 1), diff --git a/src/commands/cmd_key.cc b/src/commands/cmd_key.cc index d7219841a80..b3095f42cd8 100644 --- a/src/commands/cmd_key.cc +++ b/src/commands/cmd_key.cc @@ -534,7 +534,7 @@ class CommandSort : public Commander { SortArgument sort_argument_; }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("ttl", 2, "read-only", 1, 1, 1), +REDIS_REGISTER_COMMANDS(Key, MakeCmdAttr("ttl", 2, "read-only", 1, 1, 1), MakeCmdAttr("pttl", 2, "read-only", 1, 1, 1), MakeCmdAttr("type", 2, "read-only", 1, 1, 1), MakeCmdAttr("move", 3, "write", 1, 1, 1), diff --git a/src/commands/cmd_list.cc b/src/commands/cmd_list.cc index e9e17266625..66d3089a753 100644 --- a/src/commands/cmd_list.cc +++ b/src/commands/cmd_list.cc @@ -848,7 +848,7 @@ class CommandLPos : public Commander { PosSpec spec_; }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("blpop", -3, "write no-script", 1, -2, 1), +REDIS_REGISTER_COMMANDS(List, MakeCmdAttr("blpop", -3, "write no-script", 1, -2, 1), MakeCmdAttr("brpop", -3, "write no-script", 1, -2, 1), MakeCmdAttr("blmpop", -5, "write no-script", CommandBLMPop::keyRangeGen), MakeCmdAttr("lindex", 3, "read-only", 1, 1, 1), diff --git a/src/commands/cmd_pubsub.cc b/src/commands/cmd_pubsub.cc index 6923fb89fd0..143cfcdeb68 100644 --- a/src/commands/cmd_pubsub.cc +++ b/src/commands/cmd_pubsub.cc @@ -248,7 +248,7 @@ class CommandPubSub : public Commander { }; REDIS_REGISTER_COMMANDS( - MakeCmdAttr("publish", 3, "read-only pub-sub", 0, 0, 0), + Pubsub, MakeCmdAttr("publish", 3, "read-only pub-sub", 0, 0, 0), MakeCmdAttr("mpublish", -3, "read-only pub-sub", 0, 0, 0), MakeCmdAttr("subscribe", -2, "read-only pub-sub no-multi no-script", 0, 0, 0), MakeCmdAttr("unsubscribe", -1, "read-only pub-sub no-multi no-script", 0, 0, 0), diff --git a/src/commands/cmd_replication.cc b/src/commands/cmd_replication.cc index d3f3c0f25c5..91fdcae9d8e 100644 --- a/src/commands/cmd_replication.cc +++ b/src/commands/cmd_replication.cc @@ -340,12 +340,11 @@ class CommandDBName : public Commander { } }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("replconf", -3, "read-only replication no-script", 0, 0, 0), - MakeCmdAttr("psync", -2, "read-only replication no-multi no-script", 0, 0, 0), - MakeCmdAttr("_fetch_meta", 1, "read-only replication no-multi no-script", 0, - 0, 0), - MakeCmdAttr("_fetch_file", 2, "read-only replication no-multi no-script", 0, - 0, 0), - MakeCmdAttr("_db_name", 1, "read-only replication no-multi", 0, 0, 0), ) +REDIS_REGISTER_COMMANDS( + Replication, MakeCmdAttr("replconf", -3, "read-only replication no-script", 0, 0, 0), + MakeCmdAttr("psync", -2, "read-only replication no-multi no-script", 0, 0, 0), + MakeCmdAttr("_fetch_meta", 1, "read-only replication no-multi no-script", 0, 0, 0), + MakeCmdAttr("_fetch_file", 2, "read-only replication no-multi no-script", 0, 0, 0), + MakeCmdAttr("_db_name", 1, "read-only replication no-multi", 0, 0, 0), ) } // namespace redis diff --git a/src/commands/cmd_script.cc b/src/commands/cmd_script.cc index 2547c289fcf..71bd32cf81c 100644 --- a/src/commands/cmd_script.cc +++ b/src/commands/cmd_script.cc @@ -123,12 +123,11 @@ uint64_t GenerateScriptFlags(uint64_t flags, const std::vector &arg return flags; } -REDIS_REGISTER_COMMANDS(MakeCmdAttr("eval", -3, "exclusive write no-script", GetScriptEvalKeyRange), - MakeCmdAttr("evalsha", -3, "exclusive write no-script", GetScriptEvalKeyRange), - MakeCmdAttr("eval_ro", -3, "read-only no-script ro-script", - GetScriptEvalKeyRange), - MakeCmdAttr("evalsha_ro", -3, "read-only no-script ro-script", - GetScriptEvalKeyRange), - MakeCmdAttr("script", -2, "exclusive no-script", 0, 0, 0), ) +REDIS_REGISTER_COMMANDS( + Script, MakeCmdAttr("eval", -3, "exclusive write no-script", GetScriptEvalKeyRange), + MakeCmdAttr("evalsha", -3, "exclusive write no-script", GetScriptEvalKeyRange), + MakeCmdAttr("eval_ro", -3, "read-only no-script ro-script", GetScriptEvalKeyRange), + MakeCmdAttr("evalsha_ro", -3, "read-only no-script ro-script", GetScriptEvalKeyRange), + MakeCmdAttr("script", -2, "exclusive no-script", 0, 0, 0), ) } // namespace redis diff --git a/src/commands/cmd_search.cc b/src/commands/cmd_search.cc index 210938f9189..615c81a6448 100644 --- a/src/commands/cmd_search.cc +++ b/src/commands/cmd_search.cc @@ -486,7 +486,8 @@ class CommandFTDrop : public Commander { }; }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("ft.create", -2, "write exclusive no-multi no-script", 0, 0, 0), +REDIS_REGISTER_COMMANDS(Search, + MakeCmdAttr("ft.create", -2, "write exclusive no-multi no-script", 0, 0, 0), MakeCmdAttr("ft.searchsql", -2, "read-only", 0, 0, 0), MakeCmdAttr("ft.search", -3, "read-only", 0, 0, 0), MakeCmdAttr("ft.explainsql", -2, "read-only", 0, 0, 0), diff --git a/src/commands/cmd_server.cc b/src/commands/cmd_server.cc index ac9179e7ab7..c9a11cf7a15 100644 --- a/src/commands/cmd_server.cc +++ b/src/commands/cmd_server.cc @@ -1320,7 +1320,7 @@ class CommandPollUpdates : public Commander { Format format_ = Format::Raw; }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("auth", 2, "read-only ok-loading", 0, 0, 0), +REDIS_REGISTER_COMMANDS(Server, MakeCmdAttr("auth", 2, "read-only ok-loading", 0, 0, 0), MakeCmdAttr("ping", -1, "read-only", 0, 0, 0), MakeCmdAttr("select", 2, "read-only", 0, 0, 0), MakeCmdAttr("info", -1, "read-only ok-loading", 0, 0, 0), diff --git a/src/commands/cmd_set.cc b/src/commands/cmd_set.cc index 213a6768279..4b01e2f487f 100644 --- a/src/commands/cmd_set.cc +++ b/src/commands/cmd_set.cc @@ -437,7 +437,7 @@ class CommandSScan : public CommandSubkeyScanBase { } }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("sadd", -3, "write", 1, 1, 1), +REDIS_REGISTER_COMMANDS(Set, MakeCmdAttr("sadd", -3, "write", 1, 1, 1), MakeCmdAttr("srem", -3, "write no-dbsize-check", 1, 1, 1), MakeCmdAttr("scard", 2, "read-only", 1, 1, 1), MakeCmdAttr("smembers", 2, "read-only", 1, 1, 1), diff --git a/src/commands/cmd_sortedint.cc b/src/commands/cmd_sortedint.cc index a97e357f154..8259808a7f3 100644 --- a/src/commands/cmd_sortedint.cc +++ b/src/commands/cmd_sortedint.cc @@ -249,7 +249,7 @@ class CommandSortedintRevRangeByValue : public CommandSortedintRangeByValue { CommandSortedintRevRangeByValue() : CommandSortedintRangeByValue(true) {} }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("siadd", -3, "write", 1, 1, 1), +REDIS_REGISTER_COMMANDS(SortedInt, MakeCmdAttr("siadd", -3, "write", 1, 1, 1), MakeCmdAttr("sirem", -3, "write no-dbsize-check", 1, 1, 1), MakeCmdAttr("sicard", 2, "read-only", 1, 1, 1), MakeCmdAttr("siexists", -3, "read-only", 1, 1, 1), diff --git a/src/commands/cmd_stream.cc b/src/commands/cmd_stream.cc index 081933a14c3..06ba424f379 100644 --- a/src/commands/cmd_stream.cc +++ b/src/commands/cmd_stream.cc @@ -1838,7 +1838,7 @@ class CommandXSetId : public Commander { std::optional entries_added_; }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("xack", -4, "write no-dbsize-check", 1, 1, 1), +REDIS_REGISTER_COMMANDS(Stream, MakeCmdAttr("xack", -4, "write no-dbsize-check", 1, 1, 1), MakeCmdAttr("xadd", -5, "write", 1, 1, 1), MakeCmdAttr("xdel", -3, "write no-dbsize-check", 1, 1, 1), MakeCmdAttr("xclaim", -6, "write", 1, 1, 1), diff --git a/src/commands/cmd_string.cc b/src/commands/cmd_string.cc index 2cfa2d86e8f..be864f507c1 100644 --- a/src/commands/cmd_string.cc +++ b/src/commands/cmd_string.cc @@ -689,7 +689,8 @@ class CommandLCS : public Commander { }; REDIS_REGISTER_COMMANDS( - MakeCmdAttr("get", 2, "read-only", 1, 1, 1), MakeCmdAttr("getex", -2, "write", 1, 1, 1), + String, MakeCmdAttr("get", 2, "read-only", 1, 1, 1), + MakeCmdAttr("getex", -2, "write", 1, 1, 1), MakeCmdAttr("strlen", 2, "read-only", 1, 1, 1), MakeCmdAttr("getset", 3, "write", 1, 1, 1), MakeCmdAttr("getrange", 4, "read-only", 1, 1, 1), diff --git a/src/commands/cmd_txn.cc b/src/commands/cmd_txn.cc index 130533fbc9b..3e2495d2e6f 100644 --- a/src/commands/cmd_txn.cc +++ b/src/commands/cmd_txn.cc @@ -118,7 +118,7 @@ class CommandUnwatch : public Commander { } }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("multi", 1, "multi", 0, 0, 0), +REDIS_REGISTER_COMMANDS(Txn, MakeCmdAttr("multi", 1, "multi", 0, 0, 0), MakeCmdAttr("discard", 1, "multi", 0, 0, 0), MakeCmdAttr("exec", 1, "exclusive multi", 0, 0, 0), MakeCmdAttr("watch", -2, "multi", 1, -1, 1), diff --git a/src/commands/cmd_zset.cc b/src/commands/cmd_zset.cc index 715747ab8a4..327e06dc143 100644 --- a/src/commands/cmd_zset.cc +++ b/src/commands/cmd_zset.cc @@ -1512,7 +1512,7 @@ class CommandZDiffStore : public Commander { std::vector keys_; }; -REDIS_REGISTER_COMMANDS(MakeCmdAttr("zadd", -4, "write", 1, 1, 1), +REDIS_REGISTER_COMMANDS(ZSet, MakeCmdAttr("zadd", -4, "write", 1, 1, 1), MakeCmdAttr("zcard", 2, "read-only", 1, 1, 1), MakeCmdAttr("zcount", 4, "read-only", 1, 1, 1), MakeCmdAttr("zincrby", 4, "write", 1, 1, 1), diff --git a/src/commands/commander.cc b/src/commands/commander.cc index 54fe1aeacf5..d9c68d2d810 100644 --- a/src/commands/commander.cc +++ b/src/commands/commander.cc @@ -24,8 +24,10 @@ namespace redis { -RegisterToCommandTable::RegisterToCommandTable(std::initializer_list list) { - for (const auto &attr : list) { +RegisterToCommandTable::RegisterToCommandTable(CommandCategory category, + std::initializer_list list) { + for (auto attr : list) { + attr.category = category; CommandTable::redis_command_table.emplace_back(attr); CommandTable::original_commands[attr.name] = &CommandTable::redis_command_table.back(); CommandTable::commands[attr.name] = &CommandTable::redis_command_table.back(); diff --git a/src/commands/commander.h b/src/commands/commander.h index 1441581d36a..24a86113c62 100644 --- a/src/commands/commander.h +++ b/src/commands/commander.h @@ -67,6 +67,31 @@ enum CommandFlags : uint64_t { kCmdNoDBSizeCheck = 1ULL << 12, // "no-dbsize-check" flag }; +enum class CommandCategory : uint8_t { + Unknown = 0, + Bit, + BloomFilter, + Cluster, + Function, + Geo, + Hash, + HLL, + JSON, + Key, + List, + Pubsub, + Replication, + Script, + Search, + Server, + Set, + SortedInt, + Stream, + String, + Txn, + ZSet, +}; + class Commander { public: void SetAttributes(const CommandAttributes *attributes) { attributes_ = attributes; } @@ -130,8 +155,8 @@ struct CommandAttributes { // negative number -n means number of arguments is equal to or large than n int arity; - // space-separated flag strings to initialize flags - std::string description; + // category of this command, e.g. key, string, hash + CommandCategory category; // bitmap of enum CommandFlags uint64_t flags; @@ -226,10 +251,10 @@ inline uint64_t ParseCommandFlags(const std::string &description, const std::str template auto MakeCmdAttr(const std::string &name, int arity, const std::string &description, int first_key, int last_key, - int key_step, const AdditionalFlagGen &flag_gen = {}) { + int key_step = 1, const AdditionalFlagGen &flag_gen = {}) { CommandAttributes attr{name, arity, - description, + CommandCategory::Unknown, ParseCommandFlags(description, name), flag_gen, {first_key, last_key, key_step}, @@ -250,7 +275,7 @@ auto MakeCmdAttr(const std::string &name, int arity, const std::string &descript const AdditionalFlagGen &flag_gen = {}) { CommandAttributes attr{name, arity, - description, + CommandCategory::Unknown, ParseCommandFlags(description, name), flag_gen, {-1, 0, 0}, @@ -266,7 +291,7 @@ auto MakeCmdAttr(const std::string &name, int arity, const std::string &descript const CommandKeyRangeVecGen &vec_gen, const AdditionalFlagGen &flag_gen = {}) { CommandAttributes attr{name, arity, - description, + CommandCategory::Unknown, ParseCommandFlags(description, name), flag_gen, {-2, 0, 0}, @@ -278,7 +303,7 @@ auto MakeCmdAttr(const std::string &name, int arity, const std::string &descript } struct RegisterToCommandTable { - RegisterToCommandTable(std::initializer_list list); + RegisterToCommandTable(CommandCategory category, std::initializer_list list); }; struct CommandTable { @@ -316,7 +341,8 @@ struct CommandTable { #define KVROCKS_CONCAT2(a, b) KVROCKS_CONCAT(a, b) // NOLINT // NOLINTNEXTLINE -#define REDIS_REGISTER_COMMANDS(...) \ - static RegisterToCommandTable KVROCKS_CONCAT2(register_to_command_table_, __LINE__){__VA_ARGS__}; +#define REDIS_REGISTER_COMMANDS(cat, ...) \ + static RegisterToCommandTable KVROCKS_CONCAT2(register_to_command_table_, __LINE__)(CommandCategory::cat, \ + {__VA_ARGS__}); } // namespace redis diff --git a/src/server/redis_connection.cc b/src/server/redis_connection.cc index bdef38165e6..2f00f7cd13e 100644 --- a/src/server/redis_connection.cc +++ b/src/server/redis_connection.cc @@ -360,8 +360,10 @@ Status Connection::ExecuteCommand(const std::string &cmd_name, const std::vector return s; } -static bool IsHashOrJsonCommand(const std::string &cmd) { - return util::HasPrefix(cmd, "h") || util::HasPrefix(cmd, "json."); +static bool IsCmdForIndexing(const CommandAttributes *attr) { + return (attr->flags & redis::kCmdWrite) && + (attr->category == CommandCategory::Hash || attr->category == CommandCategory::JSON || + attr->category == CommandCategory::Key); } void Connection::ExecuteCommands(std::deque *to_process_cmds) { @@ -492,8 +494,7 @@ void Connection::ExecuteCommands(std::deque *to_process_cmds) { // TODO: transaction support for index recording std::vector index_records; - if (!srv_->index_mgr.index_map.empty() && IsHashOrJsonCommand(cmd_name) && (attributes->flags & redis::kCmdWrite) && - !config->cluster_enabled) { + if (!srv_->index_mgr.index_map.empty() && IsCmdForIndexing(attributes) && !config->cluster_enabled) { attributes->ForEachKeyRange( [&, this](const std::vector &args, const CommandKeyRange &key_range) { key_range.ForEachKey(