@@ -28,6 +28,7 @@ extern "C" {
28
28
#include " core/sorted_map.h"
29
29
#include " core/string_map.h"
30
30
#include " core/string_set.h"
31
+ #include " facade/cmd_arg_parser.h"
31
32
#include " server/blocking_controller.h"
32
33
#include " server/container_utils.h"
33
34
#include " server/engine_shard_set.h"
@@ -38,7 +39,6 @@ extern "C" {
38
39
#include " server/server_state.h"
39
40
#include " server/string_family.h"
40
41
#include " server/transaction.h"
41
-
42
42
using namespace std ;
43
43
44
44
ABSL_DECLARE_FLAG (string, dir);
@@ -712,106 +712,57 @@ void DebugCmd::Migration(CmdArgList args, facade::SinkReplyBuilder* builder) {
712
712
return builder->SendError (UnknownSubCmd (" MIGRATION" , " DEBUG" ));
713
713
}
714
714
715
+ enum PopulateFlag { FLAG_RAND, FLAG_TYPE, FLAG_ELEMENTS, FLAG_SLOT, FLAG_EXPIRE, FLAG_UNKNOWN };
716
+
715
717
// Populate arguments format:
716
718
// required: (total count) (key prefix) (val size)
717
719
// optional: [RAND | TYPE typename | ELEMENTS element num | SLOTS (key value)+ | EXPIRE start end]
718
720
optional<DebugCmd::PopulateOptions> DebugCmd::ParsePopulateArgs (CmdArgList args,
719
721
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 ));
725
723
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
- }
734
724
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 );
741
728
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 ;
766
746
}
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;
775
753
}
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 ;
808
756
}
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 ;
813
760
}
814
761
}
762
+ if (parser.HasError ()) {
763
+ builder->SendError (parser.Error ()->MakeReply ());
764
+ return nullopt;
765
+ }
815
766
return options;
816
767
}
817
768
0 commit comments