diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 2abda5fe9..31c4429cb 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -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)** \ No newline at end of file diff --git a/src/server/string_family.cc b/src/server/string_family.cc index d322a645a..98e7fb508 100644 --- a/src/server/string_family.cc +++ b/src/server/string_family.cc @@ -191,13 +191,24 @@ OpResult ExtendOrSkip(const OpArgs& op_args, string_view key, string_view return ExtendExisting(op_args, *it_res, key, val, prepend); } -OpResult OpGet(const OpArgs& op_args, string_view key) { +OpResult OpGet(const OpArgs& op_args, string_view key, bool del_hit = false) { OpResult 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 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) diff --git a/src/server/string_family.h b/src/server/string_family.h index a2031e3c6..47bee58a3 100644 --- a/src/server/string_family.h +++ b/src/server/string_family.h @@ -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); diff --git a/src/server/string_family_test.cc b/src/server/string_family_test.cc index 6e74b684e..ad21c072c 100644 --- a/src/server/string_family_test.cc +++ b/src/server/string_family_test.cc @@ -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