Skip to content

Commit 627805f

Browse files
authored
chore: introduce ParsedArguments class (#6169)
Currently we use ArgSlice, CmdArgList everywhere where we want a span on string_views. As a result, it's very hard to understand the requirements from the passed classes. This PR introduces a new ParsedArguments class and reduces the API surface for the passed object. Make sure to unwind ParsedArguments to ArgSlice only when we start executing the command. We will clean-up redundant aliases in the futures. Signed-off-by: Roman Gershman <[email protected]>
1 parent c6906ea commit 627805f

15 files changed

+91
-55
lines changed

src/facade/cmd_arg_parser.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ struct CmdArgParser {
5656
};
5757

5858
public:
59-
CmdArgParser(CmdArgList args) : args_{args} {
59+
CmdArgParser(ArgSlice args) : args_{args} {
6060
}
6161

6262
// Debug asserts sure error was consumed
@@ -159,7 +159,7 @@ struct CmdArgParser {
159159
}
160160

161161
// Return remaining arguments
162-
CmdArgList Tail() const {
162+
ArgSlice Tail() const {
163163
return args_.subspan(cur_i_);
164164
}
165165

@@ -168,7 +168,7 @@ struct CmdArgParser {
168168
return cur_i_ < args_.size() && !error_;
169169
}
170170

171-
bool HasError() {
171+
bool HasError() const {
172172
return error_.type != ErrorType::NO_ERROR;
173173
}
174174

@@ -275,7 +275,7 @@ struct CmdArgParser {
275275

276276
private:
277277
size_t cur_i_ = 0;
278-
CmdArgList args_;
278+
ArgSlice args_;
279279

280280
ErrorInfo error_;
281281
};

src/facade/command_id.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@
44

55
#pragma once
66

7+
#include <cstdint>
8+
#include <string>
79
#include <string_view>
810

9-
#include "facade/facade_types.h"
10-
1111
namespace facade {
1212

1313
class CommandId {
1414
public:
15-
using CmdArgList = facade::CmdArgList;
16-
1715
/**
1816
* @brief Construct a new Command Id object
1917
*

src/facade/dragonfly_connection.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -558,8 +558,8 @@ void Connection::AsyncOperations::operator()(Connection::PipelineMessage& msg) {
558558
DVLOG(2) << "Dispatching pipeline: " << ToSV(msg.args.front());
559559

560560
++self->local_stats_.cmds;
561-
self->service_->DispatchCommand(CmdArgList{msg.args.data(), msg.args.size()},
562-
self->reply_builder_.get(), self->cc_.get());
561+
self->service_->DispatchCommand(ParsedArgs{msg.args}, self->reply_builder_.get(),
562+
self->cc_.get());
563563

564564
self->last_interaction_ = time(nullptr);
565565
self->skip_next_squashing_ = false;
@@ -1219,7 +1219,7 @@ Connection::ParserStatus Connection::ParseRedis(unsigned max_busy_cycles) {
12191219

12201220
auto dispatch_sync = [this] {
12211221
RespExpr::VecToArgList(tmp_parse_args_, &tmp_cmd_vec_);
1222-
service_->DispatchCommand(absl::MakeSpan(tmp_cmd_vec_), reply_builder_.get(), cc_.get());
1222+
service_->DispatchCommand(ParsedArgs{tmp_cmd_vec_}, reply_builder_.get(), cc_.get());
12231223
};
12241224

12251225
auto dispatch_async = [this]() -> MessageHandle { return {FromArgs(tmp_parse_args_)}; };
@@ -1536,7 +1536,7 @@ void Connection::SquashPipeline() {
15361536
DCHECK_EQ(dispatch_q_.size(), pending_pipeline_cmd_cnt_);
15371537
DCHECK_EQ(reply_builder_->GetProtocol(), Protocol::REDIS); // Only Redis is supported.
15381538

1539-
vector<ArgSlice> squash_cmds;
1539+
vector<ParsedArgs> squash_cmds;
15401540
squash_cmds.reserve(dispatch_q_.size());
15411541

15421542
uint64_t start = CycleClock::Now();
@@ -1546,7 +1546,7 @@ void Connection::SquashPipeline() {
15461546
<< msg.handle.index() << " on " << DebugInfo();
15471547

15481548
auto& pmsg = get<PipelineMessagePtr>(msg.handle);
1549-
squash_cmds.emplace_back(absl::MakeSpan(pmsg->args));
1549+
squash_cmds.emplace_back(ParsedArgs(pmsg->args));
15501550
if (squash_cmds.size() >= pipeline_squash_limit_cached) {
15511551
// We reached the limit of commands to squash, so we dispatch them.
15521552
break;

src/facade/facade_types.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,37 @@ using CmdArgVec = std::vector<std::string_view>;
4141
using ArgSlice = absl::Span<const std::string_view>;
4242
using OwnedArgSlice = absl::Span<const std::string>;
4343

44+
class ParsedArgs {
45+
public:
46+
ParsedArgs() = default;
47+
48+
explicit ParsedArgs(ArgSlice args) : args_(args) { // NOLINT google-explicit-constructor
49+
}
50+
51+
size_t size() const {
52+
return args_.size();
53+
}
54+
55+
bool empty() const {
56+
return args_.empty();
57+
}
58+
59+
ParsedArgs Tail() const {
60+
return ParsedArgs{args_.subspan(1)};
61+
}
62+
63+
std::string_view Front() const {
64+
return args_.front();
65+
}
66+
67+
ArgSlice ToSlice() const {
68+
return args_;
69+
}
70+
71+
private:
72+
absl::Span<const std::string_view> args_;
73+
};
74+
4475
inline std::string_view ToSV(std::string_view slice) {
4576
return slice;
4677
}

src/facade/ok_main.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ namespace {
2222

2323
class OkService : public ServiceInterface {
2424
public:
25-
DispatchResult DispatchCommand(ArgSlice args, SinkReplyBuilder* builder,
25+
DispatchResult DispatchCommand(ParsedArgs args, SinkReplyBuilder* builder,
2626
ConnectionContext* cntx) final {
2727
builder->SendOk();
2828
return DispatchResult::OK;
2929
}
3030

31-
DispatchManyResult DispatchManyCommands(absl::Span<ArgSlice> args_lists,
31+
DispatchManyResult DispatchManyCommands(absl::Span<ParsedArgs> args_lists,
3232
SinkReplyBuilder* builder,
3333
ConnectionContext* cntx) final {
3434
for (auto args : args_lists)

src/facade/service_interface.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ class ServiceInterface {
3636
virtual ~ServiceInterface() {
3737
}
3838

39-
virtual DispatchResult DispatchCommand(ArgSlice args, SinkReplyBuilder* builder,
39+
virtual DispatchResult DispatchCommand(ParsedArgs args, SinkReplyBuilder* builder,
4040
ConnectionContext* cntx) = 0;
4141

42-
virtual DispatchManyResult DispatchManyCommands(absl::Span<ArgSlice> commands,
42+
virtual DispatchManyResult DispatchManyCommands(absl::Span<ParsedArgs> commands,
4343
SinkReplyBuilder* builder,
4444
ConnectionContext* cntx) = 0;
4545

src/server/command_registry.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -325,17 +325,17 @@ CommandRegistry::FamiliesVec CommandRegistry::GetFamilies() {
325325
return std::move(family_of_commands_);
326326
}
327327

328-
std::pair<const CommandId*, ArgSlice> CommandRegistry::FindExtended(string_view cmd,
329-
ArgSlice tail_args) const {
328+
std::pair<const CommandId*, ParsedArgs> CommandRegistry::FindExtended(string_view cmd,
329+
ParsedArgs tail_args) const {
330330
if (cmd == RenamedOrOriginal("ACL"sv)) {
331331
if (tail_args.empty()) {
332332
return {Find(cmd), {}};
333333
}
334334

335-
auto second_cmd = absl::AsciiStrToUpper(ArgS(tail_args, 0));
335+
auto second_cmd = absl::AsciiStrToUpper(tail_args.Front());
336336
string full_cmd = absl::StrCat(cmd, " ", second_cmd);
337337

338-
return {Find(full_cmd), tail_args.subspan(1)};
338+
return {Find(full_cmd), tail_args.Tail()};
339339
}
340340

341341
const CommandId* res = Find(cmd);
@@ -344,7 +344,7 @@ std::pair<const CommandId*, ArgSlice> CommandRegistry::FindExtended(string_view
344344

345345
// A workaround for XGROUP HELP that does not fit our static taxonomy of commands.
346346
if (tail_args.size() == 1 && res->name() == "XGROUP") {
347-
if (absl::EqualsIgnoreCase(ArgS(tail_args, 0), "HELP")) {
347+
if (absl::EqualsIgnoreCase(tail_args.Front(), "HELP")) {
348348
res = Find("_XGROUP_HELP");
349349
}
350350
}

src/server/command_registry.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "base/function2.hpp"
1616
#include "facade/command_id.h"
17+
#include "facade/facade_types.h"
1718

1819
namespace facade {
1920
class SinkReplyBuilder;
@@ -107,6 +108,8 @@ template <typename T> class MoveOnly {
107108

108109
class CommandId : public facade::CommandId {
109110
public:
111+
using CmdArgList = facade::CmdArgList;
112+
110113
// NOTICE: name must be a literal string, otherwise metrics break! (see cmd_stats_map in
111114
// server_state.h)
112115
CommandId(const char* name, uint32_t mask, int8_t arity, int8_t first_key, int8_t last_key,
@@ -251,8 +254,8 @@ class CommandRegistry {
251254
using FamiliesVec = std::vector<std::vector<std::string>>;
252255
FamiliesVec GetFamilies();
253256

254-
std::pair<const CommandId*, facade::ArgSlice> FindExtended(std::string_view cmd,
255-
facade::ArgSlice tail_args) const;
257+
std::pair<const CommandId*, facade::ParsedArgs> FindExtended(std::string_view cmd,
258+
facade::ParsedArgs tail_args) const;
256259

257260
absl::flat_hash_map<std::string, hdr_histogram*> LatencyMap() const;
258261

src/server/http_api.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ void HttpAPI(const http::QueryArgs& args, HttpRequest&& req, Service* service,
198198
facade::CapturingReplyBuilder reply_builder;
199199

200200
// TODO: to finish this.
201-
service->DispatchCommand(absl::MakeSpan(cmd_slices), &reply_builder, context);
201+
service->DispatchCommand(facade::ParsedArgs{cmd_slices}, &reply_builder, context);
202202
facade::CapturingReplyBuilder::Payload payload = reply_builder.Take();
203203

204204
auto response = http::MakeStringResponse();

src/server/journal/executor.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ void JournalExecutor::FlushSlots(const cluster::SlotRange& slot_range) {
6565
}
6666

6767
facade::DispatchResult JournalExecutor::Execute(journal::ParsedEntry::CmdData& cmd) {
68-
auto span = CmdArgList{cmd.cmd_args.data(), cmd.cmd_args.size()};
69-
return service_->DispatchCommand(span, &reply_builder_, &conn_context_);
68+
return service_->DispatchCommand(facade::ParsedArgs{cmd.cmd_args}, &reply_builder_,
69+
&conn_context_);
7070
}
7171

7272
void JournalExecutor::SelectDb(DbIndex dbid) {

0 commit comments

Comments
 (0)