Skip to content

Commit a02af96

Browse files
authored
refactor(debug-cmd): migrate ParsePopulateArgs to CmdArgParser (#4838)
* refactor(debug-cmd): migrate ParsePopulateArgs to CmdArgParser Signed-off-by: yexiaochuan <tap91624@gmail.com>
1 parent 7d05306 commit a02af96

File tree

1 file changed

+39
-88
lines changed

1 file changed

+39
-88
lines changed

src/server/debugcmd.cc

Lines changed: 39 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ extern "C" {
2828
#include "core/sorted_map.h"
2929
#include "core/string_map.h"
3030
#include "core/string_set.h"
31+
#include "facade/cmd_arg_parser.h"
3132
#include "server/blocking_controller.h"
3233
#include "server/container_utils.h"
3334
#include "server/engine_shard_set.h"
@@ -38,7 +39,6 @@ extern "C" {
3839
#include "server/server_state.h"
3940
#include "server/string_family.h"
4041
#include "server/transaction.h"
41-
4242
using namespace std;
4343

4444
ABSL_DECLARE_FLAG(string, dir);
@@ -712,106 +712,57 @@ void DebugCmd::Migration(CmdArgList args, facade::SinkReplyBuilder* builder) {
712712
return builder->SendError(UnknownSubCmd("MIGRATION", "DEBUG"));
713713
}
714714

715+
enum PopulateFlag { FLAG_RAND, FLAG_TYPE, FLAG_ELEMENTS, FLAG_SLOT, FLAG_EXPIRE, FLAG_UNKNOWN };
716+
715717
// Populate arguments format:
716718
// required: (total count) (key prefix) (val size)
717719
// optional: [RAND | TYPE typename | ELEMENTS element num | SLOTS (key value)+ | EXPIRE start end]
718720
optional<DebugCmd::PopulateOptions> DebugCmd::ParsePopulateArgs(CmdArgList args,
719721
facade::SinkReplyBuilder* builder) {
720-
if (args.size() < 2) {
721-
builder->SendError(UnknownSubCmd("populate", "DEBUG"));
722-
return nullopt;
723-
}
724-
722+
CmdArgParser parser(args.subspan(1));
725723
PopulateOptions options;
726-
if (!absl::SimpleAtoi(ArgS(args, 1), &options.total_count)) {
727-
builder->SendError(kUintErr);
728-
return nullopt;
729-
}
730-
731-
if (args.size() > 2) {
732-
options.prefix = ArgS(args, 2);
733-
}
734724

735-
if (args.size() > 3) {
736-
if (!absl::SimpleAtoi(ArgS(args, 3), &options.val_size)) {
737-
builder->SendError(kUintErr);
738-
return nullopt;
739-
}
740-
}
725+
options.total_count = parser.Next<uint64_t>();
726+
options.prefix = parser.NextOrDefault<string_view>("key");
727+
options.val_size = parser.NextOrDefault<uint32_t>(16);
741728

742-
for (size_t index = 4; args.size() > index; ++index) {
743-
string str = absl::AsciiStrToUpper(ArgS(args, index));
744-
if (str == "RAND") {
745-
options.populate_random_values = true;
746-
} else if (str == "TYPE") {
747-
if (args.size() < index + 2) {
748-
builder->SendError(kSyntaxErr);
749-
return nullopt;
750-
}
751-
++index;
752-
options.type = absl::AsciiStrToUpper(ArgS(args, index));
753-
} else if (str == "ELEMENTS") {
754-
if (args.size() < index + 2) {
755-
builder->SendError(kSyntaxErr);
756-
return nullopt;
757-
}
758-
if (!absl::SimpleAtoi(ArgS(args, ++index), &options.elements)) {
759-
builder->SendError(kSyntaxErr);
760-
return nullopt;
761-
}
762-
} else if (str == "SLOTS") {
763-
if (args.size() < index + 3) {
764-
builder->SendError(kSyntaxErr);
765-
return nullopt;
729+
while (parser.HasNext()) {
730+
PopulateFlag flag = parser.MapNext("RAND", FLAG_RAND, "TYPE", FLAG_TYPE, "ELEMENTS",
731+
FLAG_ELEMENTS, "SLOTS", FLAG_SLOT, "EXPIRE", FLAG_EXPIRE);
732+
switch (flag) {
733+
case FLAG_RAND:
734+
options.populate_random_values = true;
735+
break;
736+
case FLAG_TYPE:
737+
options.type = absl::AsciiStrToUpper(parser.Next<string_view>());
738+
break;
739+
case FLAG_ELEMENTS:
740+
options.elements = parser.Next<uint32_t>();
741+
break;
742+
case FLAG_SLOT: {
743+
auto [start, end] = parser.Next<FInt<0, 16383>, FInt<0, 16383>>();
744+
options.slot_range = cluster::SlotRange{SlotId(start), SlotId(end)};
745+
break;
766746
}
767-
768-
auto parse_slot = [](string_view slot_str) -> OpResult<uint32_t> {
769-
uint32_t slot_id;
770-
if (!absl::SimpleAtoi(slot_str, &slot_id)) {
771-
return facade::OpStatus::INVALID_INT;
772-
}
773-
if (slot_id > kMaxSlotNum) {
774-
return facade::OpStatus::INVALID_VALUE;
747+
case FLAG_EXPIRE: {
748+
auto [min_ttl, max_ttl] = parser.Next<uint32_t, uint32_t>();
749+
if (min_ttl >= max_ttl) {
750+
builder->SendError(kExpiryOutOfRange);
751+
(void)parser.Error();
752+
return nullopt;
775753
}
776-
return slot_id;
777-
};
778-
779-
auto start = parse_slot(ArgS(args, ++index));
780-
if (start.status() != facade::OpStatus::OK) {
781-
builder->SendError(start.status());
782-
return nullopt;
783-
}
784-
auto end = parse_slot(ArgS(args, ++index));
785-
if (end.status() != facade::OpStatus::OK) {
786-
builder->SendError(end.status());
787-
return nullopt;
788-
}
789-
options.slot_range = cluster::SlotRange{.start = static_cast<SlotId>(start.value()),
790-
.end = static_cast<SlotId>(end.value())};
791-
} else if (str == "EXPIRE") {
792-
if (args.size() < index + 3) {
793-
builder->SendError(kSyntaxErr);
794-
return nullopt;
795-
}
796-
uint32_t start, end;
797-
if (!absl::SimpleAtoi(ArgS(args, ++index), &start)) {
798-
builder->SendError(kSyntaxErr);
799-
return nullopt;
800-
}
801-
if (!absl::SimpleAtoi(ArgS(args, ++index), &end)) {
802-
builder->SendError(kSyntaxErr);
803-
return nullopt;
804-
}
805-
if (start >= end) {
806-
builder->SendError(kExpiryOutOfRange);
807-
return nullopt;
754+
options.expire_ttl_range = std::make_pair(min_ttl, max_ttl);
755+
break;
808756
}
809-
options.expire_ttl_range = std::make_pair(start, end);
810-
} else {
811-
builder->SendError(kSyntaxErr);
812-
return nullopt;
757+
default:
758+
LOG(FATAL) << "Unexpected flag in PopulateArgs. Args: " << args;
759+
break;
813760
}
814761
}
762+
if (parser.HasError()) {
763+
builder->SendError(parser.Error()->MakeReply());
764+
return nullopt;
765+
}
815766
return options;
816767
}
817768

0 commit comments

Comments
 (0)