Skip to content

Commit 70e757f

Browse files
authored
feat(server): extend populate command with expire (#4752)
1 parent b6a94e9 commit 70e757f

File tree

2 files changed

+54
-6
lines changed

2 files changed

+54
-6
lines changed

src/server/debugcmd.cc

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,9 @@ tuple<const CommandId*, absl::InlinedVector<string, 5>> GeneratePopulateCommand(
153153
}
154154

155155
void DoPopulateBatch(string_view type, string_view prefix, size_t val_size, bool random_value,
156-
int32_t elements, const PopulateBatch& batch, ServerFamily* sf,
157-
ConnectionContext* cntx) {
156+
int32_t elements,
157+
std::optional<std::pair<uint32_t, uint32_t>> expire_ttl_range,
158+
const PopulateBatch& batch, ServerFamily* sf, ConnectionContext* cntx) {
158159
boost::intrusive_ptr<Transaction> local_tx =
159160
new Transaction{sf->service().mutable_registry()->Find("EXEC")};
160161
local_tx->StartMultiNonAtomic();
@@ -194,6 +195,28 @@ void DoPopulateBatch(string_view type, string_view prefix, size_t val_size, bool
194195
stub_tx->InitByArgs(cntx->ns, local_cntx.conn_state.db_index, args_span);
195196

196197
sf->service().InvokeCmd(cid, args_span, &crb, &local_cntx);
198+
199+
if (expire_ttl_range.has_value()) {
200+
uint32_t start = expire_ttl_range->first;
201+
uint32_t end = expire_ttl_range->second;
202+
uint32_t expire_ttl = rand() % (end - start) + start;
203+
VLOG(1) << "set key " << key << " expire ttl as " << expire_ttl;
204+
auto cid = sf->service().mutable_registry()->Find("EXPIRE");
205+
absl::InlinedVector<string, 5> args;
206+
args.push_back(std::move(key));
207+
args.push_back(to_string(expire_ttl));
208+
args_view.clear();
209+
for (auto& arg : args) {
210+
args_view.push_back(arg);
211+
}
212+
auto args_span = absl::MakeSpan(args_view);
213+
stub_tx->MultiSwitchCmd(cid);
214+
local_cntx.cid = cid;
215+
crb.SetReplyMode(ReplyMode::NONE);
216+
stub_tx->InitByArgs(cntx->ns, local_cntx.conn_state.db_index, args_span);
217+
218+
sf->service().InvokeCmd(cid, args_span, &crb, &local_cntx);
219+
}
197220
}
198221
}
199222

@@ -536,7 +559,8 @@ void DebugCmd::Run(CmdArgList args, facade::SinkReplyBuilder* builder) {
536559
" Return sync id and array of number of journal commands executed for each replica flow",
537560
"WATCHED",
538561
" Shows the watched keys as a result of BLPOP and similar operations.",
539-
"POPULATE <count> [prefix] [size] [RAND] [SLOTS start end] [TYPE type] [ELEMENTS elements]",
562+
"POPULATE <count> [prefix] [size] [RAND] [SLOTS start end] [TYPE type] [ELEMENTS elements]"
563+
"[EXPIRE start end]",
540564
" Create <count> string keys named key:<num> with value value:<num>.",
541565
" If <prefix> is specified then it is used instead of the 'key' prefix.",
542566
" If <size> is specified then X character is concatenated multiple times to value:<num>",
@@ -545,6 +569,7 @@ void DebugCmd::Run(CmdArgList args, facade::SinkReplyBuilder* builder) {
545569
" If SLOTS is specified then create keys only in given slots range.",
546570
" TYPE specifies data type (must be STRING/LIST/SET/HASH/ZSET/JSON), default STRING.",
547571
" ELEMENTS specifies how many sub elements if relevant (like entries in a list / set).",
572+
" EXPIRE specifies key expire ttl range.",
548573
"OBJHIST",
549574
" Prints histogram of object sizes.",
550575
"STACKTRACE",
@@ -729,6 +754,9 @@ void DebugCmd::Migration(CmdArgList args, facade::SinkReplyBuilder* builder) {
729754
return builder->SendError(UnknownSubCmd("MIGRATION", "DEBUG"));
730755
}
731756

757+
// Populate arguments format:
758+
// required: (total count) (key prefix) (val size)
759+
// optional: [RAND | TYPE typename | ELEMENTS element num | SLOTS (key value)+ | EXPIRE start end]
732760
optional<DebugCmd::PopulateOptions> DebugCmd::ParsePopulateArgs(CmdArgList args,
733761
facade::SinkReplyBuilder* builder) {
734762
if (args.size() < 2) {
@@ -802,7 +830,25 @@ optional<DebugCmd::PopulateOptions> DebugCmd::ParsePopulateArgs(CmdArgList args,
802830
}
803831
options.slot_range = cluster::SlotRange{.start = static_cast<SlotId>(start.value()),
804832
.end = static_cast<SlotId>(end.value())};
805-
833+
} else if (str == "EXPIRE") {
834+
if (args.size() < index + 3) {
835+
builder->SendError(kSyntaxErr);
836+
return nullopt;
837+
}
838+
uint32_t start, end;
839+
if (!absl::SimpleAtoi(ArgS(args, ++index), &start)) {
840+
builder->SendError(kSyntaxErr);
841+
return nullopt;
842+
}
843+
if (!absl::SimpleAtoi(ArgS(args, ++index), &end)) {
844+
builder->SendError(kSyntaxErr);
845+
return nullopt;
846+
}
847+
if (start >= end) {
848+
builder->SendError(kExpiryOutOfRange);
849+
return nullopt;
850+
}
851+
options.expire_ttl_range = std::make_pair(start, end);
806852
} else {
807853
builder->SendError(kSyntaxErr);
808854
return nullopt;
@@ -889,7 +935,8 @@ void DebugCmd::PopulateRangeFiber(uint64_t from, uint64_t num_of_keys,
889935
if (shard_batch.sz == 32) {
890936
ess.Add(sid, [this, index, options, shard_batch] {
891937
DoPopulateBatch(options.type, options.prefix, options.val_size,
892-
options.populate_random_values, options.elements, shard_batch, &sf_, cntx_);
938+
options.populate_random_values, options.elements, options.expire_ttl_range,
939+
shard_batch, &sf_, cntx_);
893940
if (index % 50 == 0) {
894941
ThisFiber::Yield();
895942
}
@@ -902,7 +949,7 @@ void DebugCmd::PopulateRangeFiber(uint64_t from, uint64_t num_of_keys,
902949

903950
ess.AwaitRunningOnShardQueue([&](EngineShard* shard) {
904951
DoPopulateBatch(options.type, options.prefix, options.val_size, options.populate_random_values,
905-
options.elements, ps[shard->shard_id()], &sf_, cntx_);
952+
options.elements, options.expire_ttl_range, ps[shard->shard_id()], &sf_, cntx_);
906953
// Debug populate does not use transaction framework therefore we call OnCbFinish manually
907954
// after running the callback
908955
// Note that running debug populate while running flushall/db can cause dcheck fail because the

src/server/debugcmd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class DebugCmd {
2727
uint32_t elements = 1;
2828

2929
std::optional<cluster::SlotRange> slot_range;
30+
std::optional<std::pair<uint32_t, uint32_t>> expire_ttl_range;
3031
};
3132

3233
public:

0 commit comments

Comments
 (0)