@@ -22,14 +22,16 @@ using namespace std;
22
22
ABSL_FLAG (vector<string>, rename_command, {},
23
23
" Change the name of commands, format is: <cmd1_name>=<cmd1_new_name>, "
24
24
" <cmd2_name>=<cmd2_new_name>" );
25
- ABSL_FLAG (vector<string>, command_alias, {},
26
- " Add an alias for given commands, format is: <alias>=<original>, "
27
- " <alias>=<original>" );
28
25
ABSL_FLAG (vector<string>, restricted_commands, {},
29
26
" Commands restricted to connections on the admin port" );
30
27
31
28
ABSL_FLAG (vector<string>, oom_deny_commands, {},
32
29
" Additinal commands that will be marked as denyoom" );
30
+
31
+ ABSL_FLAG (vector<string>, command_alias, {},
32
+ " Add an alias for given command(s), format is: <alias>=<original>, <alias>=<original>. "
33
+ " Aliases must be set identically on replicas, if applicable" );
34
+
33
35
namespace dfly {
34
36
35
37
using namespace facade ;
@@ -75,16 +77,17 @@ uint32_t ImplicitAclCategories(uint32_t mask) {
75
77
return out;
76
78
}
77
79
78
- absl::flat_hash_map<std::string, std::string> ParseCmdlineArgMap (
79
- const absl::Flag<std::vector<std::string>>& flag, const bool allow_duplicates = false ) {
80
+ using CmdLineMapping = absl::flat_hash_map<std::string, std::string>;
81
+
82
+ CmdLineMapping ParseCmdlineArgMap (const absl::Flag<std::vector<std::string>>& flag) {
80
83
const auto & mappings = absl::GetFlag (flag);
81
- absl::flat_hash_map<std::string, std::string> parsed_mappings;
84
+ CmdLineMapping parsed_mappings;
82
85
parsed_mappings.reserve (mappings.size ());
83
86
84
87
for (const std::string& mapping : mappings) {
85
- std::vector <std::string_view> kv = absl::StrSplit (mapping, ' =' );
88
+ absl::InlinedVector <std::string_view, 2 > kv = absl::StrSplit (mapping, ' =' );
86
89
if (kv.size () != 2 ) {
87
- LOG (ERROR) << " Malformed command " << mapping << " for " << flag.Name ()
90
+ LOG (ERROR) << " Malformed command ' " << mapping << " ' for " << flag.Name ()
88
91
<< " , expected key=value" ;
89
92
exit (1 );
90
93
}
@@ -97,15 +100,27 @@ absl::flat_hash_map<std::string, std::string> ParseCmdlineArgMap(
97
100
exit (1 );
98
101
}
99
102
100
- const bool inserted = parsed_mappings.emplace (std::move (key), std::move (value)).second ;
101
- if (!allow_duplicates && !inserted) {
103
+ if (!parsed_mappings.emplace (std::move (key), std::move (value)).second ) {
102
104
LOG (ERROR) << " Duplicate insert to " << flag.Name () << " not allowed" ;
103
105
exit (1 );
104
106
}
105
107
}
106
108
return parsed_mappings;
107
109
}
108
110
111
+ CmdLineMapping OriginalToAliasMap () {
112
+ CmdLineMapping original_to_alias;
113
+ CmdLineMapping alias_to_original = ParseCmdlineArgMap (FLAGS_command_alias);
114
+ original_to_alias.reserve (alias_to_original.size ());
115
+ std::for_each (std::make_move_iterator (alias_to_original.begin ()),
116
+ std::make_move_iterator (alias_to_original.end ()),
117
+ [&original_to_alias](auto && pair) {
118
+ original_to_alias.emplace (std::move (pair.second ), std::move (pair.first ));
119
+ });
120
+
121
+ return original_to_alias;
122
+ }
123
+
109
124
} // namespace
110
125
111
126
CommandId::CommandId (const char * name, uint32_t mask, int8_t arity, int8_t first_key,
@@ -115,6 +130,17 @@ CommandId::CommandId(const char* name, uint32_t mask, int8_t arity, int8_t first
115
130
implicit_acl_ = !acl_categories.has_value ();
116
131
}
117
132
133
+ CommandId CommandId::Clone (const std::string_view name) const {
134
+ CommandId cloned =
135
+ CommandId{name.data (), opt_mask_, arity_, first_key_, last_key_, acl_categories_};
136
+ cloned.handler_ = handler_;
137
+ cloned.opt_mask_ = opt_mask_ | CO::HIDDEN;
138
+ cloned.acl_categories_ = acl_categories_;
139
+ cloned.implicit_acl_ = implicit_acl_;
140
+ cloned.is_alias_ = true ;
141
+ return cloned;
142
+ }
143
+
118
144
bool CommandId::IsTransactional () const {
119
145
if (first_key_ > 0 || (opt_mask_ & CO::GLOBAL_TRANS) || (opt_mask_ & CO::NO_KEY_TRANSACTIONAL))
120
146
return true ;
@@ -130,16 +156,15 @@ bool CommandId::IsMultiTransactional() const {
130
156
return CO::IsTransKind (name ()) || CO::IsEvalKind (name ());
131
157
}
132
158
133
- uint64_t CommandId::Invoke (CmdArgList args, const CommandContext& cmd_cntx,
134
- std::string_view orig_cmd_name) const {
159
+ uint64_t CommandId::Invoke (CmdArgList args, const CommandContext& cmd_cntx) const {
135
160
int64_t before = absl::GetCurrentTimeNanos ();
136
161
handler_ (args, cmd_cntx);
137
162
int64_t after = absl::GetCurrentTimeNanos ();
138
163
139
164
ServerState* ss = ServerState::tlocal (); // Might have migrated thread, read after invocation
140
165
int64_t execution_time_usec = (after - before) / 1000 ;
141
166
142
- auto & ent = command_stats_[ss->thread_index ()][orig_cmd_name] ;
167
+ auto & ent = command_stats_[ss->thread_index ()];
143
168
144
169
++ent.first ;
145
170
ent.second += execution_time_usec;
@@ -169,7 +194,6 @@ optional<facade::ErrorReply> CommandId::Validate(CmdArgList tail_args) const {
169
194
170
195
CommandRegistry::CommandRegistry () {
171
196
cmd_rename_map_ = ParseCmdlineArgMap (FLAGS_rename_command);
172
- cmd_aliases_ = ParseCmdlineArgMap (FLAGS_command_alias, true );
173
197
174
198
for (string name : GetFlag (FLAGS_restricted_commands)) {
175
199
restricted_cmds_.emplace (AsciiStrToUpper (name));
@@ -181,9 +205,20 @@ CommandRegistry::CommandRegistry() {
181
205
}
182
206
183
207
void CommandRegistry::Init (unsigned int thread_count) {
208
+ const CmdLineMapping original_to_alias = OriginalToAliasMap ();
209
+ absl::flat_hash_map<std::string, CommandId> alias_to_command_id;
210
+ alias_to_command_id.reserve (original_to_alias.size ());
184
211
for (auto & [_, cmd] : cmd_map_) {
185
212
cmd.Init (thread_count);
213
+ if (auto it = original_to_alias.find (cmd.name ()); it != original_to_alias.end ()) {
214
+ auto alias_cmd = cmd.Clone (it->second );
215
+ alias_cmd.Init (thread_count);
216
+ alias_to_command_id.insert ({it->second , std::move (alias_cmd)});
217
+ }
186
218
}
219
+ std::copy (std::make_move_iterator (alias_to_command_id.begin ()),
220
+ std::make_move_iterator (alias_to_command_id.end ()),
221
+ std::inserter (cmd_map_, cmd_map_.end ()));
187
222
}
188
223
189
224
CommandRegistry& CommandRegistry::operator <<(CommandId cmd) {
@@ -212,7 +247,7 @@ CommandRegistry& CommandRegistry::operator<<(CommandId cmd) {
212
247
213
248
if (!is_sub_command || absl::StartsWith (cmd.name (), " ACL" )) {
214
249
cmd.SetBitIndex (1ULL << bit_index_);
215
- family_of_commands_.back ().push_back ( std::string (k) );
250
+ family_of_commands_.back ().emplace_back (k );
216
251
++bit_index_;
217
252
} else {
218
253
DCHECK (absl::StartsWith (k, family_of_commands_.back ().back ()));
@@ -266,10 +301,6 @@ std::pair<const CommandId*, ArgSlice> CommandRegistry::FindExtended(string_view
266
301
return {res, tail_args};
267
302
}
268
303
269
- bool CommandRegistry::IsAlias (std::string_view cmd) const {
270
- return cmd_aliases_.contains (cmd);
271
- }
272
-
273
304
namespace CO {
274
305
275
306
const char * OptName (CO::CommandOpt fl) {
0 commit comments