fix(server): support for persist command #345 Co-authored-by: Boaz Sade <boaz@dragonflydb.io>
This commit is contained in:
parent
bfc073b59d
commit
8f5500af16
|
@ -177,7 +177,7 @@ with respect to Memcached and Redis APIs.
|
|||
- [X] EVAL
|
||||
- [X] EVALSHA
|
||||
- [ ] OBJECT
|
||||
- [ ] PERSIST
|
||||
- [x] PERSIST
|
||||
- [X] PTTL
|
||||
- [ ] RESTORE
|
||||
- [X] SCRIPT LOAD/EXISTS
|
||||
|
|
|
@ -29,6 +29,8 @@ using namespace facade;
|
|||
|
||||
namespace {
|
||||
|
||||
OpStatus OpPersist(const OpArgs& op_args, string_view key);
|
||||
|
||||
class Renamer {
|
||||
public:
|
||||
Renamer(ShardId source_id) : src_sid_(source_id) {
|
||||
|
@ -177,6 +179,22 @@ struct ScanOpts {
|
|||
unsigned bucket_id = UINT_MAX;
|
||||
};
|
||||
|
||||
OpStatus OpPersist(const OpArgs& op_args, string_view key) {
|
||||
auto& db_slice = op_args.shard->db_slice();
|
||||
auto [it, expire_it] = db_slice.FindExt(op_args.db_cntx, key);
|
||||
|
||||
if (!IsValid(it)) {
|
||||
return OpStatus::KEY_NOTFOUND;
|
||||
} else {
|
||||
if (IsValid(expire_it)) {
|
||||
// The SKIPPED not really used, just placeholder for error
|
||||
return db_slice.UpdateExpire(op_args.db_cntx.db_index, it, 0) ? OpStatus::OK
|
||||
: OpStatus::SKIPPED;
|
||||
}
|
||||
return OpStatus::OK; // fall though - this is the default
|
||||
}
|
||||
}
|
||||
|
||||
bool ScanCb(const OpArgs& op_args, PrimeIterator it, const ScanOpts& opts, StringVec* res) {
|
||||
auto& db_slice = op_args.shard->db_slice();
|
||||
if (it->second.HasExpire()) {
|
||||
|
@ -348,6 +366,15 @@ void GenericFamily::Exists(CmdArgList args, ConnectionContext* cntx) {
|
|||
return (*cntx)->SendLong(result.load(memory_order_release));
|
||||
}
|
||||
|
||||
void GenericFamily::Persist(CmdArgList args, ConnectionContext* cntx) {
|
||||
string_view key = ArgS(args, 1);
|
||||
|
||||
auto cb = [&](Transaction* t, EngineShard* shard) { return OpPersist(t->GetOpArgs(shard), key); };
|
||||
|
||||
OpStatus status = cntx->transaction->ScheduleSingleHop(move(cb));
|
||||
(*cntx)->SendLong(status == OpStatus::OK);
|
||||
}
|
||||
|
||||
void GenericFamily::Expire(CmdArgList args, ConnectionContext* cntx) {
|
||||
string_view key = ArgS(args, 1);
|
||||
string_view sec = ArgS(args, 2);
|
||||
|
@ -1036,6 +1063,7 @@ void GenericFamily::Register(CommandRegistry* registry) {
|
|||
<< CI{"EXISTS", CO::READONLY | CO::FAST, -2, 1, -1, 1}.HFUNC(Exists)
|
||||
<< CI{"EXPIRE", CO::WRITE | CO::FAST, 3, 1, 1, 1}.HFUNC(Expire)
|
||||
<< CI{"EXPIREAT", CO::WRITE | CO::FAST, 3, 1, 1, 1}.HFUNC(ExpireAt)
|
||||
<< CI{"PERSIST", CO::WRITE | CO::FAST, 2, 1, 1, 1}.HFUNC(Persist)
|
||||
<< CI{"KEYS", CO::READONLY, 2, 0, 0, 0}.HFUNC(Keys)
|
||||
<< CI{"PEXPIREAT", CO::WRITE | CO::FAST, 3, 1, 1, 1}.HFUNC(PexpireAt)
|
||||
<< CI{"RENAME", CO::WRITE, 3, 1, 2, 1}.HFUNC(Rename)
|
||||
|
|
|
@ -46,6 +46,7 @@ class GenericFamily {
|
|||
static void Exists(CmdArgList args, ConnectionContext* cntx);
|
||||
static void Expire(CmdArgList args, ConnectionContext* cntx);
|
||||
static void ExpireAt(CmdArgList args, ConnectionContext* cntx);
|
||||
static void Persist(CmdArgList args, ConnectionContext* cntx);
|
||||
static void Keys(CmdArgList args, ConnectionContext* cntx);
|
||||
static void PexpireAt(CmdArgList args, ConnectionContext* cntx);
|
||||
static void Stick(CmdArgList args, ConnectionContext* cntx);
|
||||
|
|
|
@ -282,21 +282,28 @@ TEST_F(GenericFamilyTest, Sort) {
|
|||
// numeric
|
||||
ASSERT_THAT(Run({"sort", "list-1"}).GetVec(), ElementsAre("1.2", "2.20", "3.5", "10.1", "200"));
|
||||
// string
|
||||
ASSERT_THAT(Run({"sort", "list-1", "ALPHA"}).GetVec(), ElementsAre("1.2", "10.1", "2.20", "200", "3.5"));
|
||||
ASSERT_THAT(Run({"sort", "list-1", "ALPHA"}).GetVec(),
|
||||
ElementsAre("1.2", "10.1", "2.20", "200", "3.5"));
|
||||
// desc numeric
|
||||
ASSERT_THAT(Run({"sort", "list-1", "DESC"}).GetVec(), ElementsAre("200", "10.1", "3.5", "2.20", "1.2"));
|
||||
ASSERT_THAT(Run({"sort", "list-1", "DESC"}).GetVec(),
|
||||
ElementsAre("200", "10.1", "3.5", "2.20", "1.2"));
|
||||
// desc strig
|
||||
ASSERT_THAT(Run({"sort", "list-1", "DESC", "ALPHA"}).GetVec(), ElementsAre("3.5", "200", "2.20", "10.1", "1.2"));
|
||||
ASSERT_THAT(Run({"sort", "list-1", "DESC", "ALPHA"}).GetVec(),
|
||||
ElementsAre("3.5", "200", "2.20", "10.1", "1.2"));
|
||||
// limits
|
||||
ASSERT_THAT(Run({"sort", "list-1", "LIMIT", "0", "5"}).GetVec(), ElementsAre("1.2", "2.20", "3.5", "10.1", "200"));
|
||||
ASSERT_THAT(Run({"sort", "list-1", "LIMIT", "0", "10"}).GetVec(), ElementsAre("1.2", "2.20", "3.5", "10.1", "200"));
|
||||
ASSERT_THAT(Run({"sort", "list-1", "LIMIT", "0", "5"}).GetVec(),
|
||||
ElementsAre("1.2", "2.20", "3.5", "10.1", "200"));
|
||||
ASSERT_THAT(Run({"sort", "list-1", "LIMIT", "0", "10"}).GetVec(),
|
||||
ElementsAre("1.2", "2.20", "3.5", "10.1", "200"));
|
||||
ASSERT_THAT(Run({"sort", "list-1", "LIMIT", "2", "2"}).GetVec(), ElementsAre("3.5", "10.1"));
|
||||
ASSERT_THAT(Run({"sort", "list-1", "LIMIT", "1", "1"}), "2.20");
|
||||
ASSERT_THAT(Run({"sort", "list-1", "LIMIT", "4", "2"}), "200");
|
||||
ASSERT_THAT(Run({"sort", "list-1", "LIMIT", "5", "2"}), ArrLen(0));
|
||||
// limits desc
|
||||
ASSERT_THAT(Run({"sort", "list-1", "DESC", "LIMIT", "0", "5"}).GetVec(), ElementsAre("200", "10.1", "3.5", "2.20", "1.2"));
|
||||
ASSERT_THAT(Run({"sort", "list-1", "DESC", "LIMIT", "2", "2"}).GetVec(), ElementsAre("3.5", "2.20"));
|
||||
ASSERT_THAT(Run({"sort", "list-1", "DESC", "LIMIT", "0", "5"}).GetVec(),
|
||||
ElementsAre("200", "10.1", "3.5", "2.20", "1.2"));
|
||||
ASSERT_THAT(Run({"sort", "list-1", "DESC", "LIMIT", "2", "2"}).GetVec(),
|
||||
ElementsAre("3.5", "2.20"));
|
||||
ASSERT_THAT(Run({"sort", "list-1", "DESC", "LIMIT", "1", "1"}), "10.1");
|
||||
ASSERT_THAT(Run({"sort", "list-1", "DESC", "LIMIT", "5", "2"}), ArrLen(0));
|
||||
|
||||
|
@ -304,9 +311,12 @@ TEST_F(GenericFamilyTest, Sort) {
|
|||
Run({"del", "set-1"});
|
||||
Run({"sadd", "set-1", "5.3", "4.4", "60", "99.9", "100", "9"});
|
||||
ASSERT_THAT(Run({"sort", "set-1"}).GetVec(), ElementsAre("4.4", "5.3", "9", "60", "99.9", "100"));
|
||||
ASSERT_THAT(Run({"sort", "set-1", "ALPHA"}).GetVec(), ElementsAre("100", "4.4", "5.3", "60", "9", "99.9"));
|
||||
ASSERT_THAT(Run({"sort", "set-1", "DESC"}).GetVec(), ElementsAre("100", "99.9", "60", "9", "5.3", "4.4"));
|
||||
ASSERT_THAT(Run({"sort", "set-1", "DESC", "ALPHA"}).GetVec(), ElementsAre("99.9", "9", "60", "5.3", "4.4", "100"));
|
||||
ASSERT_THAT(Run({"sort", "set-1", "ALPHA"}).GetVec(),
|
||||
ElementsAre("100", "4.4", "5.3", "60", "9", "99.9"));
|
||||
ASSERT_THAT(Run({"sort", "set-1", "DESC"}).GetVec(),
|
||||
ElementsAre("100", "99.9", "60", "9", "5.3", "4.4"));
|
||||
ASSERT_THAT(Run({"sort", "set-1", "DESC", "ALPHA"}).GetVec(),
|
||||
ElementsAre("99.9", "9", "60", "5.3", "4.4", "100"));
|
||||
|
||||
// Test intset sort
|
||||
Run({"del", "intset-1"});
|
||||
|
@ -354,4 +364,16 @@ TEST_F(GenericFamilyTest, Time) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST_F(GenericFamilyTest, Persist) {
|
||||
auto resp = Run({"set", "mykey", "somevalue"});
|
||||
EXPECT_EQ(resp, "OK");
|
||||
// Key without expiration time - return 1
|
||||
EXPECT_EQ(1, CheckedInt({"persist", "mykey"}));
|
||||
// set expiration time and try again
|
||||
resp = Run({"EXPIRE", "mykey", "10"});
|
||||
EXPECT_EQ(10, CheckedInt({"TTL", "mykey"}));
|
||||
EXPECT_EQ(1, CheckedInt({"persist", "mykey"}));
|
||||
EXPECT_EQ(-1, CheckedInt({"TTL", "mykey"}));
|
||||
}
|
||||
|
||||
} // namespace dfly
|
||||
|
|
Loading…
Reference in New Issue