You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kvrocks.apache.org by tw...@apache.org on 2023/03/24 16:36:48 UTC
[incubator-kvrocks] branch unstable updated: Round expire time for seconds to improve precision for 32bit-common-field encoding (#1352)
This is an automated email from the ASF dual-hosted git repository.
twice pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/incubator-kvrocks.git
The following commit(s) were added to refs/heads/unstable by this push:
new 95301c5a Round expire time for seconds to improve precision for 32bit-common-field encoding (#1352)
95301c5a is described below
commit 95301c5a673af83ad85e6dfb63da4db41d83afb8
Author: Twice <tw...@gmail.com>
AuthorDate: Sat Mar 25 00:36:41 2023 +0800
Round expire time for seconds to improve precision for 32bit-common-field encoding (#1352)
---
src/commands/cmd_key.cc | 6 +++---
src/storage/redis_db.cc | 4 ++--
src/storage/redis_db.h | 2 ++
src/storage/redis_metadata.cc | 3 ++-
tests/cppunit/types/string_test.cc | 8 ++++----
tests/gocase/unit/expire/expire_test.go | 2 +-
6 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/src/commands/cmd_key.cc b/src/commands/cmd_key.cc
index 8a75b2db..efd0cc57 100644
--- a/src/commands/cmd_key.cc
+++ b/src/commands/cmd_key.cc
@@ -115,13 +115,13 @@ class CommandExists : public Commander {
class CommandExpire : public Commander {
public:
Status Parse(const std::vector<std::string> &args) override {
- seconds_ = GET_OR_RET(ParseInt<int64_t>(args[2], 10)) + Util::GetTimeStamp();
+ ttl_ = GET_OR_RET(ParseInt<int64_t>(args[2], 10));
return Status::OK();
}
Status Execute(Server *svr, Connection *conn, std::string *output) override {
Redis::Database redis(svr->storage_, conn->GetNamespace());
- auto s = redis.Expire(args_[1], seconds_ * 1000);
+ auto s = redis.Expire(args_[1], ttl_ * 1000 + Util::GetTimeStampMS());
if (s.ok()) {
*output = Redis::Integer(1);
} else {
@@ -131,7 +131,7 @@ class CommandExpire : public Commander {
}
private:
- uint64_t seconds_ = 0;
+ uint64_t ttl_ = 0;
};
class CommandPExpire : public Commander {
diff --git a/src/storage/redis_db.cc b/src/storage/redis_db.cc
index c347caa4..6d2a2d1b 100644
--- a/src/storage/redis_db.cc
+++ b/src/storage/redis_db.cc
@@ -324,13 +324,13 @@ rocksdb::Status Database::RandomKey(const std::string &cursor, std::string *key)
std::string end_cursor;
std::vector<std::string> keys;
- auto s = Scan(cursor, 60, "", &keys, &end_cursor);
+ auto s = Scan(cursor, RANDOM_KEY_SCAN_LIMIT, "", &keys, &end_cursor);
if (!s.ok()) {
return s;
}
if (keys.empty() && !cursor.empty()) {
// if reach the end, restart from beginning
- s = Scan("", 60, "", &keys, &end_cursor);
+ s = Scan("", RANDOM_KEY_SCAN_LIMIT, "", &keys, &end_cursor);
if (!s.ok()) {
return s;
}
diff --git a/src/storage/redis_db.h b/src/storage/redis_db.h
index 18012bf5..437ef825 100644
--- a/src/storage/redis_db.h
+++ b/src/storage/redis_db.h
@@ -31,6 +31,8 @@
namespace Redis {
class Database {
public:
+ static constexpr uint64_t RANDOM_KEY_SCAN_LIMIT = 60;
+
explicit Database(Engine::Storage *storage, std::string ns = "");
rocksdb::Status GetMetadata(RedisType type, const Slice &ns_key, Metadata *metadata);
rocksdb::Status GetRawMetadata(const Slice &ns_key, std::string *bytes);
diff --git a/src/storage/redis_metadata.cc b/src/storage/redis_metadata.cc
index 73580abd..aa5b26fe 100644
--- a/src/storage/redis_metadata.cc
+++ b/src/storage/redis_metadata.cc
@@ -233,7 +233,8 @@ uint64_t Metadata::ExpireMsToS(uint64_t ms) {
return 1;
}
- return ms / 1000;
+ // We use rounding to get closer to the original value
+ return (ms + 499) / 1000;
}
bool Metadata::Is64BitEncoded() const { return flags & METADATA_64BIT_ENCODING_MASK; }
diff --git a/tests/cppunit/types/string_test.cc b/tests/cppunit/types/string_test.cc
index b2b4b26a..61755b9b 100644
--- a/tests/cppunit/types/string_test.cc
+++ b/tests/cppunit/types/string_test.cc
@@ -179,7 +179,7 @@ TEST_F(RedisStringTest, MSetXX) {
EXPECT_EQ(ret, 1);
int64_t ttl = 0;
string->TTL(key_, &ttl);
- EXPECT_TRUE(ttl >= 2000 && ttl <= 3000);
+ EXPECT_TRUE(ttl >= 2000 && ttl <= 4000);
string->Del(key_);
}
@@ -214,7 +214,7 @@ TEST_F(RedisStringTest, MSetNXWithTTL) {
string->SetNX(key_, "test-value", 3000, &ret);
int64_t ttl = 0;
string->TTL(key_, &ttl);
- EXPECT_TRUE(ttl >= 2000 && ttl <= 3000);
+ EXPECT_TRUE(ttl >= 2000 && ttl <= 4000);
string->Del(key_);
}
@@ -222,7 +222,7 @@ TEST_F(RedisStringTest, SetEX) {
string->SetEX(key_, "test-value", 3000);
int64_t ttl = 0;
string->TTL(key_, &ttl);
- EXPECT_TRUE(ttl >= 2000 && ttl <= 3000);
+ EXPECT_TRUE(ttl >= 2000 && ttl <= 4000);
string->Del(key_);
}
@@ -277,7 +277,7 @@ TEST_F(RedisStringTest, CAS) {
int64_t ttl = 0;
string->TTL(key, &ttl);
- EXPECT_TRUE(ttl >= 9000 && ttl <= 10000);
+ EXPECT_TRUE(ttl >= 9000 && ttl <= 11000);
string->Del(key);
}
diff --git a/tests/gocase/unit/expire/expire_test.go b/tests/gocase/unit/expire/expire_test.go
index d35b84d8..8a691966 100644
--- a/tests/gocase/unit/expire/expire_test.go
+++ b/tests/gocase/unit/expire/expire_test.go
@@ -168,7 +168,7 @@ func TestExpire(t *testing.T) {
t.Run("PTTL returns time to live in milliseconds", func(t *testing.T) {
require.NoError(t, rdb.Del(ctx, "x").Err())
require.NoError(t, rdb.SetEx(ctx, "x", "somevalue", 2*time.Second).Err())
- util.BetweenValues(t, rdb.PTTL(ctx, "x").Val(), 50*time.Millisecond, 2000*time.Millisecond)
+ util.BetweenValues(t, rdb.PTTL(ctx, "x").Val(), 500*time.Millisecond, 2500*time.Millisecond)
})
t.Run("TTL / PTTL return -1 if key has no expire", func(t *testing.T) {