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 c525d7a8 feat(cmd): avoid to use CommandAttributes::flags directly 
(#2619)
c525d7a8 is described below

commit c525d7a8c6ba19f5b7e53726319cc578767a62d9
Author: Twice <[email protected]>
AuthorDate: Thu Oct 24 17:58:16 2024 +0800

    feat(cmd): avoid to use CommandAttributes::flags directly (#2619)
---
 src/cluster/cluster.cc          |  6 ++-
 src/commands/cmd_cluster.cc     | 10 ++---
 src/commands/cmd_function.cc    |  2 +-
 src/commands/cmd_geo.cc         |  2 +-
 src/commands/cmd_pubsub.cc      | 18 ++++----
 src/commands/cmd_replication.cc | 10 ++---
 src/commands/cmd_script.cc      |  2 +-
 src/commands/cmd_search.cc      | 20 ++++-----
 src/commands/cmd_server.cc      | 74 +++++++++++++++---------------
 src/commands/cmd_stream.cc      |  6 +--
 src/commands/cmd_txn.cc         |  8 ++--
 src/commands/commander.cc       |  2 +-
 src/commands/commander.h        | 99 ++++++++++++++++++++++++++++++-----------
 src/server/redis_connection.cc  | 10 ++---
 src/server/server.cc            |  2 +-
 15 files changed, 161 insertions(+), 110 deletions(-)

diff --git a/src/cluster/cluster.cc b/src/cluster/cluster.cc
index 95b076aa..16e72b62 100644
--- a/src/cluster/cluster.cc
+++ b/src/cluster/cluster.cc
@@ -871,6 +871,8 @@ Status Cluster::CanExecByMySelf(const 
redis::CommandAttributes *attributes, cons
     cross_slot_ok = true;
   }
 
+  uint64_t flags = attributes->GenerateFlags(cmd_tokens);
+
   if (myself_ && myself_ == slots_nodes_[slot]) {
     // We use central controller to manage the topology of the cluster.
     // Server can't change the topology directly, so we record the migrated 
slots
@@ -880,7 +882,7 @@ Status Cluster::CanExecByMySelf(const 
redis::CommandAttributes *attributes, cons
     }
     // To keep data consistency, slot will be forbidden write while sending 
the last incremental data.
     // During this phase, the requests of the migrating slot has to be 
rejected.
-    if ((attributes->flags & redis::kCmdWrite) && IsWriteForbiddenSlot(slot)) {
+    if ((flags & redis::kCmdWrite) && IsWriteForbiddenSlot(slot)) {
       return {Status::RedisTryAgain, "Can't write to slot being migrated which 
is in write forbidden phase"};
     }
 
@@ -903,7 +905,7 @@ Status Cluster::CanExecByMySelf(const 
redis::CommandAttributes *attributes, cons
     return Status::OK();  // I'm serving the imported slot
   }
 
-  if (myself_ && myself_->role == kClusterSlave && !(attributes->flags & 
redis::kCmdWrite) &&
+  if (myself_ && myself_->role == kClusterSlave && !(flags & redis::kCmdWrite) 
&&
       nodes_.find(myself_->master_id) != nodes_.end() && 
nodes_[myself_->master_id] == slots_nodes_[slot] &&
       conn->IsFlagEnabled(redis::Connection::kReadOnly)) {
     return Status::OK();  // My master is serving this slot
diff --git a/src/commands/cmd_cluster.cc b/src/commands/cmd_cluster.cc
index 11f60469..ab23f86d 100644
--- a/src/commands/cmd_cluster.cc
+++ b/src/commands/cmd_cluster.cc
@@ -358,10 +358,10 @@ class CommandAsking : public Commander {
 };
 
 REDIS_REGISTER_COMMANDS(Cluster,
-                        MakeCmdAttr<CommandCluster>("cluster", -2, "cluster 
no-script", 0, 0, 0, GenerateClusterFlag),
-                        MakeCmdAttr<CommandClusterX>("clusterx", -2, "cluster 
no-script", 0, 0, 0, GenerateClusterFlag),
-                        MakeCmdAttr<CommandReadOnly>("readonly", 1, "cluster 
no-multi", 0, 0, 0),
-                        MakeCmdAttr<CommandReadWrite>("readwrite", 1, "cluster 
no-multi", 0, 0, 0),
-                        MakeCmdAttr<CommandAsking>("asking", 1, "cluster", 0, 
0, 0), )
+                        MakeCmdAttr<CommandCluster>("cluster", -2, "cluster 
no-script", NO_KEY, GenerateClusterFlag),
+                        MakeCmdAttr<CommandClusterX>("clusterx", -2, "cluster 
no-script", NO_KEY, GenerateClusterFlag),
+                        MakeCmdAttr<CommandReadOnly>("readonly", 1, "cluster 
no-multi", NO_KEY),
+                        MakeCmdAttr<CommandReadWrite>("readwrite", 1, "cluster 
no-multi", NO_KEY),
+                        MakeCmdAttr<CommandAsking>("asking", 1, "cluster", 
NO_KEY), )
 
 }  // namespace redis
diff --git a/src/commands/cmd_function.cc b/src/commands/cmd_function.cc
index 53fbc0c0..ee5a580d 100644
--- a/src/commands/cmd_function.cc
+++ b/src/commands/cmd_function.cc
@@ -110,7 +110,7 @@ uint64_t GenerateFunctionFlags(uint64_t flags, const 
std::vector<std::string> &a
 }
 
 REDIS_REGISTER_COMMANDS(
-    Function, MakeCmdAttr<CommandFunction>("function", -2, "exclusive 
no-script", 0, 0, 0, GenerateFunctionFlags),
+    Function, MakeCmdAttr<CommandFunction>("function", -2, "exclusive 
no-script", NO_KEY, GenerateFunctionFlags),
     MakeCmdAttr<CommandFCall<>>("fcall", -3, "exclusive write no-script", 
GetScriptEvalKeyRange),
     MakeCmdAttr<CommandFCall<true>>("fcall_ro", -3, "read-only ro-script 
no-script", GetScriptEvalKeyRange));
 
diff --git a/src/commands/cmd_geo.cc b/src/commands/cmd_geo.cc
index 3cf41c84..4c354611 100644
--- a/src/commands/cmd_geo.cc
+++ b/src/commands/cmd_geo.cc
@@ -278,7 +278,7 @@ class CommandGeoRadius : public CommandGeoBase {
 
         count_ = *parse_result;
         i += 2;
-      } else if ((attributes_->flags & kCmdWrite) &&
+      } else if ((attributes_->InitialFlags() & kCmdWrite) &&
                  (util::ToLower(args_[i]) == "store" || 
util::ToLower(args_[i]) == "storedist") &&
                  i + 1 < args_.size()) {
         store_key_ = args_[i + 1];
diff --git a/src/commands/cmd_pubsub.cc b/src/commands/cmd_pubsub.cc
index 346dfebd..e7e4dee7 100644
--- a/src/commands/cmd_pubsub.cc
+++ b/src/commands/cmd_pubsub.cc
@@ -253,14 +253,14 @@ class CommandPubSub : public Commander {
 };
 
 REDIS_REGISTER_COMMANDS(
-    Pubsub, MakeCmdAttr<CommandPublish>("publish", 3, "read-only pub-sub", 0, 
0, 0),
-    MakeCmdAttr<CommandMPublish>("mpublish", -3, "read-only pub-sub", 0, 0, 0),
-    MakeCmdAttr<CommandSubscribe>("subscribe", -2, "read-only pub-sub no-multi 
no-script", 0, 0, 0),
-    MakeCmdAttr<CommandUnSubscribe>("unsubscribe", -1, "read-only pub-sub 
no-multi no-script", 0, 0, 0),
-    MakeCmdAttr<CommandPSubscribe>("psubscribe", -2, "read-only pub-sub 
no-multi no-script", 0, 0, 0),
-    MakeCmdAttr<CommandPUnSubscribe>("punsubscribe", -1, "read-only pub-sub 
no-multi no-script", 0, 0, 0),
-    MakeCmdAttr<CommandSSubscribe>("ssubscribe", -2, "read-only pub-sub 
no-multi no-script", 0, 0, 0),
-    MakeCmdAttr<CommandSUnSubscribe>("sunsubscribe", -1, "read-only pub-sub 
no-multi no-script", 0, 0, 0),
-    MakeCmdAttr<CommandPubSub>("pubsub", -2, "read-only pub-sub no-script", 0, 
0, 0), )
+    Pubsub, MakeCmdAttr<CommandPublish>("publish", 3, "read-only pub-sub", 
NO_KEY),
+    MakeCmdAttr<CommandMPublish>("mpublish", -3, "read-only pub-sub", NO_KEY),
+    MakeCmdAttr<CommandSubscribe>("subscribe", -2, "read-only pub-sub no-multi 
no-script", NO_KEY),
+    MakeCmdAttr<CommandUnSubscribe>("unsubscribe", -1, "read-only pub-sub 
no-multi no-script", NO_KEY),
+    MakeCmdAttr<CommandPSubscribe>("psubscribe", -2, "read-only pub-sub 
no-multi no-script", NO_KEY),
+    MakeCmdAttr<CommandPUnSubscribe>("punsubscribe", -1, "read-only pub-sub 
no-multi no-script", NO_KEY),
+    MakeCmdAttr<CommandSSubscribe>("ssubscribe", -2, "read-only pub-sub 
no-multi no-script", NO_KEY),
+    MakeCmdAttr<CommandSUnSubscribe>("sunsubscribe", -1, "read-only pub-sub 
no-multi no-script", NO_KEY),
+    MakeCmdAttr<CommandPubSub>("pubsub", -2, "read-only pub-sub no-script", 
NO_KEY), )
 
 }  // namespace redis
diff --git a/src/commands/cmd_replication.cc b/src/commands/cmd_replication.cc
index 387b2127..71fd7fb6 100644
--- a/src/commands/cmd_replication.cc
+++ b/src/commands/cmd_replication.cc
@@ -345,10 +345,10 @@ class CommandDBName : public Commander {
 };
 
 REDIS_REGISTER_COMMANDS(
-    Replication, MakeCmdAttr<CommandReplConf>("replconf", -3, "read-only 
replication no-script", 0, 0, 0),
-    MakeCmdAttr<CommandPSync>("psync", -2, "read-only replication no-multi 
no-script", 0, 0, 0),
-    MakeCmdAttr<CommandFetchMeta>("_fetch_meta", 1, "read-only replication 
no-multi no-script", 0, 0, 0),
-    MakeCmdAttr<CommandFetchFile>("_fetch_file", 2, "read-only replication 
no-multi no-script", 0, 0, 0),
-    MakeCmdAttr<CommandDBName>("_db_name", 1, "read-only replication 
no-multi", 0, 0, 0), )
+    Replication, MakeCmdAttr<CommandReplConf>("replconf", -3, "read-only 
replication no-script", NO_KEY),
+    MakeCmdAttr<CommandPSync>("psync", -2, "read-only replication no-multi 
no-script", NO_KEY),
+    MakeCmdAttr<CommandFetchMeta>("_fetch_meta", 1, "read-only replication 
no-multi no-script", NO_KEY),
+    MakeCmdAttr<CommandFetchFile>("_fetch_file", 2, "read-only replication 
no-multi no-script", NO_KEY),
+    MakeCmdAttr<CommandDBName>("_db_name", 1, "read-only replication 
no-multi", NO_KEY), )
 
 }  // namespace redis
diff --git a/src/commands/cmd_script.cc b/src/commands/cmd_script.cc
index 1eb85705..40c19a17 100644
--- a/src/commands/cmd_script.cc
+++ b/src/commands/cmd_script.cc
@@ -130,6 +130,6 @@ REDIS_REGISTER_COMMANDS(
     MakeCmdAttr<CommandEvalSHA>("evalsha", -3, "exclusive write no-script", 
GetScriptEvalKeyRange),
     MakeCmdAttr<CommandEvalRO>("eval_ro", -3, "read-only no-script ro-script", 
GetScriptEvalKeyRange),
     MakeCmdAttr<CommandEvalSHARO>("evalsha_ro", -3, "read-only no-script 
ro-script", GetScriptEvalKeyRange),
-    MakeCmdAttr<CommandScript>("script", -2, "exclusive no-script", 0, 0, 0), )
+    MakeCmdAttr<CommandScript>("script", -2, "exclusive no-script", NO_KEY), )
 
 }  // namespace redis
diff --git a/src/commands/cmd_search.cc b/src/commands/cmd_search.cc
index 5d9e220e..f6d5ab05 100644
--- a/src/commands/cmd_search.cc
+++ b/src/commands/cmd_search.cc
@@ -509,15 +509,15 @@ class CommandFTTagVals : public Commander {
 };
 
 REDIS_REGISTER_COMMANDS(Search,
-                        MakeCmdAttr<CommandFTCreate>("ft.create", -2, "write 
exclusive no-multi no-script slow", 0, 0,
-                                                     0),
-                        MakeCmdAttr<CommandFTSearchSQL>("ft.searchsql", -2, 
"read-only", 0, 0, 0),
-                        MakeCmdAttr<CommandFTSearch>("ft.search", -3, 
"read-only", 0, 0, 0),
-                        MakeCmdAttr<CommandFTExplainSQL>("ft.explainsql", -2, 
"read-only", 0, 0, 0),
-                        MakeCmdAttr<CommandFTExplain>("ft.explain", -3, 
"read-only", 0, 0, 0),
-                        MakeCmdAttr<CommandFTInfo>("ft.info", 2, "read-only", 
0, 0, 0),
-                        MakeCmdAttr<CommandFTList>("ft._list", 1, "read-only", 
0, 0, 0),
-                        MakeCmdAttr<CommandFTDrop>("ft.dropindex", 2, "write 
exclusive no-multi no-script", 0, 0, 0),
-                        MakeCmdAttr<CommandFTTagVals>("ft.tagvals", 3, 
"read-only slow", 0, 0, 0));
+                        MakeCmdAttr<CommandFTCreate>("ft.create", -2, "write 
exclusive no-multi no-script slow",
+                                                     NO_KEY),
+                        MakeCmdAttr<CommandFTSearchSQL>("ft.searchsql", -2, 
"read-only", NO_KEY),
+                        MakeCmdAttr<CommandFTSearch>("ft.search", -3, 
"read-only", NO_KEY),
+                        MakeCmdAttr<CommandFTExplainSQL>("ft.explainsql", -2, 
"read-only", NO_KEY),
+                        MakeCmdAttr<CommandFTExplain>("ft.explain", -3, 
"read-only", NO_KEY),
+                        MakeCmdAttr<CommandFTInfo>("ft.info", 2, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandFTList>("ft._list", 1, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandFTDrop>("ft.dropindex", 2, "write 
exclusive no-multi no-script", NO_KEY),
+                        MakeCmdAttr<CommandFTTagVals>("ft.tagvals", 3, 
"read-only slow", NO_KEY));
 
 }  // namespace redis
diff --git a/src/commands/cmd_server.cc b/src/commands/cmd_server.cc
index 66637f4f..260edca1 100644
--- a/src/commands/cmd_server.cc
+++ b/src/commands/cmd_server.cc
@@ -1331,43 +1331,43 @@ class CommandPollUpdates : public Commander {
   Format format_ = Format::Raw;
 };
 
-REDIS_REGISTER_COMMANDS(Server, MakeCmdAttr<CommandAuth>("auth", 2, "read-only 
ok-loading", 0, 0, 0),
-                        MakeCmdAttr<CommandPing>("ping", -1, "read-only", 0, 
0, 0),
-                        MakeCmdAttr<CommandSelect>("select", 2, "read-only", 
0, 0, 0),
-                        MakeCmdAttr<CommandInfo>("info", -1, "read-only 
ok-loading", 0, 0, 0),
-                        MakeCmdAttr<CommandRole>("role", 1, "read-only 
ok-loading", 0, 0, 0),
-                        MakeCmdAttr<CommandConfig>("config", -2, "read-only", 
0, 0, 0, GenerateConfigFlag),
-                        MakeCmdAttr<CommandNamespace>("namespace", -3, 
"read-only", 0, 0, 0),
-                        MakeCmdAttr<CommandKeys>("keys", 2, "read-only slow", 
0, 0, 0),
-                        MakeCmdAttr<CommandFlushDB>("flushdb", 1, "write 
no-dbsize-check", 0, 0, 0),
-                        MakeCmdAttr<CommandFlushAll>("flushall", 1, "write 
no-dbsize-check", 0, 0, 0),
-                        MakeCmdAttr<CommandDBSize>("dbsize", -1, "read-only", 
0, 0, 0),
-                        MakeCmdAttr<CommandSlowlog>("slowlog", -2, 
"read-only", 0, 0, 0),
-                        MakeCmdAttr<CommandPerfLog>("perflog", -2, 
"read-only", 0, 0, 0),
-                        MakeCmdAttr<CommandClient>("client", -2, "read-only", 
0, 0, 0),
-                        MakeCmdAttr<CommandMonitor>("monitor", 1, "read-only 
no-multi", 0, 0, 0),
-                        MakeCmdAttr<CommandShutdown>("shutdown", 1, "read-only 
no-multi no-script", 0, 0, 0),
-                        MakeCmdAttr<CommandQuit>("quit", 1, "read-only", 0, 0, 
0),
-                        MakeCmdAttr<CommandScan>("scan", -2, "read-only", 0, 
0, 0),
-                        MakeCmdAttr<CommandRandomKey>("randomkey", 1, 
"read-only", 0, 0, 0),
-                        MakeCmdAttr<CommandDebug>("debug", -2, "read-only 
exclusive", 0, 0, 0),
-                        MakeCmdAttr<CommandCommand>("command", -1, 
"read-only", 0, 0, 0),
-                        MakeCmdAttr<CommandEcho>("echo", 2, "read-only", 0, 0, 
0),
-                        MakeCmdAttr<CommandTime>("time", 1, "read-only 
ok-loading", 0, 0, 0),
-                        MakeCmdAttr<CommandDisk>("disk", 3, "read-only", 0, 0, 
0),
-                        MakeCmdAttr<CommandMemory>("memory", 3, "read-only", 
0, 0, 0),
-                        MakeCmdAttr<CommandHello>("hello", -1, "read-only 
ok-loading", 0, 0, 0),
+REDIS_REGISTER_COMMANDS(Server, MakeCmdAttr<CommandAuth>("auth", 2, "read-only 
ok-loading", NO_KEY),
+                        MakeCmdAttr<CommandPing>("ping", -1, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandSelect>("select", 2, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandInfo>("info", -1, "read-only 
ok-loading", NO_KEY),
+                        MakeCmdAttr<CommandRole>("role", 1, "read-only 
ok-loading", NO_KEY),
+                        MakeCmdAttr<CommandConfig>("config", -2, "read-only", 
NO_KEY, GenerateConfigFlag),
+                        MakeCmdAttr<CommandNamespace>("namespace", -3, 
"read-only", NO_KEY),
+                        MakeCmdAttr<CommandKeys>("keys", 2, "read-only slow", 
NO_KEY),
+                        MakeCmdAttr<CommandFlushDB>("flushdb", 1, "write 
no-dbsize-check", NO_KEY),
+                        MakeCmdAttr<CommandFlushAll>("flushall", 1, "write 
no-dbsize-check", NO_KEY),
+                        MakeCmdAttr<CommandDBSize>("dbsize", -1, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandSlowlog>("slowlog", -2, 
"read-only", NO_KEY),
+                        MakeCmdAttr<CommandPerfLog>("perflog", -2, 
"read-only", NO_KEY),
+                        MakeCmdAttr<CommandClient>("client", -2, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandMonitor>("monitor", 1, "read-only 
no-multi", NO_KEY),
+                        MakeCmdAttr<CommandShutdown>("shutdown", 1, "read-only 
no-multi no-script", NO_KEY),
+                        MakeCmdAttr<CommandQuit>("quit", 1, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandScan>("scan", -2, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandRandomKey>("randomkey", 1, 
"read-only", NO_KEY),
+                        MakeCmdAttr<CommandDebug>("debug", -2, "read-only 
exclusive", NO_KEY),
+                        MakeCmdAttr<CommandCommand>("command", -1, 
"read-only", NO_KEY),
+                        MakeCmdAttr<CommandEcho>("echo", 2, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandTime>("time", 1, "read-only 
ok-loading", NO_KEY),
+                        MakeCmdAttr<CommandDisk>("disk", 3, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandMemory>("memory", 3, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandHello>("hello", -1, "read-only 
ok-loading", NO_KEY),
                         MakeCmdAttr<CommandRestore>("restore", -4, "write", 1, 
1, 1),
 
-                        MakeCmdAttr<CommandCompact>("compact", 1, "read-only 
no-script", 0, 0, 0),
-                        MakeCmdAttr<CommandBGSave>("bgsave", 1, "read-only 
no-script", 0, 0, 0),
-                        MakeCmdAttr<CommandLastSave>("lastsave", 1, 
"read-only", 0, 0, 0),
-                        MakeCmdAttr<CommandFlushBackup>("flushbackup", 1, 
"read-only no-script", 0, 0, 0),
-                        MakeCmdAttr<CommandSlaveOf>("slaveof", 3, "read-only 
exclusive no-script", 0, 0, 0),
-                        MakeCmdAttr<CommandStats>("stats", 1, "read-only", 0, 
0, 0),
-                        MakeCmdAttr<CommandRdb>("rdb", -3, "write exclusive", 
0, 0, 0),
-                        MakeCmdAttr<CommandReset>("reset", 1, "ok-loading 
multi no-script pub-sub", 0, 0, 0),
-                        MakeCmdAttr<CommandApplyBatch>("applybatch", -2, 
"write no-multi", 0, 0, 0),
-                        MakeCmdAttr<CommandDump>("dump", 2, "read-only", 0, 0, 
0),
-                        MakeCmdAttr<CommandPollUpdates>("pollupdates", -2, 
"read-only", 0, 0, 0), )
+                        MakeCmdAttr<CommandCompact>("compact", 1, "read-only 
no-script", NO_KEY),
+                        MakeCmdAttr<CommandBGSave>("bgsave", 1, "read-only 
no-script", NO_KEY),
+                        MakeCmdAttr<CommandLastSave>("lastsave", 1, 
"read-only", NO_KEY),
+                        MakeCmdAttr<CommandFlushBackup>("flushbackup", 1, 
"read-only no-script", NO_KEY),
+                        MakeCmdAttr<CommandSlaveOf>("slaveof", 3, "read-only 
exclusive no-script", NO_KEY),
+                        MakeCmdAttr<CommandStats>("stats", 1, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandRdb>("rdb", -3, "write exclusive", 
NO_KEY),
+                        MakeCmdAttr<CommandReset>("reset", 1, "ok-loading 
multi no-script pub-sub", NO_KEY),
+                        MakeCmdAttr<CommandApplyBatch>("applybatch", -2, 
"write no-multi", NO_KEY),
+                        MakeCmdAttr<CommandDump>("dump", 2, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandPollUpdates>("pollupdates", -2, 
"read-only", NO_KEY), )
 }  // namespace redis
diff --git a/src/commands/cmd_stream.cc b/src/commands/cmd_stream.cc
index 3345c3b8..903b0031 100644
--- a/src/commands/cmd_stream.cc
+++ b/src/commands/cmd_stream.cc
@@ -1884,12 +1884,12 @@ REDIS_REGISTER_COMMANDS(Stream, 
MakeCmdAttr<CommandXAck>("xack", -4, "write no-d
                         MakeCmdAttr<CommandAutoClaim>("xautoclaim", -6, 
"write", 1, 1, 1),
                         MakeCmdAttr<CommandXGroup>("xgroup", -4, "write", 2, 
2, 1),
                         MakeCmdAttr<CommandXLen>("xlen", -2, "read-only", 1, 
1, 1),
-                        MakeCmdAttr<CommandXInfo>("xinfo", -2, "read-only", 0, 
0, 0),
+                        MakeCmdAttr<CommandXInfo>("xinfo", -2, "read-only", 
NO_KEY),
                         MakeCmdAttr<CommandXPending>("xpending", -3, 
"read-only", 1, 1, 1),
                         MakeCmdAttr<CommandXRange>("xrange", -4, "read-only", 
1, 1, 1),
                         MakeCmdAttr<CommandXRevRange>("xrevrange", -2, 
"read-only", 1, 1, 1),
-                        MakeCmdAttr<CommandXRead>("xread", -4, "read-only", 0, 
0, 0),
-                        MakeCmdAttr<CommandXReadGroup>("xreadgroup", -7, 
"write", 0, 0, 0),
+                        MakeCmdAttr<CommandXRead>("xread", -4, "read-only", 
NO_KEY),
+                        MakeCmdAttr<CommandXReadGroup>("xreadgroup", -7, 
"write", NO_KEY),
                         MakeCmdAttr<CommandXTrim>("xtrim", -4, "write 
no-dbsize-check", 1, 1, 1),
                         MakeCmdAttr<CommandXSetId>("xsetid", -3, "write", 1, 
1, 1))
 
diff --git a/src/commands/cmd_txn.cc b/src/commands/cmd_txn.cc
index 2984d621..92113fee 100644
--- a/src/commands/cmd_txn.cc
+++ b/src/commands/cmd_txn.cc
@@ -119,10 +119,10 @@ class CommandUnwatch : public Commander {
   }
 };
 
-REDIS_REGISTER_COMMANDS(Txn, MakeCmdAttr<CommandMulti>("multi", 1, "multi", 0, 
0, 0),
-                        MakeCmdAttr<CommandDiscard>("discard", 1, "multi", 0, 
0, 0),
-                        MakeCmdAttr<CommandExec>("exec", 1, "exclusive multi 
slow", 0, 0, 0),
+REDIS_REGISTER_COMMANDS(Txn, MakeCmdAttr<CommandMulti>("multi", 1, "multi", 
NO_KEY),
+                        MakeCmdAttr<CommandDiscard>("discard", 1, "multi", 
NO_KEY),
+                        MakeCmdAttr<CommandExec>("exec", 1, "exclusive multi 
slow", NO_KEY),
                         MakeCmdAttr<CommandWatch>("watch", -2, "multi", 1, -1, 
1),
-                        MakeCmdAttr<CommandUnwatch>("unwatch", 1, "multi", 0, 
0, 0), )
+                        MakeCmdAttr<CommandUnwatch>("unwatch", 1, "multi", 
NO_KEY), )
 
 }  // namespace redis
diff --git a/src/commands/commander.cc b/src/commands/commander.cc
index d9c68d2d..ecab960f 100644
--- a/src/commands/commander.cc
+++ b/src/commands/commander.cc
@@ -48,7 +48,7 @@ std::string CommandTable::GetCommandInfo(const 
CommandAttributes *command_attrib
   command.append(redis::BulkString(command_attributes->name));
   command.append(redis::Integer(command_attributes->arity));
   command_flags.append(redis::MultiLen(1));
-  command_flags.append(redis::BulkString(command_attributes->flags & kCmdWrite 
? "write" : "readonly"));
+  command_flags.append(redis::BulkString(command_attributes->InitialFlags() & 
kCmdWrite ? "write" : "readonly"));
   command.append(command_flags);
   command.append(redis::Integer(command_attributes->key_range.first_key));
   command.append(redis::Integer(command_attributes->key_range.last_key));
diff --git a/src/commands/commander.h b/src/commands/commander.h
index b0389d44..3c09fe87 100644
--- a/src/commands/commander.h
+++ b/src/commands/commander.h
@@ -152,7 +152,58 @@ using CommandKeyRangeVecGen = 
std::function<std::vector<CommandKeyRange>(const s
 
 using AdditionalFlagGen = std::function<uint64_t(uint64_t, const 
std::vector<std::string> &)>;
 
+struct NoKeyInThisCommand {};
+static constexpr const NoKeyInThisCommand NO_KEY{};
+
 struct CommandAttributes {
+  CommandAttributes(std::string name, int arity, CommandCategory category, 
uint64_t flags, AdditionalFlagGen flag_gen,
+                    NoKeyInThisCommand, CommanderFactory factory)
+      : name(std::move(name)),
+        arity(arity),
+        category(category),
+        key_range{0, 0, 0},
+        factory(std::move(factory)),
+        flags_(flags),
+        flag_gen_(std::move(flag_gen)) {}
+
+  CommandAttributes(std::string name, int arity, CommandCategory category, 
uint64_t flags, AdditionalFlagGen flag_gen,
+                    CommandKeyRange key_range, CommanderFactory factory)
+      : name(std::move(name)),
+        arity(arity),
+        category(category),
+        key_range(key_range),
+        factory(std::move(factory)),
+        flags_(flags),
+        flag_gen_(std::move(flag_gen)) {
+    if (key_range.first_key <= 0 || key_range.key_step <= 0 ||
+        (key_range.last_key >= 0 && key_range.last_key < key_range.first_key)) 
{
+      std::cout << fmt::format("Encountered invalid key range in command {}", 
this->name) << std::endl;
+      std::abort();
+    }
+  }
+
+  CommandAttributes(std::string name, int arity, CommandCategory category, 
uint64_t flags, AdditionalFlagGen flag_gen,
+                    CommandKeyRangeGen key_range, CommanderFactory factory)
+      : name(std::move(name)),
+        arity(arity),
+        category(category),
+        key_range{-1, 0, 0},
+        key_range_gen(std::move(key_range)),
+        factory(std::move(factory)),
+        flags_(flags),
+        flag_gen_(std::move(flag_gen)) {}
+
+  CommandAttributes(std::string name, int arity, CommandCategory category, 
uint64_t flags, AdditionalFlagGen flag_gen,
+                    CommandKeyRangeVecGen key_range, CommanderFactory factory)
+      : name(std::move(name)),
+        arity(arity),
+        category(category),
+        key_range{-2, 0, 0},
+        key_range_vec_gen(std::move(key_range)),
+        factory(std::move(factory)),
+        flags_(flags),
+        flag_gen_(std::move(flag_gen)) {}
+
   // command name
   std::string name;
 
@@ -164,13 +215,8 @@ struct CommandAttributes {
   // category of this command, e.g. key, string, hash
   CommandCategory category;
 
-  // bitmap of enum CommandFlags
-  uint64_t flags;
-
-  // additional flags regarding to dynamic command arguments
-  AdditionalFlagGen flag_gen;
-
   // static determined key range
+  // if key_range.first_key == 0, there's no key in this command args
   CommandKeyRange key_range;
 
   // if key_range.first_key == -1, key_range_gen is used instead
@@ -182,9 +228,11 @@ struct CommandAttributes {
   // commander object generator
   CommanderFactory factory;
 
+  uint64_t InitialFlags() const { return flags_; }
+
   auto GenerateFlags(const std::vector<std::string> &args) const {
-    uint64_t res = flags;
-    if (flag_gen) res = flag_gen(res, args);
+    uint64_t res = flags_;
+    if (flag_gen_) res = flag_gen_(res, args);
     return res;
   }
 
@@ -212,6 +260,13 @@ struct CommandAttributes {
       }
     }
   }
+
+ private:
+  // bitmap of enum CommandFlags
+  uint64_t flags_;
+
+  // additional flags regarding to dynamic command arguments
+  AdditionalFlagGen flag_gen_;
 };
 
 using CommandMap = std::map<std::string, const CommandAttributes *>;
@@ -257,23 +312,21 @@ inline uint64_t ParseCommandFlags(const std::string 
&description, const std::str
   return flags;
 }
 
+template <typename T>
+auto MakeCmdAttr(const std::string &name, int arity, const std::string 
&description, NoKeyInThisCommand no_key,
+                 const AdditionalFlagGen &flag_gen = {}) {
+  CommandAttributes attr(name, arity, CommandCategory::Unknown, 
ParseCommandFlags(description, name), flag_gen, no_key,
+                         []() -> 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, int first_key, int last_key,
                  int key_step = 1, const AdditionalFlagGen &flag_gen = {}) {
-  CommandAttributes attr{name,
-                         arity,
-                         CommandCategory::Unknown,
-                         ParseCommandFlags(description, name),
-                         flag_gen,
+  CommandAttributes attr(name, arity, CommandCategory::Unknown, 
ParseCommandFlags(description, name), flag_gen,
                          {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)) {
-    std::cout << fmt::format("Encountered invalid key range in command {}", 
name) << std::endl;
-    std::abort();
-  }
+                         []() -> std::unique_ptr<Commander> { return 
std::unique_ptr<Commander>(new T()); });
 
   return attr;
 }
@@ -286,9 +339,7 @@ auto MakeCmdAttr(const std::string &name, int arity, const 
std::string &descript
                          CommandCategory::Unknown,
                          ParseCommandFlags(description, name),
                          flag_gen,
-                         {-1, 0, 0},
                          gen,
-                         {},
                          []() -> std::unique_ptr<Commander> { return 
std::unique_ptr<Commander>(new T()); }};
 
   return attr;
@@ -302,8 +353,6 @@ auto MakeCmdAttr(const std::string &name, int arity, const 
std::string &descript
                          CommandCategory::Unknown,
                          ParseCommandFlags(description, name),
                          flag_gen,
-                         {-2, 0, 0},
-                         {},
                          vec_gen,
                          []() -> std::unique_ptr<Commander> { return 
std::unique_ptr<Commander>(new T()); }};
 
diff --git a/src/server/redis_connection.cc b/src/server/redis_connection.cc
index 6647c308..24ea47b9 100644
--- a/src/server/redis_connection.cc
+++ b/src/server/redis_connection.cc
@@ -361,10 +361,9 @@ Status Connection::ExecuteCommand(engine::Context &ctx, 
const std::string &cmd_n
   return s;
 }
 
-static bool IsCmdForIndexing(const CommandAttributes *attr) {
-  return (attr->flags & redis::kCmdWrite) &&
-         (attr->category == CommandCategory::Hash || attr->category == 
CommandCategory::JSON ||
-          attr->category == CommandCategory::Key);
+static bool IsCmdForIndexing(uint64_t cmd_flags, CommandCategory cmd_cat) {
+  return (cmd_flags & redis::kCmdWrite) &&
+         (cmd_cat == CommandCategory::Hash || cmd_cat == CommandCategory::JSON 
|| cmd_cat == CommandCategory::Key);
 }
 
 void Connection::ExecuteCommands(std::deque<CommandTokens> *to_process_cmds) {
@@ -503,7 +502,8 @@ void Connection::ExecuteCommands(std::deque<CommandTokens> 
*to_process_cmds) {
 
       // TODO: transaction support for index recording
       std::vector<GlobalIndexer::RecordResult> index_records;
-      if (!srv_->index_mgr.index_map.empty() && IsCmdForIndexing(attributes) 
&& !config->cluster_enabled) {
+      if (!srv_->index_mgr.index_map.empty() && IsCmdForIndexing(cmd_flags, 
attributes->category) &&
+          !config->cluster_enabled) {
         attributes->ForEachKeyRange(
             [&, this](const std::vector<std::string> &args, const 
CommandKeyRange &key_range) {
               key_range.ForEachKey(
diff --git a/src/server/server.cc b/src/server/server.cc
index f004a19e..f20b6824 100644
--- a/src/server/server.cc
+++ b/src/server/server.cc
@@ -1983,7 +1983,7 @@ void Server::updateAllWatchedKeys() {
 }
 
 void Server::UpdateWatchedKeysFromArgs(const std::vector<std::string> &args, 
const redis::CommandAttributes &attr) {
-  if ((attr.flags & redis::kCmdWrite) && watched_key_size_ > 0) {
+  if ((attr.GenerateFlags(args) & redis::kCmdWrite) && watched_key_size_ > 0) {
     if (attr.key_range.first_key > 0) {
       updateWatchedKeysFromRange(args, attr.key_range);
     } else if (attr.key_range.first_key == -1) {

Reply via email to