feat(server): Add GETDEL command (#365)

* Added GETDEL command

* fix(server): Implement Del inside OpGet

* fix(server): Swapped result for CHECK macro

* docs(contributors): Added myself to Contributors
This commit is contained in:
Elle Y 2022-10-07 05:39:33 -07:00 committed by GitHub
parent 3bf08b803c
commit ef1f0a9efc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 1 deletions

View File

@ -8,3 +8,4 @@
* **[Ryan Russell](https://github.com/ryanrussell)**
* Docs & Code Readability
* **[Ali-Akber Saifee](https://github.com/alisaifee)**
* **[Elle Y](https://github.com/inohime)**

View File

@ -191,13 +191,24 @@ OpResult<bool> ExtendOrSkip(const OpArgs& op_args, string_view key, string_view
return ExtendExisting(op_args, *it_res, key, val, prepend);
}
OpResult<string> OpGet(const OpArgs& op_args, string_view key) {
OpResult<string> OpGet(const OpArgs& op_args, string_view key, bool del_hit = false) {
OpResult<PrimeIterator> it_res = op_args.shard->db_slice().Find(op_args.db_cntx, key, OBJ_STRING);
if (!it_res.ok())
return it_res.status();
const PrimeValue& pv = it_res.value()->second;
if (del_hit) {
string key_bearer = GetString(op_args.shard, pv);
DVLOG(1) << "Del: " << key;
auto& db_slice = op_args.shard->db_slice();
CHECK(db_slice.Del(op_args.db_cntx.db_index, it_res.value()));
return key_bearer;
}
return GetString(op_args.shard, pv);
}
@ -597,6 +608,36 @@ void StringFamily::Get(CmdArgList args, ConnectionContext* cntx) {
}
}
void StringFamily::GetDel(CmdArgList args, ConnectionContext* cntx) {
get_qps.Inc();
string_view key = ArgS(args, 1);
auto cb = [&](Transaction* t, EngineShard* shard) {
bool run_del = true;
return OpGet(t->GetOpArgs(shard), key, run_del);
};
DVLOG(1) << "Before Get::ScheduleSingleHopT " << key;
Transaction* trans = cntx->transaction;
OpResult<string> result = trans->ScheduleSingleHopT(std::move(cb));
if (result) {
DVLOG(1) << "GET " << trans->DebugId() << ": " << key << " " << result.value();
(*cntx)->SendBulkString(*result);
} else {
switch (result.status()) {
case OpStatus::WRONG_TYPE:
(*cntx)->SendError(kWrongTypeErr);
break;
default:
DVLOG(1) << "GET " << key << " nil";
(*cntx)->SendNull();
}
}
}
void StringFamily::GetSet(CmdArgList args, ConnectionContext* cntx) {
string_view key = ArgS(args, 1);
string_view value = ArgS(args, 2);
@ -1038,6 +1079,7 @@ void StringFamily::Register(CommandRegistry* registry) {
<< CI{"INCRBYFLOAT", CO::WRITE | CO::DENYOOM | CO::FAST, 3, 1, 1, 1}.HFUNC(IncrByFloat)
<< CI{"DECRBY", CO::WRITE | CO::DENYOOM | CO::FAST, 3, 1, 1, 1}.HFUNC(DecrBy)
<< CI{"GET", CO::READONLY | CO::FAST, 2, 1, 1, 1}.HFUNC(Get)
<< CI{"GETDEL", CO::WRITE | CO::DENYOOM | CO::FAST, 2, 1, 1, 1}.HFUNC(GetDel)
<< CI{"GETSET", CO::WRITE | CO::DENYOOM | CO::FAST, 3, 1, 1, 1}.HFUNC(GetSet)
<< CI{"MGET", CO::READONLY | CO::FAST | CO::REVERSE_MAPPING, -2, 1, -1, 1}.HFUNC(MGet)
<< CI{"MSET", CO::WRITE | CO::DENYOOM, -3, 1, -1, 2}.HFUNC(MSet)

View File

@ -57,6 +57,7 @@ class StringFamily {
static void Decr(CmdArgList args, ConnectionContext* cntx);
static void DecrBy(CmdArgList args, ConnectionContext* cntx);
static void Get(CmdArgList args, ConnectionContext* cntx);
static void GetDel(CmdArgList args, ConnectionContext* cntx);
static void GetRange(CmdArgList args, ConnectionContext* cntx);
static void GetSet(CmdArgList args, ConnectionContext* cntx);
static void Incr(CmdArgList args, ConnectionContext* cntx);

View File

@ -387,4 +387,16 @@ TEST_F(StringFamilyTest, SetPxAtExAt) {
EXPECT_EQ(Run({"get", "foo2"}), "abc");
}
TEST_F(StringFamilyTest, GetDel) {
auto resp = Run({"set", "foo", "bar"});
EXPECT_THAT(resp, "OK");
resp = Run({"getdel", "foo"});
// foo's value
ASSERT_THAT(resp, ArgType(RespExpr::STRING));
resp = Run({"get", "foo"});
ASSERT_THAT(resp, ArgType(RespExpr::NIL));
}
} // namespace dfly