mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2024-12-14 11:58:02 +00:00
chore: change the interface of hll, generic and list commands (#4227)
This commit is contained in:
parent
3ad5b387bd
commit
a4b3724929
5 changed files with 244 additions and 254 deletions
|
@ -995,10 +995,11 @@ OpResult<uint32_t> GenericFamily::OpDel(const OpArgs& op_args, const ShardArgs&
|
|||
return res;
|
||||
}
|
||||
|
||||
void GenericFamily::Del(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::Del(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
VLOG(1) << "Del " << ArgS(args, 0);
|
||||
|
||||
atomic_uint32_t result{0};
|
||||
auto* builder = cmd_cntx.rb;
|
||||
bool is_mc = (builder->GetProtocol() == Protocol::MEMCACHE);
|
||||
|
||||
auto cb = [&result](const Transaction* t, EngineShard* shard) {
|
||||
|
@ -1009,10 +1010,10 @@ void GenericFamily::Del(CmdArgList args, Transaction* tx, SinkReplyBuilder* buil
|
|||
return OpStatus::OK;
|
||||
};
|
||||
|
||||
OpStatus status = tx->ScheduleSingleHop(std::move(cb));
|
||||
OpStatus status = cmd_cntx.tx->ScheduleSingleHop(std::move(cb));
|
||||
CHECK_EQ(OpStatus::OK, status);
|
||||
|
||||
DVLOG(2) << "Del ts " << tx->txid();
|
||||
DVLOG(2) << "Del ts " << cmd_cntx.tx->txid();
|
||||
|
||||
uint32_t del_cnt = result.load(memory_order_relaxed);
|
||||
if (is_mc) {
|
||||
|
@ -1029,18 +1030,16 @@ void GenericFamily::Del(CmdArgList args, Transaction* tx, SinkReplyBuilder* buil
|
|||
}
|
||||
}
|
||||
|
||||
void GenericFamily::Ping(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx) {
|
||||
void GenericFamily::Ping(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
if (args.size() > 1) {
|
||||
return builder->SendError(facade::WrongNumArgsError("ping"), kSyntaxErrType);
|
||||
return rb->SendError(facade::WrongNumArgsError("ping"), kSyntaxErrType);
|
||||
}
|
||||
|
||||
string_view msg;
|
||||
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(builder);
|
||||
|
||||
// If a client in the subscribe state and in resp2 mode, it returns an array for some reason.
|
||||
if (cntx->conn_state.subscribe_info && !rb->IsResp3()) {
|
||||
if (cmd_cntx.conn_cntx->conn_state.subscribe_info && !rb->IsResp3()) {
|
||||
if (args.size() == 1) {
|
||||
msg = ArgS(args, 0);
|
||||
}
|
||||
|
@ -1050,16 +1049,16 @@ void GenericFamily::Ping(CmdArgList args, Transaction* tx, SinkReplyBuilder* bui
|
|||
}
|
||||
|
||||
if (args.size() == 0) {
|
||||
return builder->SendSimpleString("PONG");
|
||||
} else {
|
||||
return rb->SendSimpleString("PONG");
|
||||
}
|
||||
|
||||
msg = ArgS(args, 0);
|
||||
DVLOG(2) << "Ping " << msg;
|
||||
|
||||
return rb->SendBulkString(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void GenericFamily::Exists(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::Exists(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
VLOG(1) << "Exists " << ArgS(args, 0);
|
||||
|
||||
atomic_uint32_t result{0};
|
||||
|
@ -1072,28 +1071,28 @@ void GenericFamily::Exists(CmdArgList args, Transaction* tx, SinkReplyBuilder* b
|
|||
return OpStatus::OK;
|
||||
};
|
||||
|
||||
OpStatus status = tx->ScheduleSingleHop(std::move(cb));
|
||||
OpStatus status = cmd_cntx.tx->ScheduleSingleHop(std::move(cb));
|
||||
CHECK_EQ(OpStatus::OK, status);
|
||||
|
||||
return builder->SendLong(result.load(memory_order_acquire));
|
||||
return cmd_cntx.rb->SendLong(result.load(memory_order_acquire));
|
||||
}
|
||||
|
||||
void GenericFamily::Persist(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::Persist(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view key = ArgS(args, 0);
|
||||
|
||||
auto cb = [&](Transaction* t, EngineShard* shard) { return OpPersist(t->GetOpArgs(shard), key); };
|
||||
|
||||
OpStatus status = tx->ScheduleSingleHop(std::move(cb));
|
||||
builder->SendLong(status == OpStatus::OK);
|
||||
OpStatus status = cmd_cntx.tx->ScheduleSingleHop(std::move(cb));
|
||||
cmd_cntx.rb->SendLong(status == OpStatus::OK);
|
||||
}
|
||||
|
||||
void GenericFamily::Expire(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::Expire(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view key = ArgS(args, 0);
|
||||
string_view sec = ArgS(args, 1);
|
||||
int64_t int_arg;
|
||||
|
||||
if (!absl::SimpleAtoi(sec, &int_arg)) {
|
||||
return builder->SendError(kInvalidIntErr);
|
||||
return cmd_cntx.rb->SendError(kInvalidIntErr);
|
||||
}
|
||||
|
||||
int_arg = std::max<int64_t>(int_arg, -1);
|
||||
|
@ -1103,7 +1102,7 @@ void GenericFamily::Expire(CmdArgList args, Transaction* tx, SinkReplyBuilder* b
|
|||
int_arg = kMaxExpireDeadlineSec;
|
||||
}
|
||||
|
||||
auto expire_options = ParseExpireOptionsOrReply(args.subspan(2), builder);
|
||||
auto expire_options = ParseExpireOptionsOrReply(args.subspan(2), cmd_cntx.rb);
|
||||
if (!expire_options) {
|
||||
return;
|
||||
}
|
||||
|
@ -1113,21 +1112,21 @@ void GenericFamily::Expire(CmdArgList args, Transaction* tx, SinkReplyBuilder* b
|
|||
return OpExpire(t->GetOpArgs(shard), key, params);
|
||||
};
|
||||
|
||||
OpStatus status = tx->ScheduleSingleHop(std::move(cb));
|
||||
builder->SendLong(status == OpStatus::OK);
|
||||
OpStatus status = cmd_cntx.tx->ScheduleSingleHop(std::move(cb));
|
||||
cmd_cntx.rb->SendLong(status == OpStatus::OK);
|
||||
}
|
||||
|
||||
void GenericFamily::ExpireAt(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::ExpireAt(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view key = ArgS(args, 0);
|
||||
string_view sec = ArgS(args, 1);
|
||||
int64_t int_arg;
|
||||
|
||||
if (!absl::SimpleAtoi(sec, &int_arg)) {
|
||||
return builder->SendError(kInvalidIntErr);
|
||||
return cmd_cntx.rb->SendError(kInvalidIntErr);
|
||||
}
|
||||
|
||||
int_arg = std::max<int64_t>(int_arg, 0L);
|
||||
auto expire_options = ParseExpireOptionsOrReply(args.subspan(2), builder);
|
||||
auto expire_options = ParseExpireOptionsOrReply(args.subspan(2), cmd_cntx.rb);
|
||||
if (!expire_options) {
|
||||
return;
|
||||
}
|
||||
|
@ -1137,17 +1136,16 @@ void GenericFamily::ExpireAt(CmdArgList args, Transaction* tx, SinkReplyBuilder*
|
|||
auto cb = [&](Transaction* t, EngineShard* shard) {
|
||||
return OpExpire(t->GetOpArgs(shard), key, params);
|
||||
};
|
||||
OpStatus status = tx->ScheduleSingleHop(std::move(cb));
|
||||
OpStatus status = cmd_cntx.tx->ScheduleSingleHop(std::move(cb));
|
||||
|
||||
if (status == OpStatus::OUT_OF_RANGE) {
|
||||
return builder->SendError(kExpiryOutOfRange);
|
||||
return cmd_cntx.rb->SendError(kExpiryOutOfRange);
|
||||
}
|
||||
|
||||
builder->SendLong(status == OpStatus::OK);
|
||||
cmd_cntx.rb->SendLong(status == OpStatus::OK);
|
||||
}
|
||||
|
||||
void GenericFamily::Keys(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx) {
|
||||
void GenericFamily::Keys(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view pattern(ArgS(args, 0));
|
||||
uint64_t cursor = 0;
|
||||
|
||||
|
@ -1162,27 +1160,27 @@ void GenericFamily::Keys(CmdArgList args, Transaction* tx, SinkReplyBuilder* bui
|
|||
auto output_limit = absl::GetFlag(FLAGS_keys_output_limit);
|
||||
|
||||
do {
|
||||
cursor = ScanGeneric(cursor, scan_opts, &keys, cntx);
|
||||
cursor = ScanGeneric(cursor, scan_opts, &keys, cmd_cntx.conn_cntx);
|
||||
} while (cursor != 0 && keys.size() < output_limit);
|
||||
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(builder);
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
rb->StartArray(keys.size());
|
||||
for (const auto& k : keys) {
|
||||
rb->SendBulkString(k);
|
||||
}
|
||||
}
|
||||
|
||||
void GenericFamily::PexpireAt(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::PexpireAt(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view key = ArgS(args, 0);
|
||||
string_view msec = ArgS(args, 1);
|
||||
int64_t int_arg;
|
||||
|
||||
if (!absl::SimpleAtoi(msec, &int_arg)) {
|
||||
return builder->SendError(kInvalidIntErr);
|
||||
return cmd_cntx.rb->SendError(kInvalidIntErr);
|
||||
}
|
||||
|
||||
int_arg = std::max<int64_t>(int_arg, 0L);
|
||||
auto expire_options = ParseExpireOptionsOrReply(args.subspan(2), builder);
|
||||
auto expire_options = ParseExpireOptionsOrReply(args.subspan(2), cmd_cntx.rb);
|
||||
if (!expire_options) {
|
||||
return;
|
||||
}
|
||||
|
@ -1194,22 +1192,22 @@ void GenericFamily::PexpireAt(CmdArgList args, Transaction* tx, SinkReplyBuilder
|
|||
auto cb = [&](Transaction* t, EngineShard* shard) {
|
||||
return OpExpire(t->GetOpArgs(shard), key, params);
|
||||
};
|
||||
OpStatus status = tx->ScheduleSingleHop(std::move(cb));
|
||||
OpStatus status = cmd_cntx.tx->ScheduleSingleHop(std::move(cb));
|
||||
|
||||
if (status == OpStatus::OUT_OF_RANGE) {
|
||||
return builder->SendError(kExpiryOutOfRange);
|
||||
return cmd_cntx.rb->SendError(kExpiryOutOfRange);
|
||||
} else {
|
||||
builder->SendLong(status == OpStatus::OK);
|
||||
cmd_cntx.rb->SendLong(status == OpStatus::OK);
|
||||
}
|
||||
}
|
||||
|
||||
void GenericFamily::Pexpire(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::Pexpire(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view key = ArgS(args, 0);
|
||||
string_view msec = ArgS(args, 1);
|
||||
int64_t int_arg;
|
||||
|
||||
if (!absl::SimpleAtoi(msec, &int_arg)) {
|
||||
return builder->SendError(kInvalidIntErr);
|
||||
return cmd_cntx.rb->SendError(kInvalidIntErr);
|
||||
}
|
||||
int_arg = std::max<int64_t>(int_arg, -1);
|
||||
|
||||
|
@ -1218,7 +1216,7 @@ void GenericFamily::Pexpire(CmdArgList args, Transaction* tx, SinkReplyBuilder*
|
|||
int_arg = kMaxExpireDeadlineMs;
|
||||
}
|
||||
|
||||
auto expire_options = ParseExpireOptionsOrReply(args.subspan(2), builder);
|
||||
auto expire_options = ParseExpireOptionsOrReply(args.subspan(2), cmd_cntx.rb);
|
||||
if (!expire_options) {
|
||||
return;
|
||||
}
|
||||
|
@ -1228,16 +1226,16 @@ void GenericFamily::Pexpire(CmdArgList args, Transaction* tx, SinkReplyBuilder*
|
|||
auto cb = [&](Transaction* t, EngineShard* shard) {
|
||||
return OpExpire(t->GetOpArgs(shard), key, params);
|
||||
};
|
||||
OpStatus status = tx->ScheduleSingleHop(std::move(cb));
|
||||
OpStatus status = cmd_cntx.tx->ScheduleSingleHop(std::move(cb));
|
||||
|
||||
if (status == OpStatus::OUT_OF_RANGE) {
|
||||
return builder->SendError(kExpiryOutOfRange);
|
||||
return cmd_cntx.rb->SendError(kExpiryOutOfRange);
|
||||
}
|
||||
builder->SendLong(status == OpStatus::OK);
|
||||
cmd_cntx.rb->SendLong(status == OpStatus::OK);
|
||||
}
|
||||
|
||||
void GenericFamily::Stick(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
Transaction* transaction = tx;
|
||||
void GenericFamily::Stick(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
Transaction* transaction = cmd_cntx.tx;
|
||||
VLOG(1) << "Stick " << ArgS(args, 0);
|
||||
|
||||
atomic_uint32_t result{0};
|
||||
|
@ -1256,7 +1254,7 @@ void GenericFamily::Stick(CmdArgList args, Transaction* tx, SinkReplyBuilder* bu
|
|||
DVLOG(2) << "Stick ts " << transaction->txid();
|
||||
|
||||
uint32_t match_cnt = result.load(memory_order_relaxed);
|
||||
builder->SendLong(match_cnt);
|
||||
cmd_cntx.rb->SendLong(match_cnt);
|
||||
}
|
||||
|
||||
// Used to conditionally store double score
|
||||
|
@ -1377,12 +1375,12 @@ OpResultTyped<SortEntryList> OpFetchSortEntries(const OpArgs& op_args, std::stri
|
|||
return success ? res : OpStatus::INVALID_NUMERIC_RESULT;
|
||||
}
|
||||
|
||||
void GenericFamily::Sort(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::Sort(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
std::string_view key = ArgS(args, 0);
|
||||
bool alpha = false;
|
||||
bool reversed = false;
|
||||
std::optional<std::pair<size_t, size_t>> bounds;
|
||||
|
||||
auto* builder = cmd_cntx.rb;
|
||||
for (size_t i = 1; i < args.size(); i++) {
|
||||
string arg = absl::AsciiStrToUpper(ArgS(args, i));
|
||||
if (arg == "ALPHA") {
|
||||
|
@ -1409,7 +1407,7 @@ void GenericFamily::Sort(CmdArgList args, Transaction* tx, SinkReplyBuilder* bui
|
|||
}
|
||||
|
||||
OpResultTyped<SortEntryList> fetch_result =
|
||||
tx->ScheduleSingleHopT([&](Transaction* t, EngineShard* shard) {
|
||||
cmd_cntx.tx->ScheduleSingleHopT([&](Transaction* t, EngineShard* shard) {
|
||||
return OpFetchSortEntries(t->GetOpArgs(shard), key, alpha);
|
||||
});
|
||||
|
||||
|
@ -1454,11 +1452,12 @@ void GenericFamily::Sort(CmdArgList args, Transaction* tx, SinkReplyBuilder* bui
|
|||
std::visit(std::move(sort_call), fetch_result.value());
|
||||
}
|
||||
|
||||
void GenericFamily::Restore(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::Restore(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
std::string_view key = ArgS(args, 0);
|
||||
std::string_view serialized_value = ArgS(args, 2);
|
||||
|
||||
auto rdb_version = GetRdbVersion(serialized_value);
|
||||
auto* builder = cmd_cntx.rb;
|
||||
if (!rdb_version) {
|
||||
return builder->SendError(kInvalidDumpValueErr);
|
||||
}
|
||||
|
@ -1477,7 +1476,7 @@ void GenericFamily::Restore(CmdArgList args, Transaction* tx, SinkReplyBuilder*
|
|||
rdb_version.value());
|
||||
};
|
||||
|
||||
OpResult<bool> result = tx->ScheduleSingleHopT(std::move(cb));
|
||||
OpResult<bool> result = cmd_cntx.tx->ScheduleSingleHopT(std::move(cb));
|
||||
|
||||
if (result) {
|
||||
if (result.value()) {
|
||||
|
@ -1492,13 +1491,14 @@ void GenericFamily::Restore(CmdArgList args, Transaction* tx, SinkReplyBuilder*
|
|||
}
|
||||
}
|
||||
|
||||
void GenericFamily::FieldExpire(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::FieldExpire(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
CmdArgParser parser{args};
|
||||
string_view key = parser.Next();
|
||||
string_view ttl_str = parser.Next();
|
||||
uint32_t ttl_sec;
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
if (!absl::SimpleAtoi(ttl_str, &ttl_sec) || ttl_sec == 0 || ttl_sec > kMaxTtl) {
|
||||
return builder->SendError(kInvalidIntErr);
|
||||
return rb->SendError(kInvalidIntErr);
|
||||
}
|
||||
CmdArgList fields = parser.Tail();
|
||||
|
||||
|
@ -1506,8 +1506,8 @@ void GenericFamily::FieldExpire(CmdArgList args, Transaction* tx, SinkReplyBuild
|
|||
return OpFieldExpire(t->GetOpArgs(shard), key, ttl_sec, fields);
|
||||
};
|
||||
|
||||
OpResult<vector<long>> result = tx->ScheduleSingleHopT(std::move(cb));
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(builder);
|
||||
OpResult<vector<long>> result = cmd_cntx.tx->ScheduleSingleHopT(std::move(cb));
|
||||
|
||||
if (result) {
|
||||
rb->StartArray(result->size());
|
||||
const auto& array = result.value();
|
||||
|
@ -1515,33 +1515,33 @@ void GenericFamily::FieldExpire(CmdArgList args, Transaction* tx, SinkReplyBuild
|
|||
rb->SendLong(v);
|
||||
}
|
||||
} else {
|
||||
builder->SendError(result.status());
|
||||
rb->SendError(result.status());
|
||||
}
|
||||
}
|
||||
|
||||
// Returns -2 if key not found, WRONG_TYPE if key is not a set or hash
|
||||
// -1 if the field does not have associated TTL on it, and -3 if field is not found.
|
||||
void GenericFamily::FieldTtl(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::FieldTtl(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view key = ArgS(args, 0);
|
||||
string_view field = ArgS(args, 1);
|
||||
|
||||
auto cb = [&](Transaction* t, EngineShard* shard) { return OpFieldTtl(t, shard, key, field); };
|
||||
|
||||
OpResult<long> result = tx->ScheduleSingleHopT(std::move(cb));
|
||||
OpResult<long> result = cmd_cntx.tx->ScheduleSingleHopT(std::move(cb));
|
||||
|
||||
if (result) {
|
||||
builder->SendLong(*result);
|
||||
cmd_cntx.rb->SendLong(*result);
|
||||
return;
|
||||
}
|
||||
|
||||
builder->SendError(result.status());
|
||||
cmd_cntx.rb->SendError(result.status());
|
||||
}
|
||||
|
||||
void GenericFamily::Move(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::Move(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view key = ArgS(args, 0);
|
||||
string_view target_db_sv = ArgS(args, 1);
|
||||
int32_t target_db;
|
||||
|
||||
auto* builder = cmd_cntx.rb;
|
||||
if (!absl::SimpleAtoi(target_db_sv, &target_db)) {
|
||||
return builder->SendError(kInvalidIntErr);
|
||||
}
|
||||
|
@ -1550,7 +1550,7 @@ void GenericFamily::Move(CmdArgList args, Transaction* tx, SinkReplyBuilder* bui
|
|||
return builder->SendError(kDbIndOutOfRangeErr);
|
||||
}
|
||||
|
||||
if (target_db == tx->GetDbIndex()) {
|
||||
if (target_db == cmd_cntx.tx->GetDbIndex()) {
|
||||
return builder->SendError("source and destination objects are the same");
|
||||
}
|
||||
|
||||
|
@ -1570,20 +1570,20 @@ void GenericFamily::Move(CmdArgList args, Transaction* tx, SinkReplyBuilder* bui
|
|||
return OpStatus::OK;
|
||||
};
|
||||
|
||||
tx->ScheduleSingleHop(std::move(cb));
|
||||
cmd_cntx.tx->ScheduleSingleHop(std::move(cb));
|
||||
// Exactly one shard will call OpMove.
|
||||
DCHECK(res != OpStatus::SKIPPED);
|
||||
builder->SendLong(res == OpStatus::OK);
|
||||
}
|
||||
|
||||
void GenericFamily::Rename(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
auto reply = RenameGeneric(args, false, tx);
|
||||
builder->SendError(reply);
|
||||
void GenericFamily::Rename(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
auto reply = RenameGeneric(args, false, cmd_cntx.tx);
|
||||
cmd_cntx.rb->SendError(reply);
|
||||
}
|
||||
|
||||
void GenericFamily::RenameNx(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
auto reply = RenameGeneric(args, true, tx);
|
||||
|
||||
void GenericFamily::RenameNx(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
auto reply = RenameGeneric(args, true, cmd_cntx.tx);
|
||||
auto* builder = cmd_cntx.rb;
|
||||
if (!reply.status) {
|
||||
builder->SendError(reply);
|
||||
return;
|
||||
|
@ -1599,26 +1599,26 @@ void GenericFamily::RenameNx(CmdArgList args, Transaction* tx, SinkReplyBuilder*
|
|||
}
|
||||
}
|
||||
|
||||
void GenericFamily::ExpireTime(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
ExpireTimeGeneric(args, TimeUnit::SEC, tx, builder);
|
||||
void GenericFamily::ExpireTime(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
ExpireTimeGeneric(args, TimeUnit::SEC, cmd_cntx.tx, cmd_cntx.rb);
|
||||
}
|
||||
|
||||
void GenericFamily::PExpireTime(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
ExpireTimeGeneric(args, TimeUnit::MSEC, tx, builder);
|
||||
void GenericFamily::PExpireTime(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
ExpireTimeGeneric(args, TimeUnit::MSEC, cmd_cntx.tx, cmd_cntx.rb);
|
||||
}
|
||||
|
||||
void GenericFamily::Ttl(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
TtlGeneric(args, TimeUnit::SEC, tx, builder);
|
||||
void GenericFamily::Ttl(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
TtlGeneric(args, TimeUnit::SEC, cmd_cntx.tx, cmd_cntx.rb);
|
||||
}
|
||||
|
||||
void GenericFamily::Pttl(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
TtlGeneric(args, TimeUnit::MSEC, tx, builder);
|
||||
void GenericFamily::Pttl(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
TtlGeneric(args, TimeUnit::MSEC, cmd_cntx.tx, cmd_cntx.rb);
|
||||
}
|
||||
|
||||
void GenericFamily::Select(CmdArgList args, Transaction*, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx) {
|
||||
void GenericFamily::Select(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view key = ArgS(args, 0);
|
||||
int64_t index;
|
||||
auto* builder = cmd_cntx.rb;
|
||||
if (!absl::SimpleAtoi(key, &index)) {
|
||||
return builder->SendError(kInvalidDbIndErr);
|
||||
}
|
||||
|
@ -1628,7 +1628,7 @@ void GenericFamily::Select(CmdArgList args, Transaction*, SinkReplyBuilder* buil
|
|||
if (index < 0 || index >= absl::GetFlag(FLAGS_dbnum)) {
|
||||
return builder->SendError(kDbIndOutOfRangeErr);
|
||||
}
|
||||
|
||||
auto* cntx = cmd_cntx.conn_cntx;
|
||||
if (cntx->conn_state.db_index == index) {
|
||||
// accept a noop.
|
||||
return builder->SendOk();
|
||||
|
@ -1649,22 +1649,23 @@ void GenericFamily::Select(CmdArgList args, Transaction*, SinkReplyBuilder* buil
|
|||
return builder->SendOk();
|
||||
}
|
||||
|
||||
void GenericFamily::Dump(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::Dump(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
std::string_view key = ArgS(args, 0);
|
||||
DVLOG(1) << "Dumping before ::ScheduleSingleHopT " << key;
|
||||
auto cb = [&](Transaction* t, EngineShard* shard) { return OpDump(t->GetOpArgs(shard), key); };
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
OpResult<string> result = cmd_cntx.tx->ScheduleSingleHopT(std::move(cb));
|
||||
|
||||
OpResult<string> result = tx->ScheduleSingleHopT(std::move(cb));
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(builder);
|
||||
if (result) {
|
||||
DVLOG(1) << "Dump " << tx->DebugId() << ": " << key << ", dump size " << result.value().size();
|
||||
DVLOG(1) << "Dump " << cmd_cntx.tx->DebugId() << ": " << key << ", dump size "
|
||||
<< result.value().size();
|
||||
rb->SendBulkString(*result);
|
||||
} else {
|
||||
rb->SendNull();
|
||||
}
|
||||
}
|
||||
|
||||
void GenericFamily::Type(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::Type(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
std::string_view key = ArgS(args, 0);
|
||||
|
||||
auto cb = [&](Transaction* t, EngineShard* shard) -> OpResult<CompactObjType> {
|
||||
|
@ -1676,40 +1677,39 @@ void GenericFamily::Type(CmdArgList args, Transaction* tx, SinkReplyBuilder* bui
|
|||
return OpStatus::KEY_NOTFOUND;
|
||||
}
|
||||
};
|
||||
OpResult<CompactObjType> result = tx->ScheduleSingleHopT(std::move(cb));
|
||||
OpResult<CompactObjType> result = cmd_cntx.tx->ScheduleSingleHopT(std::move(cb));
|
||||
if (!result) {
|
||||
builder->SendSimpleString("none");
|
||||
cmd_cntx.rb->SendSimpleString("none");
|
||||
} else {
|
||||
builder->SendSimpleString(ObjTypeToString(result.value()));
|
||||
cmd_cntx.rb->SendSimpleString(ObjTypeToString(result.value()));
|
||||
}
|
||||
}
|
||||
|
||||
void GenericFamily::Time(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::Time(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
uint64_t now_usec;
|
||||
if (tx) {
|
||||
now_usec = tx->GetDbContext().time_now_ms * 1000;
|
||||
if (cmd_cntx.tx) {
|
||||
now_usec = cmd_cntx.tx->GetDbContext().time_now_ms * 1000;
|
||||
} else {
|
||||
now_usec = absl::GetCurrentTimeNanos() / 1000;
|
||||
}
|
||||
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(builder);
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
rb->StartArray(2);
|
||||
rb->SendLong(now_usec / 1000000);
|
||||
rb->SendLong(now_usec % 1000000);
|
||||
}
|
||||
|
||||
void GenericFamily::Echo(CmdArgList args, Transaction*, SinkReplyBuilder* builder) {
|
||||
void GenericFamily::Echo(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view key = ArgS(args, 0);
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(builder);
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
return rb->SendBulkString(key);
|
||||
}
|
||||
|
||||
// SCAN cursor [MATCH <glob>] [TYPE <type>] [COUNT <count>] [BUCKET <bucket_id>]
|
||||
void GenericFamily::Scan(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx) {
|
||||
void GenericFamily::Scan(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view token = ArgS(args, 0);
|
||||
uint64_t cursor = 0;
|
||||
|
||||
auto* builder = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
if (!absl::SimpleAtoi(token, &cursor)) {
|
||||
return builder->SendError("invalid cursor");
|
||||
}
|
||||
|
@ -1723,14 +1723,13 @@ void GenericFamily::Scan(CmdArgList args, Transaction* tx, SinkReplyBuilder* bui
|
|||
ScanOpts scan_op = ops.value();
|
||||
|
||||
StringVec keys;
|
||||
cursor = ScanGeneric(cursor, scan_op, &keys, cntx);
|
||||
cursor = ScanGeneric(cursor, scan_op, &keys, cmd_cntx.conn_cntx);
|
||||
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(builder);
|
||||
rb->StartArray(2);
|
||||
rb->SendBulkString(absl::StrCat(cursor));
|
||||
rb->StartArray(keys.size());
|
||||
builder->StartArray(2);
|
||||
builder->SendBulkString(absl::StrCat(cursor));
|
||||
builder->StartArray(keys.size());
|
||||
for (const auto& k : keys) {
|
||||
rb->SendBulkString(k);
|
||||
builder->SendBulkString(k);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1746,12 +1745,12 @@ OpResult<uint32_t> GenericFamily::OpExists(const OpArgs& op_args, const ShardArg
|
|||
return res;
|
||||
}
|
||||
|
||||
void GenericFamily::RandomKey(CmdArgList args, Transaction*, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx) {
|
||||
void GenericFamily::RandomKey(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
const static size_t kMaxAttempts = 3;
|
||||
|
||||
absl::BitGen bitgen;
|
||||
atomic_size_t candidates_counter{0};
|
||||
auto* cntx = cmd_cntx.conn_cntx;
|
||||
DbContext db_cntx{cntx->ns, cntx->conn_state.db_index, GetCurrentTimeMs()};
|
||||
ScanOpts scan_opts;
|
||||
scan_opts.limit = 3; // number of entries per shard
|
||||
|
@ -1785,7 +1784,7 @@ void GenericFamily::RandomKey(CmdArgList args, Transaction*, SinkReplyBuilder* b
|
|||
auto candidates_count = candidates_counter.load(memory_order_relaxed);
|
||||
std::optional<string> random_key = std::nullopt;
|
||||
auto random_idx = absl::Uniform<size_t>(bitgen, 0, candidates_count);
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(builder);
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
for (const auto& candidate : candidates_collection) {
|
||||
if (random_idx >= candidate.size()) {
|
||||
random_idx -= candidate.size();
|
||||
|
|
|
@ -22,6 +22,7 @@ using facade::OpResult;
|
|||
class ConnectionContext;
|
||||
class CommandRegistry;
|
||||
class Transaction;
|
||||
struct CommandContext;
|
||||
|
||||
class GenericFamily {
|
||||
public:
|
||||
|
@ -34,41 +35,36 @@ class GenericFamily {
|
|||
private:
|
||||
using SinkReplyBuilder = facade::SinkReplyBuilder;
|
||||
|
||||
static void Del(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Ping(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx);
|
||||
static void Exists(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Expire(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void ExpireAt(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Persist(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Keys(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx);
|
||||
static void PexpireAt(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Pexpire(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Stick(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Sort(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Move(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Del(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Ping(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Exists(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Expire(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void ExpireAt(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Persist(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Keys(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void PexpireAt(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Pexpire(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Stick(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Sort(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Move(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
|
||||
static void Rename(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void RenameNx(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void ExpireTime(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void PExpireTime(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Ttl(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Pttl(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Rename(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void RenameNx(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void ExpireTime(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void PExpireTime(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Ttl(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Pttl(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
|
||||
static void Echo(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Select(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx);
|
||||
static void Scan(CmdArgList args, Transaction*, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx);
|
||||
static void Time(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Type(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Dump(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Restore(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void RandomKey(CmdArgList args, Transaction*, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx);
|
||||
static void FieldTtl(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void FieldExpire(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void Echo(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Select(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Scan(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Time(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Type(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Dump(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void Restore(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void RandomKey(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void FieldTtl(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void FieldExpire(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
};
|
||||
|
||||
} // namespace dfly
|
||||
|
|
|
@ -125,7 +125,7 @@ OpResult<int> AddToHll(const OpArgs& op_args, string_view key, CmdArgList values
|
|||
return std::min(updated, 1);
|
||||
}
|
||||
|
||||
void PFAdd(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void PFAdd(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view key = ArgS(args, 0);
|
||||
args.remove_prefix(1);
|
||||
|
||||
|
@ -133,8 +133,8 @@ void PFAdd(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
|||
return AddToHll(t->GetOpArgs(shard), key, args);
|
||||
};
|
||||
|
||||
OpResult<int> res = tx->ScheduleSingleHopT(std::move(cb));
|
||||
HandleOpValueResult(res, builder);
|
||||
OpResult<int> res = cmd_cntx.tx->ScheduleSingleHopT(std::move(cb));
|
||||
HandleOpValueResult(res, cmd_cntx.rb);
|
||||
}
|
||||
|
||||
OpResult<int64_t> CountHllsSingle(const OpArgs& op_args, string_view key) {
|
||||
|
@ -204,7 +204,7 @@ vector<HllBufferPtr> ConvertShardVector(const vector<vector<string>>& hlls) {
|
|||
return ptrs;
|
||||
}
|
||||
|
||||
OpResult<int64_t> PFCountMulti(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
OpResult<int64_t> PFCountMulti(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
vector<vector<string>> hlls;
|
||||
hlls.resize(shard_set->size());
|
||||
|
||||
|
@ -218,7 +218,7 @@ OpResult<int64_t> PFCountMulti(CmdArgList args, Transaction* tx, SinkReplyBuilde
|
|||
return result.status();
|
||||
};
|
||||
|
||||
tx->ScheduleSingleHop(std::move(cb));
|
||||
cmd_cntx.tx->ScheduleSingleHop(std::move(cb));
|
||||
|
||||
vector<HllBufferPtr> ptrs = ConvertShardVector(hlls);
|
||||
int64_t pf_count = pfcountMulti(ptrs.data(), ptrs.size());
|
||||
|
@ -229,17 +229,17 @@ OpResult<int64_t> PFCountMulti(CmdArgList args, Transaction* tx, SinkReplyBuilde
|
|||
}
|
||||
}
|
||||
|
||||
void PFCount(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void PFCount(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
if (args.size() == 1) {
|
||||
string_view key = ArgS(args, 0);
|
||||
auto cb = [&](Transaction* t, EngineShard* shard) {
|
||||
return CountHllsSingle(t->GetOpArgs(shard), key);
|
||||
};
|
||||
|
||||
OpResult<int64_t> res = tx->ScheduleSingleHopT(std::move(cb));
|
||||
HandleOpValueResult(res, builder);
|
||||
OpResult<int64_t> res = cmd_cntx.tx->ScheduleSingleHopT(std::move(cb));
|
||||
HandleOpValueResult(res, cmd_cntx.rb);
|
||||
} else {
|
||||
HandleOpValueResult(PFCountMulti(args, tx, builder), builder);
|
||||
HandleOpValueResult(PFCountMulti(args, cmd_cntx), cmd_cntx.rb);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -909,19 +909,18 @@ void MoveGeneric(string_view src, string_view dest, ListDir src_dir, ListDir des
|
|||
}
|
||||
}
|
||||
|
||||
void RPopLPush(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void RPopLPush(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view src = ArgS(args, 0);
|
||||
string_view dest = ArgS(args, 1);
|
||||
|
||||
MoveGeneric(src, dest, ListDir::RIGHT, ListDir::LEFT, tx, builder);
|
||||
MoveGeneric(src, dest, ListDir::RIGHT, ListDir::LEFT, cmd_cntx.tx, cmd_cntx.rb);
|
||||
}
|
||||
|
||||
void BRPopLPush(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx) {
|
||||
void BRPopLPush(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
facade::CmdArgParser parser{args};
|
||||
auto [src, dest] = parser.Next<string_view, string_view>();
|
||||
float timeout = parser.Next<float>();
|
||||
|
||||
auto* builder = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
if (auto err = parser.Error(); err)
|
||||
return builder->SendError(err->MakeReply());
|
||||
|
||||
|
@ -929,17 +928,17 @@ void BRPopLPush(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder,
|
|||
return builder->SendError("timeout is negative");
|
||||
|
||||
BPopPusher bpop_pusher(src, dest, ListDir::RIGHT, ListDir::LEFT);
|
||||
OpResult<string> op_res = bpop_pusher.Run(unsigned(timeout * 1000), tx, cntx);
|
||||
OpResult<string> op_res =
|
||||
bpop_pusher.Run(unsigned(timeout * 1000), cmd_cntx.tx, cmd_cntx.conn_cntx);
|
||||
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(builder);
|
||||
if (op_res) {
|
||||
return rb->SendBulkString(*op_res);
|
||||
return builder->SendBulkString(*op_res);
|
||||
}
|
||||
|
||||
switch (op_res.status()) {
|
||||
case OpStatus::CANCELLED:
|
||||
case OpStatus::TIMED_OUT:
|
||||
return rb->SendNull();
|
||||
return builder->SendNull();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -948,13 +947,13 @@ void BRPopLPush(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder,
|
|||
}
|
||||
}
|
||||
|
||||
void BLMove(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder, ConnectionContext* cntx) {
|
||||
void BLMove(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
facade::CmdArgParser parser{args};
|
||||
auto [src, dest] = parser.Next<string_view, string_view>();
|
||||
ListDir src_dir = ParseDir(&parser);
|
||||
ListDir dest_dir = ParseDir(&parser);
|
||||
float timeout = parser.Next<float>();
|
||||
|
||||
auto* builder = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
if (auto err = parser.Error(); err)
|
||||
return builder->SendError(err->MakeReply());
|
||||
|
||||
|
@ -962,17 +961,17 @@ void BLMove(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder, Connect
|
|||
return builder->SendError("timeout is negative");
|
||||
|
||||
BPopPusher bpop_pusher(src, dest, src_dir, dest_dir);
|
||||
OpResult<string> op_res = bpop_pusher.Run(unsigned(timeout * 1000), tx, cntx);
|
||||
OpResult<string> op_res =
|
||||
bpop_pusher.Run(unsigned(timeout * 1000), cmd_cntx.tx, cmd_cntx.conn_cntx);
|
||||
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(builder);
|
||||
if (op_res) {
|
||||
return rb->SendBulkString(*op_res);
|
||||
return builder->SendBulkString(*op_res);
|
||||
}
|
||||
|
||||
switch (op_res.status()) {
|
||||
case OpStatus::CANCELLED:
|
||||
case OpStatus::TIMED_OUT:
|
||||
return rb->SendNull();
|
||||
return builder->SendNull();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1176,44 +1175,44 @@ void BPopGeneric(ListDir dir, CmdArgList args, Transaction* tx, SinkReplyBuilder
|
|||
|
||||
} // namespace
|
||||
|
||||
void ListFamily::LPush(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
return PushGeneric(ListDir::LEFT, false, std::move(args), tx, builder);
|
||||
void ListFamily::LPush(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
return PushGeneric(ListDir::LEFT, false, std::move(args), cmd_cntx.tx, cmd_cntx.rb);
|
||||
}
|
||||
|
||||
void ListFamily::LPushX(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
return PushGeneric(ListDir::LEFT, true, std::move(args), tx, builder);
|
||||
void ListFamily::LPushX(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
return PushGeneric(ListDir::LEFT, true, std::move(args), cmd_cntx.tx, cmd_cntx.rb);
|
||||
}
|
||||
|
||||
void ListFamily::LPop(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
return PopGeneric(ListDir::LEFT, std::move(args), tx, builder);
|
||||
void ListFamily::LPop(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
return PopGeneric(ListDir::LEFT, std::move(args), cmd_cntx.tx, cmd_cntx.rb);
|
||||
}
|
||||
|
||||
void ListFamily::RPush(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
return PushGeneric(ListDir::RIGHT, false, std::move(args), tx, builder);
|
||||
void ListFamily::RPush(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
return PushGeneric(ListDir::RIGHT, false, std::move(args), cmd_cntx.tx, cmd_cntx.rb);
|
||||
}
|
||||
|
||||
void ListFamily::RPushX(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
return PushGeneric(ListDir::RIGHT, true, std::move(args), tx, builder);
|
||||
void ListFamily::RPushX(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
return PushGeneric(ListDir::RIGHT, true, std::move(args), cmd_cntx.tx, cmd_cntx.rb);
|
||||
}
|
||||
|
||||
void ListFamily::RPop(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
return PopGeneric(ListDir::RIGHT, std::move(args), tx, builder);
|
||||
void ListFamily::RPop(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
return PopGeneric(ListDir::RIGHT, std::move(args), cmd_cntx.tx, cmd_cntx.rb);
|
||||
}
|
||||
|
||||
void ListFamily::LLen(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void ListFamily::LLen(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
auto key = ArgS(args, 0);
|
||||
auto cb = [&](Transaction* t, EngineShard* shard) { return OpLen(t->GetOpArgs(shard), key); };
|
||||
OpResult<uint32_t> result = tx->ScheduleSingleHopT(std::move(cb));
|
||||
OpResult<uint32_t> result = cmd_cntx.tx->ScheduleSingleHopT(std::move(cb));
|
||||
if (result) {
|
||||
builder->SendLong(result.value());
|
||||
cmd_cntx.rb->SendLong(result.value());
|
||||
} else if (result.status() == OpStatus::KEY_NOTFOUND) {
|
||||
builder->SendLong(0);
|
||||
cmd_cntx.rb->SendLong(0);
|
||||
} else {
|
||||
builder->SendError(result.status());
|
||||
cmd_cntx.rb->SendError(result.status());
|
||||
}
|
||||
}
|
||||
|
||||
void ListFamily::LPos(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void ListFamily::LPos(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
facade::CmdArgParser parser{args};
|
||||
auto [key, elem] = parser.Next<string_view, string_view>();
|
||||
|
||||
|
@ -1242,26 +1241,26 @@ void ListFamily::LPos(CmdArgList args, Transaction* tx, SinkReplyBuilder* builde
|
|||
parser.Skip(1);
|
||||
}
|
||||
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
if (rank == 0)
|
||||
return builder->SendError(kInvalidIntErr);
|
||||
return rb->SendError(kInvalidIntErr);
|
||||
|
||||
if (auto err = parser.Error(); err)
|
||||
return builder->SendError(err->MakeReply());
|
||||
return rb->SendError(err->MakeReply());
|
||||
|
||||
auto cb = [&](Transaction* t, EngineShard* shard) {
|
||||
return OpPos(t->GetOpArgs(shard), key, elem, rank, count, max_len);
|
||||
};
|
||||
|
||||
Transaction* trans = tx;
|
||||
Transaction* trans = cmd_cntx.tx;
|
||||
OpResult<vector<uint32_t>> result = trans->ScheduleSingleHopT(std::move(cb));
|
||||
|
||||
if (result.status() == OpStatus::WRONG_TYPE) {
|
||||
return builder->SendError(result.status());
|
||||
return rb->SendError(result.status());
|
||||
} else if (result.status() == OpStatus::INVALID_VALUE) {
|
||||
return builder->SendError(result.status());
|
||||
return rb->SendError(result.status());
|
||||
}
|
||||
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(builder);
|
||||
if (skip_count) {
|
||||
if (result->empty()) {
|
||||
rb->SendNull();
|
||||
|
@ -1269,7 +1268,7 @@ void ListFamily::LPos(CmdArgList args, Transaction* tx, SinkReplyBuilder* builde
|
|||
rb->SendLong((*result)[0]);
|
||||
}
|
||||
} else {
|
||||
SinkReplyBuilder::ReplyAggregator agg(builder);
|
||||
SinkReplyBuilder::ReplyAggregator agg(rb);
|
||||
rb->StartArray(result->size());
|
||||
const auto& array = result.value();
|
||||
for (const auto& v : array) {
|
||||
|
@ -1278,12 +1277,14 @@ void ListFamily::LPos(CmdArgList args, Transaction* tx, SinkReplyBuilder* builde
|
|||
}
|
||||
}
|
||||
|
||||
void ListFamily::LIndex(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void ListFamily::LIndex(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
std::string_view key = ArgS(args, 0);
|
||||
std::string_view index_str = ArgS(args, 1);
|
||||
int32_t index;
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
|
||||
if (!absl::SimpleAtoi(index_str, &index)) {
|
||||
builder->SendError(kInvalidIntErr);
|
||||
rb->SendError(kInvalidIntErr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1291,26 +1292,25 @@ void ListFamily::LIndex(CmdArgList args, Transaction* tx, SinkReplyBuilder* buil
|
|||
return OpIndex(t->GetOpArgs(shard), key, index);
|
||||
};
|
||||
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(builder);
|
||||
OpResult<string> result = tx->ScheduleSingleHopT(std::move(cb));
|
||||
OpResult<string> result = cmd_cntx.tx->ScheduleSingleHopT(std::move(cb));
|
||||
if (result) {
|
||||
rb->SendBulkString(result.value());
|
||||
} else if (result.status() == OpStatus::WRONG_TYPE) {
|
||||
builder->SendError(result.status());
|
||||
rb->SendError(result.status());
|
||||
} else {
|
||||
rb->SendNull();
|
||||
}
|
||||
}
|
||||
|
||||
/* LINSERT <key> (BEFORE|AFTER) <pivot> <element> */
|
||||
void ListFamily::LInsert(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void ListFamily::LInsert(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
facade::CmdArgParser parser{args};
|
||||
string_view key = parser.Next();
|
||||
InsertParam where = parser.MapNext("AFTER", INSERT_AFTER, "BEFORE", INSERT_BEFORE);
|
||||
auto [pivot, elem] = parser.Next<string_view, string_view>();
|
||||
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
if (auto err = parser.Error(); err)
|
||||
return builder->SendError(err->MakeReply());
|
||||
return rb->SendError(err->MakeReply());
|
||||
|
||||
DCHECK(pivot.data() && elem.data());
|
||||
|
||||
|
@ -1318,42 +1318,43 @@ void ListFamily::LInsert(CmdArgList args, Transaction* tx, SinkReplyBuilder* bui
|
|||
return OpInsert(t->GetOpArgs(shard), key, pivot, elem, where);
|
||||
};
|
||||
|
||||
OpResult<int> result = tx->ScheduleSingleHopT(std::move(cb));
|
||||
OpResult<int> result = cmd_cntx.tx->ScheduleSingleHopT(std::move(cb));
|
||||
if (result || result == OpStatus::KEY_NOTFOUND) {
|
||||
return builder->SendLong(result.value_or(0));
|
||||
return rb->SendLong(result.value_or(0));
|
||||
}
|
||||
|
||||
builder->SendError(result.status());
|
||||
rb->SendError(result.status());
|
||||
}
|
||||
|
||||
void ListFamily::LTrim(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void ListFamily::LTrim(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
string_view key = ArgS(args, 0);
|
||||
string_view s_str = ArgS(args, 1);
|
||||
string_view e_str = ArgS(args, 2);
|
||||
int32_t start, end;
|
||||
|
||||
if (!absl::SimpleAtoi(s_str, &start) || !absl::SimpleAtoi(e_str, &end)) {
|
||||
builder->SendError(kInvalidIntErr);
|
||||
cmd_cntx.rb->SendError(kInvalidIntErr);
|
||||
return;
|
||||
}
|
||||
|
||||
auto cb = [&](Transaction* t, EngineShard* shard) {
|
||||
return OpTrim(t->GetOpArgs(shard), key, start, end);
|
||||
};
|
||||
OpStatus st = tx->ScheduleSingleHop(std::move(cb));
|
||||
OpStatus st = cmd_cntx.tx->ScheduleSingleHop(std::move(cb));
|
||||
if (st == OpStatus::KEY_NOTFOUND)
|
||||
st = OpStatus::OK;
|
||||
builder->SendError(st);
|
||||
cmd_cntx.rb->SendError(st);
|
||||
}
|
||||
|
||||
void ListFamily::LRange(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void ListFamily::LRange(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
std::string_view key = ArgS(args, 0);
|
||||
std::string_view s_str = ArgS(args, 1);
|
||||
std::string_view e_str = ArgS(args, 2);
|
||||
int32_t start, end;
|
||||
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(cmd_cntx.rb);
|
||||
if (!absl::SimpleAtoi(s_str, &start) || !absl::SimpleAtoi(e_str, &end)) {
|
||||
builder->SendError(kInvalidIntErr);
|
||||
rb->SendError(kInvalidIntErr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1361,79 +1362,76 @@ void ListFamily::LRange(CmdArgList args, Transaction* tx, SinkReplyBuilder* buil
|
|||
return OpRange(t->GetOpArgs(shard), key, start, end);
|
||||
};
|
||||
|
||||
auto res = tx->ScheduleSingleHopT(std::move(cb));
|
||||
auto res = cmd_cntx.tx->ScheduleSingleHopT(std::move(cb));
|
||||
if (!res && res.status() != OpStatus::KEY_NOTFOUND) {
|
||||
return builder->SendError(res.status());
|
||||
return rb->SendError(res.status());
|
||||
}
|
||||
|
||||
auto* rb = static_cast<RedisReplyBuilder*>(builder);
|
||||
rb->SendBulkStrArr(*res);
|
||||
}
|
||||
|
||||
// lrem key 5 foo, will remove foo elements from the list if exists at most 5 times.
|
||||
void ListFamily::LRem(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void ListFamily::LRem(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
std::string_view key = ArgS(args, 0);
|
||||
std::string_view index_str = ArgS(args, 1);
|
||||
std::string_view elem = ArgS(args, 2);
|
||||
int32_t count;
|
||||
|
||||
if (!absl::SimpleAtoi(index_str, &count)) {
|
||||
builder->SendError(kInvalidIntErr);
|
||||
cmd_cntx.rb->SendError(kInvalidIntErr);
|
||||
return;
|
||||
}
|
||||
|
||||
auto cb = [&](Transaction* t, EngineShard* shard) {
|
||||
return OpRem(t->GetOpArgs(shard), key, elem, count);
|
||||
};
|
||||
OpResult<uint32_t> result = tx->ScheduleSingleHopT(std::move(cb));
|
||||
OpResult<uint32_t> result = cmd_cntx.tx->ScheduleSingleHopT(std::move(cb));
|
||||
if (result || result == OpStatus::KEY_NOTFOUND) {
|
||||
return builder->SendLong(result.value_or(0));
|
||||
return cmd_cntx.rb->SendLong(result.value_or(0));
|
||||
}
|
||||
builder->SendError(result.status());
|
||||
cmd_cntx.rb->SendError(result.status());
|
||||
}
|
||||
|
||||
void ListFamily::LSet(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void ListFamily::LSet(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
std::string_view key = ArgS(args, 0);
|
||||
std::string_view index_str = ArgS(args, 1);
|
||||
std::string_view elem = ArgS(args, 2);
|
||||
int32_t count;
|
||||
|
||||
if (!absl::SimpleAtoi(index_str, &count)) {
|
||||
builder->SendError(kInvalidIntErr);
|
||||
cmd_cntx.rb->SendError(kInvalidIntErr);
|
||||
return;
|
||||
}
|
||||
|
||||
auto cb = [&](Transaction* t, EngineShard* shard) {
|
||||
return OpSet(t->GetOpArgs(shard), key, elem, count);
|
||||
};
|
||||
OpResult<void> result = tx->ScheduleSingleHop(std::move(cb));
|
||||
OpResult<void> result = cmd_cntx.tx->ScheduleSingleHop(std::move(cb));
|
||||
if (result) {
|
||||
builder->SendOk();
|
||||
cmd_cntx.rb->SendOk();
|
||||
} else {
|
||||
builder->SendError(result.status());
|
||||
cmd_cntx.rb->SendError(result.status());
|
||||
}
|
||||
}
|
||||
|
||||
void ListFamily::BLPop(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx) {
|
||||
BPopGeneric(ListDir::LEFT, std::move(args), tx, builder, cntx);
|
||||
void ListFamily::BLPop(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
BPopGeneric(ListDir::LEFT, std::move(args), cmd_cntx.tx, cmd_cntx.rb, cmd_cntx.conn_cntx);
|
||||
}
|
||||
|
||||
void ListFamily::BRPop(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx) {
|
||||
BPopGeneric(ListDir::RIGHT, std::move(args), tx, builder, cntx);
|
||||
void ListFamily::BRPop(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
BPopGeneric(ListDir::RIGHT, std::move(args), cmd_cntx.tx, cmd_cntx.rb, cmd_cntx.conn_cntx);
|
||||
}
|
||||
|
||||
void ListFamily::LMove(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder) {
|
||||
void ListFamily::LMove(CmdArgList args, const CommandContext& cmd_cntx) {
|
||||
facade::CmdArgParser parser{args};
|
||||
auto [src, dest] = parser.Next<string_view, string_view>();
|
||||
ListDir src_dir = ParseDir(&parser);
|
||||
ListDir dest_dir = ParseDir(&parser);
|
||||
|
||||
if (auto err = parser.Error(); err)
|
||||
return builder->SendError(err->MakeReply());
|
||||
return cmd_cntx.rb->SendError(err->MakeReply());
|
||||
|
||||
MoveGeneric(src, dest, src_dir, dest_dir, tx, builder);
|
||||
MoveGeneric(src, dest, src_dir, dest_dir, cmd_cntx.tx, cmd_cntx.rb);
|
||||
}
|
||||
|
||||
using CI = CommandId;
|
||||
|
|
|
@ -15,9 +15,8 @@ namespace dfly {
|
|||
|
||||
using facade::OpResult;
|
||||
|
||||
class ConnectionContext;
|
||||
class CommandRegistry;
|
||||
class Transaction;
|
||||
struct CommandContext;
|
||||
|
||||
class ListFamily {
|
||||
public:
|
||||
|
@ -26,25 +25,23 @@ class ListFamily {
|
|||
private:
|
||||
using SinkReplyBuilder = facade::SinkReplyBuilder;
|
||||
|
||||
static void LPush(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void LPushX(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void RPush(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void RPushX(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void LPop(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void RPop(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void BLPop(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx);
|
||||
static void BRPop(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder,
|
||||
ConnectionContext* cntx);
|
||||
static void LLen(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void LPos(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void LIndex(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void LInsert(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void LTrim(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void LRange(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void LRem(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void LSet(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void LMove(CmdArgList args, Transaction* tx, SinkReplyBuilder* builder);
|
||||
static void LPush(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void LPushX(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void RPush(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void RPushX(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void LPop(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void RPop(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void BLPop(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void BRPop(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void LLen(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void LPos(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void LIndex(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void LInsert(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void LTrim(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void LRange(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void LRem(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void LSet(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
static void LMove(CmdArgList args, const CommandContext& cmd_cntx);
|
||||
};
|
||||
|
||||
} // namespace dfly
|
||||
|
|
Loading…
Reference in a new issue