diff --git a/.github/workflows/pika.yml b/.github/workflows/pika.yml index fc86272a92..63c2e884e0 100644 --- a/.github/workflows/pika.yml +++ b/.github/workflows/pika.yml @@ -69,6 +69,7 @@ jobs: - name: Start codis, pika master and pika slave working-directory: ${{ github.workspace }}/build run: | + echo "hello" chmod +x ../tests/integration/start_master_and_slave.sh ../tests/integration/start_master_and_slave.sh chmod +x ../tests/integration/start_codis.sh diff --git a/include/pika_cache.h b/include/pika_cache.h index 5073b1b174..d82627ced7 100644 --- a/include/pika_cache.h +++ b/include/pika_cache.h @@ -67,7 +67,7 @@ class PikaCache : public pstd::noncopyable, public std::enable_shared_from_this< rocksdb::Status Del(const std::vector& keys); rocksdb::Status Expire(std::string& key, int64_t ttl); - rocksdb::Status Expireat(std::string& key, int64_t ttl); + rocksdb::Status Expireat(std::string& key, int64_t ttl_sec); rocksdb::Status TTL(std::string& key, int64_t* ttl); rocksdb::Status Persist(std::string& key); rocksdb::Status Type(std::string& key, std::string* value); diff --git a/include/pika_kv.h b/include/pika_kv.h index a02f6b1a4c..de2918e408 100644 --- a/include/pika_kv.h +++ b/include/pika_kv.h @@ -36,12 +36,12 @@ class SetCmd : public Cmd { std::string value_; std::string target_; int32_t success_ = 0; - int64_t sec_ = 0; + int64_t ttl_millsec = 0; bool has_ttl_ = false; SetCmd::SetCondition condition_{kNONE}; void DoInitial() override; void Clear() override { - sec_ = 0; + ttl_millsec = 0; success_ = 0; condition_ = kNONE; } @@ -69,7 +69,7 @@ class GetCmd : public Cmd { private: std::string key_; std::string value_; - int64_t sec_ = 0; + int64_t ttl_millsec_ = 0; void DoInitial() override; rocksdb::Status s_; }; @@ -115,7 +115,7 @@ class IncrCmd : public Cmd { int64_t new_value_ = 0; void DoInitial() override; rocksdb::Status s_; - int64_t expired_timestamp_sec_ = 0; + int64_t expired_timestamp_millsec_ = 0; std::string ToRedisProtocol() override; }; @@ -140,7 +140,7 @@ class IncrbyCmd : public Cmd { int64_t by_ = 0, new_value_ = 0; void DoInitial() override; rocksdb::Status s_; - int64_t expired_timestamp_sec_ = 0; + int64_t expired_timestamp_millsec_ = 0; std::string ToRedisProtocol() override; }; @@ -165,7 +165,7 @@ class IncrbyfloatCmd : public Cmd { double by_ = 0; void DoInitial() override; rocksdb::Status s_; - int64_t expired_timestamp_sec_ = 0; + int64_t expired_timestamp_millsec_ = 0; std::string ToRedisProtocol() override; }; @@ -260,7 +260,7 @@ class AppendCmd : public Cmd { std::string new_value_; void DoInitial() override; rocksdb::Status s_; - int64_t expired_timestamp_sec_ = 0; + int64_t expired_timestamp_millsec_ = 0; std::string ToRedisProtocol() override; }; @@ -351,7 +351,7 @@ class SetexCmd : public Cmd { private: std::string key_; - int64_t sec_ = 0; + int64_t ttl_sec_ = 0; std::string value_; void DoInitial() override; rocksdb::Status s_; @@ -376,7 +376,7 @@ class PsetexCmd : public Cmd { private: std::string key_; - int64_t usec_ = 0; + int64_t ttl_millsec = 0; std::string value_; void DoInitial() override; rocksdb::Status s_; @@ -540,7 +540,7 @@ class StrlenCmd : public Cmd { private: std::string key_; std::string value_; - int64_t sec_ = 0; + int64_t ttl_millsec = 0; void DoInitial() override; rocksdb::Status s_; }; @@ -581,7 +581,7 @@ class ExpireCmd : public Cmd { private: std::string key_; - int64_t sec_ = 0; + int64_t ttl_sec_ = 0; void DoInitial() override; std::string ToRedisProtocol() override; rocksdb::Status s_; @@ -605,7 +605,7 @@ class PexpireCmd : public Cmd { private: std::string key_; - int64_t msec_ = 0; + int64_t ttl_millsec = 0; void DoInitial() override; std::string ToRedisProtocol() override; rocksdb::Status s_; @@ -629,7 +629,7 @@ class ExpireatCmd : public Cmd { private: std::string key_; - int64_t time_stamp_ = 0; + int64_t time_stamp_sec_ = 0; void DoInitial() override; rocksdb::Status s_; }; @@ -652,10 +652,9 @@ class PexpireatCmd : public Cmd { private: std::string key_; - int64_t time_stamp_ms_ = 0; + int64_t time_stamp_millsec_ = 0; void DoInitial() override; rocksdb::Status s_; - std::string ToRedisProtocol() override; }; class TtlCmd : public Cmd { @@ -810,9 +809,9 @@ class PKSetexAtCmd : public Cmd { private: std::string key_; std::string value_; - int64_t time_stamp_ = 0; + int64_t time_stamp_sec_ = 0; void DoInitial() override; - void Clear() override { time_stamp_ = 0; } + void Clear() override { time_stamp_sec_ = 0; } rocksdb::Status s_; }; diff --git a/src/net/examples/performance/server.cc b/src/net/examples/performance/server.cc index 5b7b65cbc7..ce70abddcc 100644 --- a/src/net/examples/performance/server.cc +++ b/src/net/examples/performance/server.cc @@ -86,7 +86,7 @@ int main(int argc, char* argv[]) { std::unique_ptr st_thread(NewDispatchThread(ip, port, 24, &conn_factory, 1000)); st_thread->StartThread(); - uint64_t st, ed; + pstd::TimeType st, ed; while (!should_stop) { st = NowMicros(); diff --git a/src/pika_admin.cc b/src/pika_admin.cc index a6226917f8..47a980c0ca 100644 --- a/src/pika_admin.cc +++ b/src/pika_admin.cc @@ -2841,8 +2841,8 @@ void ConfigCmd::ConfigSet(std::shared_ptr db) { "The rsync rate limit now is " << new_throughput_limit << "(Which Is Around " << (new_throughput_limit >> 20) << " MB/s)"; res_.AppendStringRaw("+OK\r\n"); - } else if(set_item == "rsync-timeout-ms"){ - if(pstd::string2int(value.data(), value.size(), &ival) == 0 || ival <= 0){ + } else if (set_item == "rsync-timeout-ms") { + if (pstd::string2int(value.data(), value.size(), &ival) == 0 || ival <= 0) { res_.AppendStringRaw("-ERR Invalid argument \'" + value + "\' for CONFIG SET 'rsync-timeout-ms'\r\n"); return; } @@ -3037,9 +3037,9 @@ void DbsizeCmd::Do() { if (!dbs) { res_.SetRes(CmdRes::kInvalidDB); } else { - if (g_pika_conf->slotmigrate()){ + if (g_pika_conf->slotmigrate()) { int64_t dbsize = 0; - for (int i = 0; i < g_pika_conf->default_slot_num(); ++i){ + for (int i = 0; i < g_pika_conf->default_slot_num(); ++i) { int32_t card = 0; rocksdb::Status s = dbs->storage()->SCard(SlotKeyPrefix+std::to_string(i), &card); if (s.ok() && card >= 0) { diff --git a/src/pika_bit.cc b/src/pika_bit.cc index 2367364054..ee48d0ba5f 100644 --- a/src/pika_bit.cc +++ b/src/pika_bit.cc @@ -114,7 +114,7 @@ void BitGetCmd::DoThroughDB() { Do(); } -void BitGetCmd::DoUpdateCache(){ +void BitGetCmd::DoUpdateCache() { if (s_.ok()) { db_->cache()->PushKeyToAsyncLoadQueue(PIKA_KEY_TYPE_KV, key_, db_); } diff --git a/src/pika_cache.cc b/src/pika_cache.cc index d6dff559de..b7d1f45eb1 100644 --- a/src/pika_cache.cc +++ b/src/pika_cache.cc @@ -126,10 +126,10 @@ Status PikaCache::Expire(std::string& key, int64_t ttl) { return caches_[cache_index]->Expire(key, ttl); } -Status PikaCache::Expireat(std::string& key, int64_t ttl) { +Status PikaCache::Expireat(std::string& key, int64_t ttl_sec) { int cache_index = CacheIndex(key); std::lock_guard lm(*cache_mutexs_[cache_index]); - return caches_[cache_index]->Expireat(key, ttl); + return caches_[cache_index]->Expireat(key, ttl_sec); } Status PikaCache::TTL(std::string& key, int64_t *ttl) { diff --git a/src/pika_cache_load_thread.cc b/src/pika_cache_load_thread.cc index b2205a7d49..f9bb040a40 100644 --- a/src/pika_cache_load_thread.cc +++ b/src/pika_cache_load_thread.cc @@ -113,13 +113,13 @@ bool PikaCacheLoadThread::LoadSet(std::string& key, const std::shared_ptr& d } std::vector values; - int64_t ttl = -1; - rocksdb::Status s = db->storage()->SMembersWithTTL(key, &values, &ttl); + int64_t ttl_millsec = -1; + rocksdb::Status s = db->storage()->SMembersWithTTL(key, &values, &ttl_millsec); if (!s.ok()) { LOG(WARNING) << "load set failed, key=" << key; return false; } - db->cache()->WriteSetToCache(key, values, ttl); + db->cache()->WriteSetToCache(key, values, ttl_millsec > 0 ? ttl_millsec / 1000 : ttl_millsec); return true; } diff --git a/src/pika_conf.cc b/src/pika_conf.cc index 327fcd3554..d67d0dd29c 100644 --- a/src/pika_conf.cc +++ b/src/pika_conf.cc @@ -184,7 +184,7 @@ int PikaConf::Load() { std::string admin_cmd_list; GetConfStr("admin-cmd-list", &admin_cmd_list); - if (admin_cmd_list == ""){ + if (admin_cmd_list == "") { admin_cmd_list = "info, monitor, ping"; SetAdminCmd(admin_cmd_list); } @@ -724,7 +724,7 @@ int PikaConf::Load() { int64_t tmp_rsync_timeout_ms = -1; GetConfInt64("rsync-timeout-ms", &tmp_rsync_timeout_ms); - if(tmp_rsync_timeout_ms <= 0){ + if (tmp_rsync_timeout_ms <= 0) { rsync_timeout_ms_.store(1000); } else { rsync_timeout_ms_.store(tmp_rsync_timeout_ms); diff --git a/src/pika_geo.cc b/src/pika_geo.cc index acb7d38dcb..7e7575eca1 100644 --- a/src/pika_geo.cc +++ b/src/pika_geo.cc @@ -366,7 +366,7 @@ static void GetAllNeighbors(const std::shared_ptr& db, std::string& key, Geo int32_t count = 0; int32_t card = db->storage()->Exists({range.storekey}); if (card) { - if (db->storage()->Del({range.storekey}) > 0){ + if (db->storage()->Del({range.storekey}) > 0) { db->cache()->Del({range.storekey}); } } diff --git a/src/pika_kv.cc b/src/pika_kv.cc index abcf0e53d8..027d9dfde8 100644 --- a/src/pika_kv.cc +++ b/src/pika_kv.cc @@ -22,7 +22,7 @@ void SetCmd::DoInitial() { key_ = argv_[1]; value_ = argv_[2]; condition_ = SetCmd::kNONE; - sec_ = 0; + ttl_millsec = 0; size_t index = 3; while (index != argv_.size()) { std::string opt = argv_[index]; @@ -46,13 +46,13 @@ void SetCmd::DoInitial() { res_.SetRes(CmdRes::kSyntaxErr); return; } - if (pstd::string2int(argv_[index].data(), argv_[index].size(), &sec_) == 0) { + if (pstd::string2int(argv_[index].data(), argv_[index].size(), &ttl_millsec) == 0) { res_.SetRes(CmdRes::kInvalidInt); return; } - if (strcasecmp(opt.data(), "px") == 0) { - sec_ /= 1000; + if (strcasecmp(opt.data(), "ex") == 0) { + ttl_millsec *= 1000; } has_ttl_ = true; } else { @@ -67,16 +67,16 @@ void SetCmd::Do() { int32_t res = 1; switch (condition_) { case SetCmd::kXX: - s_ = db_->storage()->Setxx(key_, value_, &res, sec_); + s_ = db_->storage()->Setxx(key_, value_, &res, ttl_millsec); break; case SetCmd::kNX: - s_ = db_->storage()->Setnx(key_, value_, &res, sec_); + s_ = db_->storage()->Setnx(key_, value_, &res, ttl_millsec); break; case SetCmd::kVX: - s_ = db_->storage()->Setvx(key_, target_, value_, &success_, sec_); + s_ = db_->storage()->Setvx(key_, target_, value_, &success_, ttl_millsec); break; case SetCmd::kEXORPX: - s_ = db_->storage()->Setex(key_, value_, sec_); + s_ = db_->storage()->Setex(key_, value_, ttl_millsec); break; default: s_ = db_->storage()->Set(key_, value_); @@ -111,7 +111,7 @@ void SetCmd::DoUpdateCache() { } if (s_.ok()) { if (has_ttl_) { - db_->cache()->Setxx(key_, value_, sec_); + db_->cache()->Setxx(key_, value_, ttl_millsec / 1000); } else { db_->cache()->SetxxWithoutTTL(key_, value_); } @@ -133,7 +133,9 @@ std::string SetCmd::ToRedisProtocol() { RedisAppendContent(content, key_); // time_stamp char buf[100]; - auto time_stamp = time(nullptr) + sec_; + + // TODO 精度损失 + auto time_stamp = time(nullptr) + ttl_millsec / 1000; pstd::ll2string(buf, 100, time_stamp); std::string at(buf); RedisAppendLenUint64(content, at.size(), "$"); @@ -156,7 +158,7 @@ void GetCmd::DoInitial() { } void GetCmd::Do() { - s_ = db_->storage()->GetWithTTL(key_, &value_, &sec_); + s_ = db_->storage()->GetWithTTL(key_, &value_, &ttl_millsec_); if (s_.ok()) { res_.AppendStringLenUint64(value_.size()); res_.AppendContent(value_); @@ -186,7 +188,7 @@ void GetCmd::DoThroughDB() { void GetCmd::DoUpdateCache() { if (s_.ok()) { - db_->cache()->WriteKVToCache(key_, value_, sec_); + db_->cache()->WriteKVToCache(key_, value_, ttl_millsec_ / 1000); } } @@ -255,7 +257,7 @@ void IncrCmd::DoInitial() { } void IncrCmd::Do() { - s_ = db_->storage()->Incrby(key_, 1, &new_value_, &expired_timestamp_sec_); + s_ = db_->storage()->Incrby(key_, 1, &new_value_, &expired_timestamp_millsec_); if (s_.ok()) { res_.AppendContent(":" + std::to_string(new_value_)); AddSlotKey("k", key_, db_); @@ -294,7 +296,7 @@ std::string IncrCmd::ToRedisProtocol() { RedisAppendContent(content, key_); // time_stamp char buf[100]; - auto time_stamp = expired_timestamp_sec_; + auto time_stamp = expired_timestamp_millsec_ > 0 ? expired_timestamp_millsec_ / 1000 : expired_timestamp_millsec_; pstd::ll2string(buf, sizeof(buf), time_stamp); std::string at(buf); RedisAppendLenUint64(content, at.size(), "$"); @@ -319,7 +321,7 @@ void IncrbyCmd::DoInitial() { } void IncrbyCmd::Do() { - s_ = db_->storage()->Incrby(key_, by_, &new_value_, &expired_timestamp_sec_); + s_ = db_->storage()->Incrby(key_, by_, &new_value_, &expired_timestamp_millsec_); if (s_.ok()) { res_.AppendContent(":" + std::to_string(new_value_)); AddSlotKey("k", key_, db_); @@ -358,7 +360,7 @@ std::string IncrbyCmd::ToRedisProtocol() { RedisAppendContent(content, key_); // time_stamp char buf[100]; - auto time_stamp = expired_timestamp_sec_; + auto time_stamp = expired_timestamp_millsec_ > 0 ? expired_timestamp_millsec_ / 1000 : expired_timestamp_millsec_; pstd::ll2string(buf, sizeof(buf), time_stamp); std::string at(buf); RedisAppendLenUint64(content, at.size(), "$"); @@ -384,7 +386,7 @@ void IncrbyfloatCmd::DoInitial() { } void IncrbyfloatCmd::Do() { - s_ = db_->storage()->Incrbyfloat(key_, value_, &new_value_, &expired_timestamp_sec_); + s_ = db_->storage()->Incrbyfloat(key_, value_, &new_value_, &expired_timestamp_millsec_); if (s_.ok()) { res_.AppendStringLenUint64(new_value_.size()); res_.AppendContent(new_value_); @@ -427,7 +429,7 @@ std::string IncrbyfloatCmd::ToRedisProtocol() { RedisAppendContent(content, key_); // time_stamp char buf[100]; - auto time_stamp = expired_timestamp_sec_; + auto time_stamp = expired_timestamp_millsec_ > 0 ? expired_timestamp_millsec_ / 1000 : expired_timestamp_millsec_; pstd::ll2string(buf, sizeof(buf), time_stamp); std::string at(buf); RedisAppendLenUint64(content, at.size(), "$"); @@ -558,7 +560,7 @@ void AppendCmd::DoInitial() { void AppendCmd::Do() { int32_t new_len = 0; - s_ = db_->storage()->Append(key_, value_, &new_len, &expired_timestamp_sec_, new_value_); + s_ = db_->storage()->Append(key_, value_, &new_len, &expired_timestamp_millsec_, new_value_); if (s_.ok() || s_.IsNotFound()) { res_.AppendInteger(new_len); AddSlotKey("k", key_, db_); @@ -569,7 +571,7 @@ void AppendCmd::Do() { } } -void AppendCmd::DoThroughDB(){ +void AppendCmd::DoThroughDB() { Do(); } @@ -593,7 +595,7 @@ std::string AppendCmd::ToRedisProtocol() { RedisAppendContent(content, key_); // time_stamp char buf[100]; - auto time_stamp = expired_timestamp_sec_; + auto time_stamp = expired_timestamp_millsec_ > 0 ? expired_timestamp_millsec_ / 1000 : expired_timestamp_millsec_; pstd::ll2string(buf, sizeof(buf), time_stamp); std::string at(buf); RedisAppendLenUint64(content, at.size(), "$"); @@ -632,7 +634,7 @@ void MgetCmd::AssembleResponseFromCache() { void MgetCmd::Do() { // Without using the cache and querying only the DB, we need to use keys_. // This line will only be assigned when querying the DB directly. - if(cache_miss_keys_.size() == 0) { + if (cache_miss_keys_.size() == 0) { cache_miss_keys_ = keys_; } db_value_status_array_.clear(); @@ -704,7 +706,8 @@ void MgetCmd::DoUpdateCache() { size_t db_index = 0; for (const auto key : cache_miss_keys_) { if (db_index < db_value_status_array_.size() && db_value_status_array_[db_index].status.ok()) { - db_->cache()->WriteKVToCache(const_cast(key), db_value_status_array_[db_index].value, db_value_status_array_[db_index].ttl); + int64_t ttl_millsec = db_value_status_array_[db_index].ttl_millsec; + db_->cache()->WriteKVToCache(const_cast(key), db_value_status_array_[db_index].value, ttl_millsec > 0 ? ttl_millsec / 1000 : ttl_millsec); } db_index++; } @@ -838,7 +841,7 @@ void SetexCmd::DoInitial() { return; } key_ = argv_[1]; - if (pstd::string2int(argv_[2].data(), argv_[2].size(), &sec_) == 0) { + if (pstd::string2int(argv_[2].data(), argv_[2].size(), &ttl_sec_) == 0) { res_.SetRes(CmdRes::kInvalidInt); return; } @@ -846,7 +849,7 @@ void SetexCmd::DoInitial() { } void SetexCmd::Do() { - s_ = db_->storage()->Setex(key_, value_, sec_); + s_ = db_->storage()->Setex(key_, value_, ttl_sec_ * 1000); if (s_.ok()) { res_.SetRes(CmdRes::kOk); AddSlotKey("k", key_, db_); @@ -863,7 +866,7 @@ void SetexCmd::DoThroughDB() { void SetexCmd::DoUpdateCache() { if (s_.ok()) { - db_->cache()->Setxx(key_, value_, sec_); + db_->cache()->Setxx(key_, value_, ttl_sec_); } } @@ -881,7 +884,7 @@ std::string SetexCmd::ToRedisProtocol() { RedisAppendContent(content, key_); // time_stamp char buf[100]; - auto time_stamp = time(nullptr) + sec_; + auto time_stamp = time(nullptr) + ttl_sec_; pstd::ll2string(buf, 100, time_stamp); std::string at(buf); RedisAppendLenUint64(content, at.size(), "$"); @@ -898,7 +901,7 @@ void PsetexCmd::DoInitial() { return; } key_ = argv_[1]; - if (pstd::string2int(argv_[2].data(), argv_[2].size(), &usec_) == 0) { + if (pstd::string2int(argv_[2].data(), argv_[2].size(), &ttl_millsec) == 0) { res_.SetRes(CmdRes::kInvalidInt); return; } @@ -906,7 +909,7 @@ void PsetexCmd::DoInitial() { } void PsetexCmd::Do() { - s_ = db_->storage()->Setex(key_, value_, usec_ / 1000); + s_ = db_->storage()->Setex(key_, value_, ttl_millsec); if (s_.ok()) { res_.SetRes(CmdRes::kOk); } else if (s_.IsInvalidArgument()) { @@ -922,7 +925,7 @@ void PsetexCmd::DoThroughDB() { void PsetexCmd::DoUpdateCache() { if (s_.ok()) { - db_->cache()->Setxx(key_, value_, usec_ / 1000); + db_->cache()->Setxx(key_, value_, ttl_millsec / 1000); } } @@ -940,7 +943,7 @@ std::string PsetexCmd::ToRedisProtocol() { RedisAppendContent(content, key_); // time_stamp char buf[100]; - auto time_stamp = time(nullptr) + usec_ / 1000; + auto time_stamp = pstd::NowMillis() + ttl_millsec; pstd::ll2string(buf, 100, time_stamp); std::string at(buf); RedisAppendLenUint64(content, at.size(), "$"); @@ -1047,7 +1050,7 @@ void MsetCmd::DoBinlog() { set_argv[0] = "set"; set_cmd_->SetConn(GetConn()); set_cmd_->SetResp(resp_.lock()); - for(auto& kv: kvs_){ + for(auto& kv: kvs_) { set_argv[1] = kv.key; set_argv[2] = kv.value; set_cmd_->Initial(set_argv, db_name_); @@ -1235,7 +1238,7 @@ void StrlenCmd::ReadCache() { void StrlenCmd::DoThroughDB() { res_.clear(); - s_ = db_->storage()->GetWithTTL(key_, &value_, &sec_); + s_ = db_->storage()->GetWithTTL(key_, &value_, &ttl_millsec); if (s_.ok() || s_.IsNotFound()) { res_.AppendInteger(value_.size()); } else { @@ -1245,7 +1248,7 @@ void StrlenCmd::DoThroughDB() { void StrlenCmd::DoUpdateCache() { if (s_.ok()) { - db_->cache()->WriteKVToCache(key_, value_, sec_); + db_->cache()->WriteKVToCache(key_, value_, ttl_millsec > 0 ? ttl_millsec : ttl_millsec / 1000); } } @@ -1302,14 +1305,14 @@ void ExpireCmd::DoInitial() { return; } key_ = argv_[1]; - if (pstd::string2int(argv_[2].data(), argv_[2].size(), &sec_) == 0) { + if (pstd::string2int(argv_[2].data(), argv_[2].size(), &ttl_sec_) == 0) { res_.SetRes(CmdRes::kInvalidInt); return; } } void ExpireCmd::Do() { - int32_t res = db_->storage()->Expire(key_, sec_); + int32_t res = db_->storage()->Expire(key_, ttl_sec_ * 1000); if (res != -1) { res_.AppendInteger(res); s_ = rocksdb::Status::OK(); @@ -1333,7 +1336,7 @@ std::string ExpireCmd::ToRedisProtocol() { RedisAppendContent(content, key_); // sec char buf[100]; - int64_t expireat = time(nullptr) + sec_; + int64_t expireat = time(nullptr) + ttl_sec_; pstd::ll2string(buf, 100, expireat); std::string at(buf); RedisAppendLenUint64(content, at.size(), "$"); @@ -1347,7 +1350,7 @@ void ExpireCmd::DoThroughDB() { void ExpireCmd::DoUpdateCache() { if (s_.ok()) { - db_->cache()->Expire(key_, sec_); + db_->cache()->Expire(key_, ttl_sec_); } } @@ -1357,14 +1360,14 @@ void PexpireCmd::DoInitial() { return; } key_ = argv_[1]; - if (pstd::string2int(argv_[2].data(), argv_[2].size(), &msec_) == 0) { + if (pstd::string2int(argv_[2].data(), argv_[2].size(), &ttl_millsec) == 0) { res_.SetRes(CmdRes::kInvalidInt); return; } } void PexpireCmd::Do() { - int64_t res = db_->storage()->Expire(key_, msec_ / 1000); + int64_t res = db_->storage()->Expire(key_, ttl_millsec); if (res != -1) { res_.AppendInteger(res); s_ = rocksdb::Status::OK(); @@ -1379,8 +1382,8 @@ std::string PexpireCmd::ToRedisProtocol() { content.reserve(RAW_ARGS_LEN); RedisAppendLenUint64(content, argv_.size(), "*"); - // to expireat cmd - std::string expireat_cmd("expireat"); + // to pexpireat cmd + std::string expireat_cmd("pexpireat"); RedisAppendLenUint64(content, expireat_cmd.size(), "$"); RedisAppendContent(content, expireat_cmd); // key @@ -1388,7 +1391,7 @@ std::string PexpireCmd::ToRedisProtocol() { RedisAppendContent(content, key_); // sec char buf[100]; - int64_t expireat = time(nullptr) + msec_ / 1000; + int64_t expireat = pstd::NowMillis() + ttl_millsec; pstd::ll2string(buf, 100, expireat); std::string at(buf); RedisAppendLenUint64(content, at.size(), "$"); @@ -1396,13 +1399,13 @@ std::string PexpireCmd::ToRedisProtocol() { return content; } -void PexpireCmd::DoThroughDB(){ +void PexpireCmd::DoThroughDB() { Do(); } void PexpireCmd::DoUpdateCache() { if (s_.ok()) { - db_->cache()->Expire(key_, msec_ / 1000); + db_->cache()->Expire(key_, ttl_millsec); } } @@ -1412,14 +1415,14 @@ void ExpireatCmd::DoInitial() { return; } key_ = argv_[1]; - if (pstd::string2int(argv_[2].data(), argv_[2].size(), &time_stamp_) == 0) { + if (pstd::string2int(argv_[2].data(), argv_[2].size(), &time_stamp_sec_) == 0) { res_.SetRes(CmdRes::kInvalidInt); return; } } void ExpireatCmd::Do() { - int32_t res = db_->storage()->Expireat(key_, time_stamp_); + int32_t res = db_->storage()->Expireat(key_, time_stamp_sec_ * 1000); if (res != -1) { res_.AppendInteger(res); s_ = rocksdb::Status::OK(); @@ -1435,7 +1438,7 @@ void ExpireatCmd::DoThroughDB() { void ExpireatCmd::DoUpdateCache() { if (s_.ok()) { - db_->cache()->Expireat(key_, time_stamp_); + db_->cache()->Expireat(key_, time_stamp_sec_); } } @@ -1445,36 +1448,14 @@ void PexpireatCmd::DoInitial() { return; } key_ = argv_[1]; - if (pstd::string2int(argv_[2].data(), argv_[2].size(), &time_stamp_ms_) == 0) { + if (pstd::string2int(argv_[2].data(), argv_[2].size(), &time_stamp_millsec_) == 0) { res_.SetRes(CmdRes::kInvalidInt); return; } } -std::string PexpireatCmd::ToRedisProtocol() { - std::string content; - content.reserve(RAW_ARGS_LEN); - RedisAppendLenUint64(content, argv_.size(), "*"); - - // to expireat cmd - std::string expireat_cmd("expireat"); - RedisAppendLenUint64(content, expireat_cmd.size(), "$"); - RedisAppendContent(content, expireat_cmd); - // key - RedisAppendLenUint64(content, key_.size(), "$"); - RedisAppendContent(content, key_); - // sec - char buf[100]; - int64_t expireat = time_stamp_ms_ / 1000; - pstd::ll2string(buf, 100, expireat); - std::string at(buf); - RedisAppendLenUint64(content, at.size(), "$"); - RedisAppendContent(content, at); - return content; -} - void PexpireatCmd::Do() { - int32_t res = db_->storage()->Expireat(key_, static_cast(time_stamp_ms_ / 1000)); + int32_t res = db_->storage()->Expireat(key_, static_cast(time_stamp_millsec_)); if (res != -1) { res_.AppendInteger(res); s_ = rocksdb::Status::OK(); @@ -1490,7 +1471,7 @@ void PexpireatCmd::DoThroughDB() { void PexpireatCmd::DoUpdateCache() { if (s_.ok()) { - db_->cache()->Expireat(key_, time_stamp_ms_ / 1000); + db_->cache()->Expireat(key_, time_stamp_millsec_ / 1000); } } @@ -1503,11 +1484,11 @@ void TtlCmd::DoInitial() { } void TtlCmd::Do() { - int64_t timestamp = db_->storage()->TTL(key_); - if (timestamp == -3) { + int64_t ttl_sec_ = db_->storage()->TTL(key_); + if (ttl_sec_ == -3) { res_.SetRes(CmdRes::kErrOther, "ttl internal error"); } else { - res_.AppendInteger(timestamp); + res_.AppendInteger(ttl_sec_); } } @@ -1536,28 +1517,17 @@ void PttlCmd::DoInitial() { } void PttlCmd::Do() { - int64_t timestamp = db_->storage()->TTL(key_); - if (timestamp == -3) { + int64_t ttl_millsec = db_->storage()->PTTL(key_); + if (ttl_millsec == -3) { res_.SetRes(CmdRes::kErrOther, "ttl internal error"); } else { - res_.AppendInteger(timestamp); + res_.AppendInteger(ttl_millsec); } } void PttlCmd::ReadCache() { - int64_t timestamp = db_->cache()->TTL(key_); - if (timestamp == -3) { - res_.SetRes(CmdRes::kErrOther, "ttl internal error"); - } else if (timestamp != -2) { - if (timestamp == -1) { - res_.AppendInteger(-1); - } else { - res_.AppendInteger(timestamp * 1000); - } - } else { - // mean this key not exist - res_.SetRes(CmdRes::kCacheMiss); - } + // redis cache don't support pttl cache, so read directly from db + DoThroughDB(); } void PttlCmd::DoThroughDB() { @@ -1790,14 +1760,14 @@ void PKSetexAtCmd::DoInitial() { } key_ = argv_[1]; value_ = argv_[3]; - if ((pstd::string2int(argv_[2].data(), argv_[2].size(), &time_stamp_) == 0) || time_stamp_ >= INT32_MAX) { + if ((pstd::string2int(argv_[2].data(), argv_[2].size(), &time_stamp_sec_) == 0) || time_stamp_sec_ >= INT32_MAX) { res_.SetRes(CmdRes::kInvalidInt); return; } } void PKSetexAtCmd::Do() { - s_ = db_->storage()->PKSetexAt(key_, value_, static_cast(time_stamp_)); + s_ = db_->storage()->PKSetexAt(key_, value_, static_cast(time_stamp_sec_ * 1000)); if (s_.ok()) { res_.SetRes(CmdRes::kOk); } else if (s_.IsInvalidArgument()) { @@ -1813,7 +1783,7 @@ void PKSetexAtCmd::DoThroughDB() { void PKSetexAtCmd::DoUpdateCache() { if (s_.ok()) { - auto expire = time_stamp_ - static_cast(std::time(nullptr)); + auto expire = time_stamp_sec_ - static_cast(std::time(nullptr)); if (expire <= 0) [[unlikely]] { db_->cache()->Del({key_}); return; diff --git a/src/pika_list.cc b/src/pika_list.cc index 35004fd6a4..9cec350baa 100644 --- a/src/pika_list.cc +++ b/src/pika_list.cc @@ -130,7 +130,7 @@ void LLenCmd::Do() { void LLenCmd::ReadCache() { uint64_t llen = 0; auto s = db_->cache()->LLen(key_, &llen); - if (s.ok()){ + if (s.ok()) { res_.AppendInteger(llen); } else if (s.IsNotFound()) { res_.SetRes(CmdRes::kCacheMiss); diff --git a/src/pika_server.cc b/src/pika_server.cc index 7b8995ea24..c40fc3bbbf 100644 --- a/src/pika_server.cc +++ b/src/pika_server.cc @@ -611,7 +611,7 @@ int32_t PikaServer::GetSlaveListString(std::string& slave_list_str) { master_boffset.offset - sent_slave_boffset.offset; tmp_stream << "(" << db->DBName() << ":" << lag << ")"; } - } else if (s.ok() && slave_state == SlaveState::kSlaveDbSync){ + } else if (s.ok() && slave_state == SlaveState::kSlaveDbSync) { tmp_stream << "(" << db->DBName() << ":full syncing)"; } else { tmp_stream << "(" << db->DBName() << ":not syncing)"; @@ -1599,7 +1599,7 @@ void DoBgslotsreload(void* arg) { rocksdb::Status s; std::vector keys; int64_t cursor_ret = -1; - while(cursor_ret != 0 && p->GetSlotsreloading()){ + while(cursor_ret != 0 && p->GetSlotsreloading()) { cursor_ret = reload.db->storage()->Scan(storage::DataType::kAll, reload.cursor, reload.pattern, reload.count, &keys); std::vector::const_iterator iter; @@ -1607,8 +1607,8 @@ void DoBgslotsreload(void* arg) { std::string key_type; int s = GetKeyType(*iter, key_type, reload.db); //if key is slotkey, can't add to SlotKey - if (s > 0){ - if (key_type == "s" && ((*iter).find(SlotKeyPrefix) != std::string::npos || (*iter).find(SlotTagPrefix) != std::string::npos)){ + if (s > 0) { + if (key_type == "s" && ((*iter).find(SlotKeyPrefix) != std::string::npos || (*iter).find(SlotTagPrefix) != std::string::npos)) { continue; } @@ -1716,7 +1716,7 @@ void DoBgslotscleanup(void* arg) { std::vector keys; int64_t cursor_ret = -1; std::vector cleanupSlots(cleanup.cleanup_slots); - while (cursor_ret != 0 && p->GetSlotscleaningup()){ + while (cursor_ret != 0 && p->GetSlotscleaningup()) { cursor_ret = g_pika_server->bgslots_cleanup_.db->storage()->Scan(storage::DataType::kAll, cleanup.cursor, cleanup.pattern, cleanup.count, &keys); std::string key_type; @@ -1725,12 +1725,12 @@ void DoBgslotscleanup(void* arg) { if ((*iter).find(SlotKeyPrefix) != std::string::npos || (*iter).find(SlotTagPrefix) != std::string::npos) { continue; } - if (std::find(cleanupSlots.begin(), cleanupSlots.end(), GetSlotID(g_pika_conf->default_slot_num(), *iter)) != cleanupSlots.end()){ + if (std::find(cleanupSlots.begin(), cleanupSlots.end(), GetSlotID(g_pika_conf->default_slot_num(), *iter)) != cleanupSlots.end()) { if (GetKeyType(*iter, key_type, g_pika_server->bgslots_cleanup_.db) <= 0) { LOG(WARNING) << "slots clean get key type for slot " << GetSlotID(g_pika_conf->default_slot_num(), *iter) << " key " << *iter << " error"; continue; } - if (DeleteKey(*iter, key_type[0], g_pika_server->bgslots_cleanup_.db) <= 0){ + if (DeleteKey(*iter, key_type[0], g_pika_server->bgslots_cleanup_.db) <= 0) { LOG(WARNING) << "slots clean del for slot " << GetSlotID(g_pika_conf->default_slot_num(), *iter) << " key "<< *iter << " error"; } } @@ -1741,7 +1741,7 @@ void DoBgslotscleanup(void* arg) { keys.clear(); } - for (int cleanupSlot : cleanupSlots){ + for (int cleanupSlot : cleanupSlots) { WriteDelKeyToBinlog(GetSlotKey(cleanupSlot), g_pika_server->bgslots_cleanup_.db); WriteDelKeyToBinlog(GetSlotsTagKey(cleanupSlot), g_pika_server->bgslots_cleanup_.db); } diff --git a/src/pika_zset.cc b/src/pika_zset.cc index 43da6e3b9f..ad8abd1423 100644 --- a/src/pika_zset.cc +++ b/src/pika_zset.cc @@ -77,7 +77,7 @@ void ZCardCmd::Do() { } } -void ZCardCmd::ReadCache(){ +void ZCardCmd::ReadCache() { res_.SetRes(CmdRes::kCacheMiss); } @@ -590,7 +590,7 @@ void ZRevrangebyscoreCmd::Do() { } } -void ZRevrangebyscoreCmd::ReadCache(){ +void ZRevrangebyscoreCmd::ReadCache() { if (min_score_ == storage::ZSET_SCORE_MAX || max_score_ == storage::ZSET_SCORE_MIN || max_score_ < min_score_) { res_.AppendContent("*0"); @@ -827,7 +827,7 @@ void ZUnionstoreCmd::DoBinlog() { del_cmd->SetResp(resp_.lock()); del_cmd->DoBinlog(); - if(value_to_dest_.empty()){ + if (value_to_dest_.empty()) { // The union operation got an empty set, only use del to simulate overwrite the dest_key with empty set return; } @@ -975,7 +975,7 @@ void ZRankCmd::ReadCache() { auto s = db_->cache()->ZRank(key_, member_, &rank, db_); if (s.ok()) { res_.AppendInteger(rank); - } else if (s.IsNotFound()){ + } else if (s.IsNotFound()) { res_.SetRes(CmdRes::kCacheMiss); } else { res_.SetRes(CmdRes::kErrOther, s.ToString()); @@ -1020,7 +1020,7 @@ void ZRevrankCmd::ReadCache() { auto s = db_->cache()->ZRevrank(key_, member_, &revrank, db_); if (s.ok()) { res_.AppendInteger(revrank); - } else if (s.IsNotFound()){ + } else if (s.IsNotFound()) { res_.SetRes(CmdRes::kCacheMiss); } else { res_.SetRes(CmdRes::kErrOther, s.ToString()); diff --git a/src/pstd/include/env.h b/src/pstd/include/env.h index 8e8cbbaa37..f11680206f 100644 --- a/src/pstd/include/env.h +++ b/src/pstd/include/env.h @@ -17,6 +17,8 @@ class SequentialFile; class RWFile; class RandomRWFile; +using TimeType = uint64_t; + /* * Set the resource limits of a process */ @@ -61,7 +63,10 @@ class FileLock : public pstd::noncopyable { int GetChildren(const std::string& dir, std::vector& result); void GetDescendant(const std::string& dir, std::vector& result); -uint64_t NowMicros(); +TimeType NowMicros(); + +TimeType NowMillis(); + void SleepForMicroseconds(int micros); Status NewSequentialFile(const std::string& fname, std::unique_ptr& result); diff --git a/src/pstd/src/env.cc b/src/pstd/src/env.cc index 7dadf924ea..1abfe35cf2 100644 --- a/src/pstd/src/env.cc +++ b/src/pstd/src/env.cc @@ -217,11 +217,16 @@ uint64_t Du(const std::string& path) { return sum; } -uint64_t NowMicros() { +TimeType NowMicros() { auto now = std::chrono::system_clock::now(); return std::chrono::duration_cast(now.time_since_epoch()).count(); } +TimeType NowMillis() { + auto now = std::chrono::system_clock::now(); + return std::chrono::duration_cast(now.time_since_epoch()).count(); +} + void SleepForMicroseconds(int micros) { std::this_thread::sleep_for(std::chrono::microseconds(micros)); } SequentialFile::~SequentialFile() = default; diff --git a/src/storage/include/storage/storage.h b/src/storage/include/storage/storage.h index f929fb2091..43318ed3aa 100644 --- a/src/storage/include/storage/storage.h +++ b/src/storage/include/storage/storage.h @@ -107,8 +107,8 @@ struct KeyInfo { struct ValueStatus { std::string value; Status status; - int64_t ttl; - bool operator==(const ValueStatus& vs) const { return (vs.value == value && vs.status == status && vs.ttl == ttl); } + int64_t ttl_millsec; + bool operator==(const ValueStatus& vs) const { return (vs.value == value && vs.status == status && vs.ttl_millsec == ttl_millsec); } }; struct FieldValue { @@ -192,7 +192,7 @@ class Storage { Status Set(const Slice& key, const Slice& value); // Set key to hold the string value. if key exist - Status Setxx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl = 0); + Status Setxx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl_millsec = 0); // Get the value of key. If the key does not exist // the special value nil is returned @@ -200,7 +200,7 @@ class Storage { // Get the value and ttl of key. If the key does not exist // the special value nil is returned. If the key has no ttl, ttl is -1 - Status GetWithTTL(const Slice& key, std::string* value, int64_t* ttl); + Status GetWithTTL(const Slice& key, std::string* value, int64_t* ttl_millsec); // Atomically sets key to value and returns the old value stored at key // Returns an error when key exists but does not hold a string value. @@ -229,7 +229,7 @@ class Storage { // Set key to hold string value if key does not exist // return 1 if the key was set // return 0 if the key was not set - Status Setnx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl = 0); + Status Setnx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl_millsec = 0); // Sets the given keys to their respective values. // MSETNX will not perform any operation at all even @@ -240,7 +240,7 @@ class Storage { // return 1 if the key currently hold the give value And override success // return 0 if the key doesn't exist And override fail // return -1 if the key currently does not hold the given value And override fail - Status Setvx(const Slice& key, const Slice& value, const Slice& new_value, int32_t* ret, int64_t ttl = 0); + Status Setvx(const Slice& key, const Slice& value, const Slice& new_value, int32_t* ret, int64_t ttl_millsec = 0); // delete the key that holds a given value // return 1 if the key currently hold the give value And delete success @@ -257,12 +257,12 @@ class Storage { Status Getrange(const Slice& key, int64_t start_offset, int64_t end_offset, std::string* ret); Status GetrangeWithValue(const Slice& key, int64_t start_offset, int64_t end_offset, - std::string* ret, std::string* value, int64_t* ttl); + std::string* ret, std::string* value, int64_t* ttl_millsec); // If key already exists and is a string, this command appends the value at // the end of the string // return the length of the string after the append operation - Status Append(const Slice& key, const Slice& value, int32_t* ret, int64_t* expired_timestamp_sec, std::string& out_new_value); + Status Append(const Slice& key, const Slice& value, int32_t* ret, int64_t* expired_timestamp_millsec, std::string& out_new_value); // Count the number of set bits (population counting) in a string. // return the number of bits set to 1 @@ -287,7 +287,7 @@ class Storage { // Increments the number stored at key by increment. // If the key does not exist, it is set to 0 before performing the operation - Status Incrby(const Slice& key, int64_t value, int64_t* ret, int64_t* expired_timestamp_sec); + Status Incrby(const Slice& key, int64_t value, int64_t* ret, int64_t* expired_timestamp_millsec); // Increment the string representing a floating point number // stored at key by the specified increment. @@ -295,7 +295,7 @@ class Storage { // Set key to hold the string value and set key to timeout after a given // number of seconds - Status Setex(const Slice& key, const Slice& value, int64_t ttl); + Status Setex(const Slice& key, const Slice& value, int64_t ttl_millsec); // Returns the length of the string value stored at key. An error // is returned when key holds a non-string value. @@ -305,7 +305,7 @@ class Storage { // specifying the number of seconds representing the TTL (time to live), it // takes an absolute Unix timestamp (seconds since January 1, 1970). A // timestamp in the past will delete the key immediately. - Status PKSetexAt(const Slice& key, const Slice& value, int64_t timestamp); + Status PKSetexAt(const Slice& key, const Slice& value, int64_t time_stamp_millsec_); // Hashes Commands @@ -336,7 +336,7 @@ class Storage { // reply is twice the size of the hash. Status HGetall(const Slice& key, std::vector* fvs); - Status HGetallWithTTL(const Slice& key, std::vector* fvs, int64_t* ttl); + Status HGetallWithTTL(const Slice& key, std::vector* fvs, int64_t* ttl_millsec); // Returns all field names in the hash stored at key. Status HKeys(const Slice& key, std::vector* fields); @@ -469,7 +469,7 @@ class Storage { // This has the same effect as running SINTER with one argument key. Status SMembers(const Slice& key, std::vector* members); - Status SMembersWithTTL(const Slice& key, std::vector* members, int64_t *ttl); + Status SMembersWithTTL(const Slice& key, std::vector* members, int64_t * ttl_millsec); // Remove the specified members from the set stored at key. Specified members // that are not a member of this set are ignored. If key does not exist, it is @@ -542,7 +542,7 @@ class Storage { // (the head of the list), 1 being the next element and so on. Status LRange(const Slice& key, int64_t start, int64_t stop, std::vector* ret); - Status LRangeWithTTL(const Slice& key, int64_t start, int64_t stop, std::vector* ret, int64_t *ttl); + Status LRangeWithTTL(const Slice& key, int64_t start, int64_t stop, std::vector* ret, int64_t * ttl_millsec); // Removes the first count occurrences of elements equal to value from the // list stored at key. The count argument influences the operation in the @@ -705,7 +705,7 @@ class Storage { Status ZRange(const Slice& key, int32_t start, int32_t stop, std::vector* score_members); Status ZRangeWithTTL(const Slice& key, int32_t start, int32_t stop, std::vector* score_members, - int64_t *ttl); + int64_t * ttl_millsec); // Returns all the elements in the sorted set at key with a score between min // and max (including elements with score equal to min or max). The elements @@ -959,10 +959,10 @@ class Storage { // While any error happens, you need to check type_status for // the error message - // Set a timeout on key + // Set a timeout on key, milliseconds unit // return -1 operation exception errors happen in database // return >=0 success - int32_t Expire(const Slice& key, int64_t ttl); + int32_t Expire(const Slice& key, int64_t ttl_millsec); // Removes the specified keys // return -1 operation exception errors happen in database @@ -1007,12 +1007,12 @@ class Storage { // EXPIREAT has the same effect and semantic as EXPIRE, but instead of // specifying the number of seconds representing the TTL (time to live), it - // takes an absolute Unix timestamp (seconds since January 1, 1970). A + // takes an absolute Unix timestamp (milliseconds since January 1, 1970). A // timestamp in the past will delete the key immediately. // return -1 operation exception errors happen in database // return 0 if key does not exist // return >=1 if the timueout was set - int32_t Expireat(const Slice& key, int64_t timestamp); + int32_t Expireat(const Slice& key, int64_t timestamp_millsec); // Remove the existing timeout on key, turning the key from volatile (a key // with an expire set) to persistent (a key that will never expire as no @@ -1029,6 +1029,13 @@ class Storage { // return > 0 TTL in seconds int64_t TTL(const Slice& key); + // Returns the remaining time to live of a key that has a timeout. + // return -3 operation exception errors happen in database + // return -2 if the key does not exist + // return -1 if the key exists but has not associated expire + // return > 0 TTL in milliseconds + int64_t PTTL(const Slice& key); + // Reutrns the data all type of the key // if single is true, the query will return the first one Status GetType(const std::string& key, enum DataType& type); @@ -1122,7 +1129,7 @@ class Storage { // For scan keys in data base std::atomic scan_keynum_exit_ = {false}; - Status MGetWithTTL(const Slice& key, std::string* value, int64_t* ttl); + Status MGetWithTTL(const Slice& key, std::string* value, int64_t* ttl_millsec); }; } // namespace storage diff --git a/src/storage/src/base_data_value_format.h b/src/storage/src/base_data_value_format.h index 41648b11ef..be6735f54c 100644 --- a/src/storage/src/base_data_value_format.h +++ b/src/storage/src/base_data_value_format.h @@ -40,7 +40,8 @@ class BaseDataValue : public InternalValue { dst += user_value_.size(); memcpy(dst, reserve_, kSuffixReserveLength); dst += kSuffixReserveLength; - EncodeFixed64(dst, ctime_); + uint64_t ctime = ctime_ > 0 ? (ctime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, ctime); dst += kTimestampLength; return rocksdb::Slice(start_pos, needed); } @@ -58,7 +59,8 @@ class ParsedBaseDataValue : public ParsedInternalValue { if (value_->size() >= kBaseDataValueSuffixLength) { user_value_ = rocksdb::Slice(value_->data(), value_->size() - kBaseDataValueSuffixLength); memcpy(reserve_, value_->data() + user_value_.size(), kSuffixReserveLength); - ctime_ = DecodeFixed64(value_->data() + user_value_.size() + kSuffixReserveLength); + uint64_t ctime = DecodeFixed64(value_->data() + user_value_.size() + kSuffixReserveLength); + ctime_ = (ctime & ~(1ULL << 63)); } } @@ -70,7 +72,8 @@ class ParsedBaseDataValue : public ParsedInternalValue { if (value.size() >= kBaseDataValueSuffixLength) { user_value_ = rocksdb::Slice(value.data(), value.size() - kBaseDataValueSuffixLength); memcpy(reserve_, value.data() + user_value_.size(), kSuffixReserveLength); - ctime_ = DecodeFixed64(value.data() + user_value_.size() + kSuffixReserveLength); + uint64_t ctime = DecodeFixed64(value.data() + user_value_.size() + kSuffixReserveLength); + ctime_ = (ctime & ~(1ULL << 63)); } } @@ -81,7 +84,8 @@ class ParsedBaseDataValue : public ParsedInternalValue { void SetCtimeToValue() override { if (value_) { char* dst = const_cast(value_->data()) + value_->size() - kTimestampLength; - EncodeFixed64(dst, ctime_); + uint64_t ctime = ctime_ > 0 ? (ctime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, ctime); } } diff --git a/src/storage/src/base_filter.h b/src/storage/src/base_filter.h index 5dd17b09c6..934b2d96d7 100644 --- a/src/storage/src/base_filter.h +++ b/src/storage/src/base_filter.h @@ -28,9 +28,7 @@ class BaseMetaFilter : public rocksdb::CompactionFilter { BaseMetaFilter() = default; bool Filter(int level, const rocksdb::Slice& key, const rocksdb::Slice& value, std::string* new_value, bool* value_changed) const override { - int64_t unix_time; - rocksdb::Env::Default()->GetCurrentTime(&unix_time); - auto cur_time = static_cast(unix_time); + auto cur_time = pstd::NowMillis(); /* * For the filtering of meta information, because the field designs of string * and list are different, their filtering policies are written separately. @@ -181,9 +179,8 @@ class BaseDataFilter : public rocksdb::CompactionFilter { return true; } - int64_t unix_time; - rocksdb::Env::Default()->GetCurrentTime(&unix_time); - if (cur_meta_etime_ != 0 && cur_meta_etime_ < static_cast(unix_time)) { + pstd::TimeType unix_time = pstd::NowMillis(); + if (cur_meta_etime_ != 0 && cur_meta_etime_ < unix_time) { TRACE("Drop[Timeout]"); return true; } diff --git a/src/storage/src/base_meta_value_format.h b/src/storage/src/base_meta_value_format.h index 150774479a..588c980624 100644 --- a/src/storage/src/base_meta_value_format.h +++ b/src/storage/src/base_meta_value_format.h @@ -39,18 +39,22 @@ class BaseMetaValue : public InternalValue { dst += sizeof(version_); memcpy(dst, reserve_, sizeof(reserve_)); dst += sizeof(reserve_); - EncodeFixed64(dst, ctime_); + // The most significant bit is 1 for milliseconds and 0 for seconds. + // The previous data was stored in seconds, but the subsequent data was stored in milliseconds + uint64_t ctime = ctime_ > 0 ? (ctime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, ctime); dst += sizeof(ctime_); - EncodeFixed64(dst, etime_); + uint64_t etime = etime_ > 0 ? (etime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, etime); return {start_, needed}; } uint64_t UpdateVersion() { - int64_t unix_time = pstd::NowMicros() / 1000000; + pstd::TimeType unix_time = pstd::NowMillis(); if (version_ >= unix_time) { version_++; } else { - version_ = uint64_t(unix_time); + version_ = unix_time; } return version_; } @@ -71,9 +75,20 @@ class ParsedBaseMetaValue : public ParsedInternalValue { offset += sizeof(version_); memcpy(reserve_, internal_value_str->data() + offset, sizeof(reserve_)); offset += sizeof(reserve_); - ctime_ = DecodeFixed64(internal_value_str->data() + offset); + uint64_t ctime = DecodeFixed64(internal_value_str->data() + offset); offset += sizeof(ctime_); - etime_ = DecodeFixed64(internal_value_str->data() + offset); + uint64_t etime = DecodeFixed64(internal_value_str->data() + offset); + + ctime_ = (ctime & ~(1ULL << 63)); + // if ctime_==ctime, means ctime_ storaged in seconds + if (ctime_ == ctime) { + ctime_ *= 1000; + } + etime_ = (etime & ~(1ULL << 63)); + // if etime_==etime, means etime_ storaged in seconds + if (etime == etime_) { + etime_ *= 1000; + } } count_ = DecodeFixed32(internal_value_str->data() + kTypeLength); } @@ -91,9 +106,20 @@ class ParsedBaseMetaValue : public ParsedInternalValue { offset += sizeof(uint64_t); memcpy(reserve_, internal_value_slice.data() + offset, sizeof(reserve_)); offset += sizeof(reserve_); - ctime_ = DecodeFixed64(internal_value_slice.data() + offset); + uint64_t ctime = DecodeFixed64(internal_value_slice.data() + offset); offset += sizeof(ctime_); - etime_ = DecodeFixed64(internal_value_slice.data() + offset); + uint64_t etime = DecodeFixed64(internal_value_slice.data() + offset); + + ctime_ = (ctime & ~(1ULL << 63)); + // if ctime_!=ctime, means ctime_ storaged in seconds + if (ctime_ == ctime) { + ctime_ *= 1000; + } + etime_ = (etime & ~(1ULL << 63)); + // if etime_!=etime, means etime_ storaged in seconds + if (etime == etime_) { + etime_ *= 1000; + } } count_ = DecodeFixed32(internal_value_slice.data() + kTypeLength); } @@ -114,14 +140,16 @@ class ParsedBaseMetaValue : public ParsedInternalValue { void SetCtimeToValue() override { if (value_) { char* dst = const_cast(value_->data()) + value_->size() - 2 * kTimestampLength; - EncodeFixed64(dst, ctime_); + uint64_t ctime = ctime_ > 0 ? (ctime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, ctime); } } void SetEtimeToValue() override { if (value_) { char* dst = const_cast(value_->data()) + value_->size() - kTimestampLength; - EncodeFixed64(dst, etime_); + uint64_t etime = etime_ > 0 ? (etime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, etime); } } @@ -171,12 +199,11 @@ class ParsedBaseMetaValue : public ParsedInternalValue { } uint64_t UpdateVersion() { - int64_t unix_time; - rocksdb::Env::Default()->GetCurrentTime(&unix_time); - if (version_ >= static_cast(unix_time)) { + pstd::TimeType unix_time = pstd::NowMillis(); + if (version_ >= unix_time) { version_++; } else { - version_ = static_cast(unix_time); + version_ = unix_time; } SetVersionToValue(); return version_; diff --git a/src/storage/src/base_value_format.h b/src/storage/src/base_value_format.h index 3f0f181f97..14e0175f46 100644 --- a/src/storage/src/base_value_format.h +++ b/src/storage/src/base_value_format.h @@ -41,7 +41,7 @@ constexpr char DataTypeToTag(DataType type) { class InternalValue { public: explicit InternalValue(DataType type, const rocksdb::Slice& user_value) : type_(type), user_value_(user_value) { - ctime_ = pstd::NowMicros() / 1e6; + ctime_ = pstd::NowMillis(); } virtual ~InternalValue() { @@ -51,10 +51,9 @@ class InternalValue { } void SetEtime(uint64_t etime = 0) { etime_ = etime; } void setCtime(uint64_t ctime) { ctime_ = ctime; } - rocksdb::Status SetRelativeTimestamp(int64_t ttl) { - int64_t unix_time; - rocksdb::Env::Default()->GetCurrentTime(&unix_time); - etime_ = uint64_t(unix_time + ttl); + rocksdb::Status SetRelativeTimeInMillsec(int64_t ttl_millsec) { + pstd::TimeType unix_time = pstd::NowMillis(); + etime_ = unix_time + ttl_millsec; return rocksdb::Status::OK(); } void SetVersion(uint64_t version = 0) { version_ = version; } @@ -122,10 +121,9 @@ class ParsedInternalValue { SetCtimeToValue(); } - void SetRelativeTimestamp(int64_t ttl) { - int64_t unix_time; - rocksdb::Env::Default()->GetCurrentTime(&unix_time); - etime_ = unix_time + ttl; + void SetRelativeTimestamp(int64_t ttl_millsec) { + pstd::TimeType unix_time = pstd::NowMillis(); + etime_ = unix_time + ttl_millsec; SetEtimeToValue(); } @@ -135,8 +133,7 @@ class ParsedInternalValue { if (etime_ == 0) { return false; } - int64_t unix_time; - rocksdb::Env::Default()->GetCurrentTime(&unix_time); + pstd::TimeType unix_time = pstd::NowMillis(); return etime_ < unix_time; } diff --git a/src/storage/src/lists_filter.h b/src/storage/src/lists_filter.h index a5d8ccb1a6..92186d5149 100644 --- a/src/storage/src/lists_filter.h +++ b/src/storage/src/lists_filter.h @@ -88,8 +88,7 @@ class ListsDataFilter : public rocksdb::CompactionFilter { return true; } - int64_t unix_time; - rocksdb::Env::Default()->GetCurrentTime(&unix_time); + pstd::TimeType unix_time = pstd::NowMillis(); if (cur_meta_etime_ != 0 && cur_meta_etime_ < static_cast(unix_time)) { TRACE("Drop[Timeout]"); return true; diff --git a/src/storage/src/lists_meta_value_format.h b/src/storage/src/lists_meta_value_format.h index c860ed9e12..b417d9a186 100644 --- a/src/storage/src/lists_meta_value_format.h +++ b/src/storage/src/lists_meta_value_format.h @@ -44,15 +44,18 @@ class ListsMetaValue : public InternalValue { dst += kListValueIndexLength; memcpy(dst, reserve_, sizeof(reserve_)); dst += kSuffixReserveLength; - EncodeFixed64(dst, ctime_); + // The most significant bit is 1 for milliseconds and 0 for seconds. + // The previous data was stored in seconds, but the subsequent data was stored in milliseconds + uint64_t ctime = ctime_ > 0 ? (ctime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, ctime); dst += kTimestampLength; - EncodeFixed64(dst, etime_); + uint64_t etime = etime_ > 0 ? (etime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, etime); return {start_, needed}; } uint64_t UpdateVersion() { - int64_t unix_time; - rocksdb::Env::Default()->GetCurrentTime(&unix_time); + pstd::TimeType unix_time = pstd::NowMillis(); if (version_ >= static_cast(unix_time)) { version_++; } else { @@ -95,10 +98,21 @@ class ParsedListsMetaValue : public ParsedInternalValue { offset += kListValueIndexLength; memcpy(reserve_, internal_value_str->data() + offset, sizeof(reserve_)); offset += kSuffixReserveLength; - ctime_ = DecodeFixed64(internal_value_str->data() + offset); + uint64_t ctime = DecodeFixed64(internal_value_str->data() + offset); offset += kTimestampLength; - etime_ = DecodeFixed64(internal_value_str->data() + offset); + uint64_t etime = DecodeFixed64(internal_value_str->data() + offset); offset += kTimestampLength; + + ctime_ = (ctime & ~(1ULL << 63)); + // if ctime_==ctime, means ctime_ storaged in seconds + if (ctime_ == ctime) { + ctime_ *= 1000; + } + etime_ = (etime & ~(1ULL << 63)); + // if etime_==etime, means etime_ storaged in seconds + if (etime == etime_) { + etime_ *= 1000; + } } count_ = DecodeFixed64(internal_value_str->data() + kTypeLength); } @@ -122,10 +136,21 @@ class ParsedListsMetaValue : public ParsedInternalValue { offset += kListValueIndexLength; memcpy(reserve_, internal_value_slice.data() + offset, sizeof(reserve_)); offset += kSuffixReserveLength; - ctime_ = DecodeFixed64(internal_value_slice.data() + offset); + uint64_t ctime = DecodeFixed64(internal_value_slice.data() + offset); offset += kTimestampLength; - etime_ = DecodeFixed64(internal_value_slice.data() + offset); + uint64_t etime = DecodeFixed64(internal_value_slice.data() + offset); offset += kTimestampLength; + + ctime_ = (ctime & ~(1ULL << 63)); + // if ctime_==ctime, means ctime_ storaged in seconds + if (ctime_ == ctime) { + ctime_ *= 1000; + } + etime_ = (etime & ~(1ULL << 63)); + // if etime_==etime, means etime_ storaged in seconds + if (etime == etime_) { + etime_ *= 1000; + } } count_ = DecodeFixed64(internal_value_slice.data() + kTypeLength); } @@ -146,14 +171,16 @@ class ParsedListsMetaValue : public ParsedInternalValue { void SetCtimeToValue() override { if (value_) { char* dst = const_cast(value_->data()) + value_->size() - 2 * kTimestampLength; - EncodeFixed64(dst, ctime_); + uint64_t ctime = ctime_ > 0 ? (ctime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, ctime); } } void SetEtimeToValue() override { if (value_) { char* dst = const_cast(value_->data()) + value_->size() - kTimestampLength; - EncodeFixed64(dst, etime_); + uint64_t etime = etime_ > 0 ? (etime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, etime); } } @@ -198,8 +225,7 @@ class ParsedListsMetaValue : public ParsedInternalValue { } uint64_t UpdateVersion() { - int64_t unix_time; - rocksdb::Env::Default()->GetCurrentTime(&unix_time); + pstd::TimeType unix_time = pstd::NowMillis(); if (version_ >= static_cast(unix_time)) { version_++; } else { diff --git a/src/storage/src/redis.h b/src/storage/src/redis.h index 8d23a43118..8bc87f5943 100644 --- a/src/storage/src/redis.h +++ b/src/storage/src/redis.h @@ -117,11 +117,11 @@ class Redis { Status ScanStreamsKeyNum(KeyInfo* key_info); // Keys Commands - virtual Status StringsExpire(const Slice& key, int64_t ttl, std::string&& prefetch_meta = {}); - virtual Status HashesExpire(const Slice& key, int64_t ttl, std::string&& prefetch_meta = {}); - virtual Status ListsExpire(const Slice& key, int64_t ttl, std::string&& prefetch_meta = {}); - virtual Status ZsetsExpire(const Slice& key, int64_t ttl, std::string&& prefetch_meta = {}); - virtual Status SetsExpire(const Slice& key, int64_t ttl, std::string&& prefetch_meta = {}); + virtual Status StringsExpire(const Slice& key, int64_t ttl_millsec, std::string&& prefetch_meta = {}); + virtual Status HashesExpire(const Slice& key, int64_t ttl_millsec, std::string&& prefetch_meta = {}); + virtual Status ListsExpire(const Slice& key, int64_t ttl_millsec, std::string&& prefetch_meta = {}); + virtual Status ZsetsExpire(const Slice& key, int64_t ttl_millsec, std::string&& prefetch_meta = {}); + virtual Status SetsExpire(const Slice& key, int64_t ttl_millsec, std::string&& prefetch_meta = {}); virtual Status StringsDel(const Slice& key, std::string&& prefetch_meta = {}); virtual Status HashesDel(const Slice& key, std::string&& prefetch_meta = {}); @@ -130,11 +130,11 @@ class Redis { virtual Status SetsDel(const Slice& key, std::string&& prefetch_meta = {}); virtual Status StreamsDel(const Slice& key, std::string&& prefetch_meta = {}); - virtual Status StringsExpireat(const Slice& key, int64_t timestamp, std::string&& prefetch_meta = {}); - virtual Status HashesExpireat(const Slice& key, int64_t timestamp, std::string&& prefetch_meta = {}); - virtual Status ListsExpireat(const Slice& key, int64_t timestamp, std::string&& prefetch_meta = {}); - virtual Status SetsExpireat(const Slice& key, int64_t timestamp, std::string&& prefetch_meta = {}); - virtual Status ZsetsExpireat(const Slice& key, int64_t timestamp, std::string&& prefetch_meta = {}); + virtual Status StringsExpireat(const Slice& key, int64_t timestamp_millsec, std::string&& prefetch_meta = {}); + virtual Status HashesExpireat(const Slice& key, int64_t timestamp_millsec, std::string&& prefetch_meta = {}); + virtual Status ListsExpireat(const Slice& key, int64_t timestamp_millsec, std::string&& prefetch_meta = {}); + virtual Status SetsExpireat(const Slice& key, int64_t timestamp_millsec, std::string&& prefetch_meta = {}); + virtual Status ZsetsExpireat(const Slice& key, int64_t timestamp_millsec, std::string&& prefetch_meta = {}); virtual Status StringsPersist(const Slice& key, std::string&& prefetch_meta = {}); virtual Status HashesPersist(const Slice& key, std::string&& prefetch_meta = {}); @@ -142,38 +142,38 @@ class Redis { virtual Status ZsetsPersist(const Slice& key, std::string&& prefetch_meta = {}); virtual Status SetsPersist(const Slice& key, std::string&& prefetch_meta = {}); - virtual Status StringsTTL(const Slice& key, int64_t* timestamp, std::string&& prefetch_meta = {}); - virtual Status HashesTTL(const Slice& key, int64_t* timestamp, std::string&& prefetch_meta = {}); - virtual Status ListsTTL(const Slice& key, int64_t* timestamp, std::string&& prefetch_meta = {}); - virtual Status ZsetsTTL(const Slice& key, int64_t* timestamp, std::string&& prefetch_meta = {}); - virtual Status SetsTTL(const Slice& key, int64_t* timestamp, std::string&& prefetch_meta = {}); + virtual Status StringsTTL(const Slice& key, int64_t* ttl_millsec, std::string&& prefetch_meta = {}); + virtual Status HashesTTL(const Slice& key, int64_t* ttl_millsec, std::string&& prefetch_meta = {}); + virtual Status ListsTTL(const Slice& key, int64_t* ttl_millsec, std::string&& prefetch_meta = {}); + virtual Status ZsetsTTL(const Slice& key, int64_t* ttl_millsec, std::string&& prefetch_meta = {}); + virtual Status SetsTTL(const Slice& key, int64_t* ttl_millsec, std::string&& prefetch_meta = {}); // Strings Commands - Status Append(const Slice& key, const Slice& value, int32_t* ret, int64_t* expired_timestamp_sec, std::string& out_new_value); + Status Append(const Slice& key, const Slice& value, int32_t* ret, int64_t* expired_timestamp_millsec, std::string& out_new_value); Status BitCount(const Slice& key, int64_t start_offset, int64_t end_offset, int32_t* ret, bool have_range); Status BitOp(BitOpType op, const std::string& dest_key, const std::vector& src_keys, std::string &value_to_dest, int64_t* ret); Status Decrby(const Slice& key, int64_t value, int64_t* ret); Status Get(const Slice& key, std::string* value); Status HyperloglogGet(const Slice& key, std::string* value); Status MGet(const Slice& key, std::string* value); - Status GetWithTTL(const Slice& key, std::string* value, int64_t* ttl); - Status MGetWithTTL(const Slice& key, std::string* value, int64_t* ttl); + Status GetWithTTL(const Slice& key, std::string* value, int64_t* ttl_millsec); + Status MGetWithTTL(const Slice& key, std::string* value, int64_t* ttl_millsec); Status GetBit(const Slice& key, int64_t offset, int32_t* ret); Status Getrange(const Slice& key, int64_t start_offset, int64_t end_offset, std::string* ret); Status GetrangeWithValue(const Slice& key, int64_t start_offset, int64_t end_offset, - std::string* ret, std::string* value, int64_t* ttl); + std::string* ret, std::string* value, int64_t* ttl_millsec); Status GetSet(const Slice& key, const Slice& value, std::string* old_value); - Status Incrby(const Slice& key, int64_t value, int64_t* ret, int64_t* expired_timestamp_sec); + Status Incrby(const Slice& key, int64_t value, int64_t* ret, int64_t* expired_timestamp_millsec); Status Incrbyfloat(const Slice& key, const Slice& value, std::string* ret, int64_t* expired_timestamp_sec); Status MSet(const std::vector& kvs); Status MSetnx(const std::vector& kvs, int32_t* ret); Status Set(const Slice& key, const Slice& value); Status HyperloglogSet(const Slice& key, const Slice& value); - Status Setxx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl = 0); + Status Setxx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl_millsec = 0); Status SetBit(const Slice& key, int64_t offset, int32_t value, int32_t* ret); - Status Setex(const Slice& key, const Slice& value, int64_t ttl); - Status Setnx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl = 0); - Status Setvx(const Slice& key, const Slice& value, const Slice& new_value, int32_t* ret, int64_t ttl = 0); + Status Setex(const Slice& key, const Slice& value, int64_t ttl_millsec); + Status Setnx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl_millsec = 0); + Status Setvx(const Slice& key, const Slice& value, const Slice& new_value, int32_t* ret, int64_t ttl_millsec = 0); Status Delvx(const Slice& key, const Slice& value, int32_t* ret); Status Setrange(const Slice& key, int64_t start_offset, const Slice& value, int32_t* ret); Status Strlen(const Slice& key, int32_t* len); @@ -181,14 +181,14 @@ class Redis { Status BitPos(const Slice& key, int32_t bit, int64_t* ret); Status BitPos(const Slice& key, int32_t bit, int64_t start_offset, int64_t* ret); Status BitPos(const Slice& key, int32_t bit, int64_t start_offset, int64_t end_offset, int64_t* ret); - Status PKSetexAt(const Slice& key, const Slice& value, int64_t timestamp); + Status PKSetexAt(const Slice& key, const Slice& value, int64_t time_stamp_millsec_); Status Exists(const Slice& key); Status Del(const Slice& key); - Status Expire(const Slice& key, int64_t timestamp); - Status Expireat(const Slice& key, int64_t timestamp); + Status Expire(const Slice& key, int64_t ttl_millsec); + Status Expireat(const Slice& key, int64_t timestamp_millsec); Status Persist(const Slice& key); - Status TTL(const Slice& key, int64_t* timestamp); + Status TTL(const Slice& key, int64_t* ttl_millsec); Status PKPatternMatchDelWithRemoveKeys(const std::string& pattern, int64_t* ret, std::vector* remove_keys, const int64_t& max_count); Status GetType(const Slice& key, enum DataType& type); @@ -198,7 +198,7 @@ class Redis { Status HExists(const Slice& key, const Slice& field); Status HGet(const Slice& key, const Slice& field, std::string* value); Status HGetall(const Slice& key, std::vector* fvs); - Status HGetallWithTTL(const Slice& key, std::vector* fvs, int64_t* ttl); + Status HGetallWithTTL(const Slice& key, std::vector* fvs, int64_t* ttl_millsec); Status HIncrby(const Slice& key, const Slice& field, int64_t value, int64_t* ret); Status HIncrbyfloat(const Slice& key, const Slice& field, const Slice& by, std::string* new_value); Status HKeys(const Slice& key, std::vector* fields); @@ -255,7 +255,7 @@ class Redis { Status SInterstore(const Slice& destination, const std::vector& keys, std::vector& value_to_dest, int32_t* ret); Status SIsmember(const Slice& key, const Slice& member, int32_t* ret); Status SMembers(const Slice& key, std::vector* members); - Status SMembersWithTTL(const Slice& key, std::vector* members, int64_t* ttl); + Status SMembersWithTTL(const Slice& key, std::vector* members, int64_t* ttl_millsec); Status SMove(const Slice& source, const Slice& destination, const Slice& member, int32_t* ret); Status SPop(const Slice& key, std::vector* members, int64_t cnt); Status SRandmember(const Slice& key, int32_t count, std::vector* members); @@ -276,7 +276,7 @@ class Redis { Status LPush(const Slice& key, const std::vector& values, uint64_t* ret); Status LPushx(const Slice& key, const std::vector& values, uint64_t* len); Status LRange(const Slice& key, int64_t start, int64_t stop, std::vector* ret); - Status LRangeWithTTL(const Slice& key, int64_t start, int64_t stop, std::vector* ret, int64_t* ttl); + Status LRangeWithTTL(const Slice& key, int64_t start, int64_t stop, std::vector* ret, int64_t* ttl_millsec); Status LRem(const Slice& key, int64_t count, const Slice& value, uint64_t* ret); Status LSet(const Slice& key, int64_t index, const Slice& value); Status LTrim(const Slice& key, int64_t start, int64_t stop); @@ -291,7 +291,7 @@ class Redis { Status ZCount(const Slice& key, double min, double max, bool left_close, bool right_close, int32_t* ret); Status ZIncrby(const Slice& key, const Slice& member, double increment, double* ret); Status ZRange(const Slice& key, int32_t start, int32_t stop, std::vector* score_members); - Status ZRangeWithTTL(const Slice& key, int32_t start, int32_t stop, std::vector* score_members, int64_t* ttl); + Status ZRangeWithTTL(const Slice& key, int32_t start, int32_t stop, std::vector* score_members, int64_t* ttl_millsec); Status ZRangebyscore(const Slice& key, double min, double max, bool left_close, bool right_close, int64_t count, int64_t offset, std::vector* score_members); Status ZRank(const Slice& key, const Slice& member, int32_t* rank); diff --git a/src/storage/src/redis_hashes.cc b/src/storage/src/redis_hashes.cc index 9193dddd1c..1a947c07e7 100644 --- a/src/storage/src/redis_hashes.cc +++ b/src/storage/src/redis_hashes.cc @@ -31,8 +31,7 @@ Status Redis::ScanHashesKeyNum(KeyInfo* key_info) { iterator_options.snapshot = snapshot; iterator_options.fill_cache = false; - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); + pstd::TimeType curtime = pstd::NowMillis(); rocksdb::Iterator* iter = db_->NewIterator(iterator_options, handles_[kMetaCF]); for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { @@ -116,7 +115,7 @@ Status Redis::HDel(const Slice& key, const std::vector& fields, int } } *ret = del_cnt; - if (!parsed_hashes_meta_value.CheckModifyCount(-del_cnt)){ + if (!parsed_hashes_meta_value.CheckModifyCount(-del_cnt)) { return Status::InvalidArgument("hash size overflow"); } parsed_hashes_meta_value.ModifyCount(-del_cnt); @@ -221,7 +220,7 @@ Status Redis::HGetall(const Slice& key, std::vector* fvs) { return s; } -Status Redis::HGetallWithTTL(const Slice& key, std::vector* fvs, int64_t* ttl) { +Status Redis::HGetallWithTTL(const Slice& key, std::vector* fvs, int64_t* ttl_millsec) { rocksdb::ReadOptions read_options; const rocksdb::Snapshot* snapshot; @@ -249,13 +248,12 @@ Status Redis::HGetallWithTTL(const Slice& key, std::vector* fvs, int return Status::NotFound("Stale"); } else { // ttl - *ttl = parsed_hashes_meta_value.Etime(); - if (*ttl == 0) { - *ttl = -1; + *ttl_millsec = parsed_hashes_meta_value.Etime(); + if (*ttl_millsec == 0) { + *ttl_millsec = -1; } else { - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); - *ttl = *ttl - curtime >= 0 ? *ttl - curtime : -2; + pstd::TimeType curtime = pstd::NowMillis(); + *ttl_millsec = *ttl_millsec - curtime >= 0 ? *ttl_millsec - curtime : -2; } version = parsed_hashes_meta_value.Version(); @@ -332,7 +330,7 @@ Status Redis::HIncrby(const Slice& key, const Slice& field, int64_t value, int64 statistic++; } else if (s.IsNotFound()) { Int64ToStr(value_buf, 32, value); - if (!parsed_hashes_meta_value.CheckModifyCount(1)){ + if (!parsed_hashes_meta_value.CheckModifyCount(1)) { return Status::InvalidArgument("hash size overflow"); } BaseDataValue internal_value(value_buf); @@ -426,7 +424,7 @@ Status Redis::HIncrbyfloat(const Slice& key, const Slice& field, const Slice& by statistic++; } else if (s.IsNotFound()) { LongDoubleToStr(long_double_by, new_value); - if (!parsed_hashes_meta_value.CheckModifyCount(1)){ + if (!parsed_hashes_meta_value.CheckModifyCount(1)) { return Status::InvalidArgument("hash size overflow"); } parsed_hashes_meta_value.ModifyCount(1); @@ -654,7 +652,7 @@ Status Redis::HMSet(const Slice& key, const std::vector& fvs) { return s; } } - if (!parsed_hashes_meta_value.CheckModifyCount(count)){ + if (!parsed_hashes_meta_value.CheckModifyCount(count)) { return Status::InvalidArgument("hash size overflow"); } parsed_hashes_meta_value.ModifyCount(count); @@ -722,7 +720,7 @@ Status Redis::HSet(const Slice& key, const Slice& field, const Slice& value, int statistic++; } } else if (s.IsNotFound()) { - if (!parsed_hashes_meta_value.CheckModifyCount(1)){ + if (!parsed_hashes_meta_value.CheckModifyCount(1)) { return Status::InvalidArgument("hash size overflow"); } parsed_hashes_meta_value.ModifyCount(1); @@ -789,7 +787,7 @@ Status Redis::HSetnx(const Slice& key, const Slice& field, const Slice& value, i if (s.ok()) { *ret = 0; } else if (s.IsNotFound()) { - if (!parsed_hashes_meta_value.CheckModifyCount(1)){ + if (!parsed_hashes_meta_value.CheckModifyCount(1)) { return Status::InvalidArgument("hash size overflow"); } parsed_hashes_meta_value.ModifyCount(1); @@ -1122,7 +1120,7 @@ Status Redis::PKHRScanRange(const Slice& key, const Slice& field_start, const st return Status::NotFound(); } else { uint64_t version = parsed_hashes_meta_value.Version(); - int32_t start_key_version = start_no_limit ? version + 1 : version; + uint64_t start_key_version = start_no_limit ? version + 1 : version; std::string start_key_field = start_no_limit ? "" : field_start.ToString(); HashesDataKey hashes_data_prefix(key, version, Slice()); HashesDataKey hashes_start_data_key(key, start_key_version, start_key_field); @@ -1157,7 +1155,7 @@ Status Redis::PKHRScanRange(const Slice& key, const Slice& field_start, const st return Status::OK(); } -Status Redis::HashesExpire(const Slice& key, int64_t ttl, std::string&& prefetch_meta) { +Status Redis::HashesExpire(const Slice& key, int64_t ttl_millsec, std::string&& prefetch_meta) { std::string meta_value(std::move(prefetch_meta)); ScopeRecordLock l(lock_mgr_, key); BaseMetaKey base_meta_key(key); @@ -1186,8 +1184,8 @@ Status Redis::HashesExpire(const Slice& key, int64_t ttl, std::string&& prefetch return Status::NotFound(); } - if (ttl > 0) { - parsed_hashes_meta_value.SetRelativeTimestamp(ttl); + if (ttl_millsec > 0) { + parsed_hashes_meta_value.SetRelativeTimestamp(ttl_millsec); s = db_->Put(default_write_options_, handles_[kMetaCF], base_meta_key.Encode(), meta_value); } else { parsed_hashes_meta_value.InitialMetaValue(); @@ -1234,7 +1232,7 @@ Status Redis::HashesDel(const Slice& key, std::string&& prefetch_meta) { return s; } -Status Redis::HashesExpireat(const Slice& key, int64_t timestamp, std::string&& prefetch_meta) { +Status Redis::HashesExpireat(const Slice& key, int64_t timestamp_millsec, std::string&& prefetch_meta) { std::string meta_value(std::move(prefetch_meta)); ScopeRecordLock l(lock_mgr_, key); BaseMetaKey base_meta_key(key); @@ -1262,8 +1260,8 @@ Status Redis::HashesExpireat(const Slice& key, int64_t timestamp, std::string&& } else if (parsed_hashes_meta_value.Count() == 0) { return Status::NotFound(); } else { - if (timestamp > 0) { - parsed_hashes_meta_value.SetEtime(static_cast(timestamp)); + if (timestamp_millsec > 0) { + parsed_hashes_meta_value.SetEtime(static_cast(timestamp_millsec)); } else { parsed_hashes_meta_value.InitialMetaValue(); } @@ -1313,7 +1311,7 @@ Status Redis::HashesPersist(const Slice& key, std::string&& prefetch_meta) { return s; } -Status Redis::HashesTTL(const Slice& key, int64_t* timestamp, std::string&& prefetch_meta) { +Status Redis::HashesTTL(const Slice& key, int64_t* ttl_millsec, std::string&& prefetch_meta) { std::string meta_value(std::move(prefetch_meta)); Status s; BaseMetaKey base_meta_key(key); @@ -1336,23 +1334,22 @@ Status Redis::HashesTTL(const Slice& key, int64_t* timestamp, std::string&& pref if (s.ok()) { ParsedHashesMetaValue parsed_hashes_meta_value(&meta_value); if (parsed_hashes_meta_value.IsStale()) { - *timestamp = -2; + *ttl_millsec = -2; return Status::NotFound("Stale"); } else if (parsed_hashes_meta_value.Count() == 0) { - *timestamp = -2; + *ttl_millsec = -2; return Status::NotFound(); } else { - *timestamp = parsed_hashes_meta_value.Etime(); - if (*timestamp == 0) { - *timestamp = -1; + *ttl_millsec = parsed_hashes_meta_value.Etime(); + if (*ttl_millsec == 0) { + *ttl_millsec = -1; } else { - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); - *timestamp = *timestamp - curtime >= 0 ? *timestamp - curtime : -2; + pstd::TimeType curtime = pstd::NowMillis(); + *ttl_millsec = *ttl_millsec - curtime >= 0 ? *ttl_millsec - curtime : -2; } } } else if (s.IsNotFound()) { - *timestamp = -2; + *ttl_millsec = -2; } return s; } diff --git a/src/storage/src/redis_lists.cc b/src/storage/src/redis_lists.cc index db007ee2cf..cdf4ff122d 100644 --- a/src/storage/src/redis_lists.cc +++ b/src/storage/src/redis_lists.cc @@ -30,8 +30,7 @@ Status Redis::ScanListsKeyNum(KeyInfo* key_info) { iterator_options.snapshot = snapshot; iterator_options.fill_cache = false; - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); + pstd::TimeType curtime = pstd::NowMillis(); rocksdb::Iterator* iter = db_->NewIterator(iterator_options, handles_[kMetaCF]); for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { @@ -471,7 +470,7 @@ Status Redis::LRange(const Slice& key, int64_t start, int64_t stop, std::vector< } } -Status Redis::LRangeWithTTL(const Slice& key, int64_t start, int64_t stop, std::vector* ret, int64_t* ttl) { +Status Redis::LRangeWithTTL(const Slice& key, int64_t start, int64_t stop, std::vector* ret, int64_t* ttl_millsec) { rocksdb::ReadOptions read_options; const rocksdb::Snapshot* snapshot; @@ -499,13 +498,12 @@ Status Redis::LRangeWithTTL(const Slice& key, int64_t start, int64_t stop, std:: return Status::NotFound("Stale"); } else { // ttl - *ttl = parsed_lists_meta_value.Etime(); - if (*ttl == 0) { - *ttl = -1; + *ttl_millsec = parsed_lists_meta_value.Etime(); + if (*ttl_millsec == 0) { + *ttl_millsec = -1; } else { - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); - *ttl = *ttl - curtime >= 0 ? *ttl - curtime : -2; + pstd::TimeType curtime = pstd::NowMillis(); + *ttl_millsec = *ttl_millsec - curtime >= 0 ? *ttl_millsec - curtime : -2; } uint64_t version = parsed_lists_meta_value.Version(); @@ -1097,7 +1095,7 @@ Status Redis::RPushx(const Slice& key, const std::vector& values, u return s; } -Status Redis::ListsExpire(const Slice& key, int64_t ttl, std::string&& prefetch_meta) { +Status Redis::ListsExpire(const Slice& key, int64_t ttl_millsec, std::string&& prefetch_meta) { std::string meta_value(std::move(prefetch_meta)); ScopeRecordLock l(lock_mgr_, key); BaseMetaKey base_meta_key(key); @@ -1126,8 +1124,8 @@ Status Redis::ListsExpire(const Slice& key, int64_t ttl, std::string&& prefetch_ return Status::NotFound(); } - if (ttl > 0) { - parsed_lists_meta_value.SetRelativeTimestamp(ttl); + if (ttl_millsec > 0) { + parsed_lists_meta_value.SetRelativeTimestamp(ttl_millsec); s = db_->Put(default_write_options_, handles_[kMetaCF], base_meta_key.Encode(), meta_value); } else { parsed_lists_meta_value.InitialMetaValue(); @@ -1174,7 +1172,7 @@ Status Redis::ListsDel(const Slice& key, std::string&& prefetch_meta) { return s; } -Status Redis::ListsExpireat(const Slice& key, int64_t timestamp, std::string&& prefetch_meta) { +Status Redis::ListsExpireat(const Slice& key, int64_t timestamp_millsec, std::string&& prefetch_meta) { std::string meta_value(std::move(prefetch_meta)); ScopeRecordLock l(lock_mgr_, key); BaseMetaKey base_meta_key(key); @@ -1202,8 +1200,8 @@ Status Redis::ListsExpireat(const Slice& key, int64_t timestamp, std::string&& p } else if (parsed_lists_meta_value.Count() == 0) { return Status::NotFound(); } else { - if (timestamp > 0) { - parsed_lists_meta_value.SetEtime(static_cast(timestamp)); + if (timestamp_millsec > 0) { + parsed_lists_meta_value.SetEtime(static_cast(timestamp_millsec)); } else { parsed_lists_meta_value.InitialMetaValue(); } @@ -1253,7 +1251,7 @@ Status Redis::ListsPersist(const Slice& key, std::string&& prefetch_meta) { return s; } -Status Redis::ListsTTL(const Slice& key, int64_t* timestamp, std::string&& prefetch_meta) { +Status Redis::ListsTTL(const Slice& key, int64_t* ttl_millsec, std::string&& prefetch_meta) { std::string meta_value(std::move(prefetch_meta)); BaseMetaKey base_meta_key(key); Status s; @@ -1276,24 +1274,23 @@ Status Redis::ListsTTL(const Slice& key, int64_t* timestamp, std::string&& prefe if (s.ok()) { ParsedListsMetaValue parsed_lists_meta_value(&meta_value); if (parsed_lists_meta_value.IsStale()) { - *timestamp = -2; + *ttl_millsec = -2; return Status::NotFound("Stale"); } else if (parsed_lists_meta_value.Count() == 0) { - *timestamp = -2; + *ttl_millsec = -2; return Status::NotFound(); } else { // Return -1 for lists with no set expiration, and calculate remaining time for others - *timestamp = parsed_lists_meta_value.Etime(); - if (*timestamp == 0) { - *timestamp = -1; + *ttl_millsec = parsed_lists_meta_value.Etime(); + if (*ttl_millsec == 0) { + *ttl_millsec = -1; } else { - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); - *timestamp = *timestamp - curtime >= 0 ? *timestamp - curtime : -2; + pstd::TimeType curtime = pstd::NowMillis(); + *ttl_millsec = *ttl_millsec - curtime >= 0 ? *ttl_millsec - curtime : -2; } } } else if (s.IsNotFound()) { - *timestamp = -2; + *ttl_millsec = -2; } return s; } diff --git a/src/storage/src/redis_sets.cc b/src/storage/src/redis_sets.cc index db5044b440..5f33d9574b 100644 --- a/src/storage/src/redis_sets.cc +++ b/src/storage/src/redis_sets.cc @@ -34,8 +34,7 @@ rocksdb::Status Redis::ScanSetsKeyNum(KeyInfo* key_info) { iterator_options.snapshot = snapshot; iterator_options.fill_cache = false; - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); + pstd::TimeType curtime = pstd::NowMillis(); rocksdb::Iterator* iter = db_->NewIterator(iterator_options, handles_[kMetaCF]); for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { @@ -124,7 +123,7 @@ rocksdb::Status Redis::SAdd(const Slice& key, const std::vector& me if (cnt == 0) { return rocksdb::Status::OK(); } else { - if (!parsed_sets_meta_value.CheckModifyCount(cnt)){ + if (!parsed_sets_meta_value.CheckModifyCount(cnt)) { return Status::InvalidArgument("set size overflow"); } parsed_sets_meta_value.ModifyCount(cnt); @@ -743,7 +742,7 @@ rocksdb::Status Redis::SMembers(const Slice& key, std::vector* memb Status Redis::SMembersWithTTL(const Slice& key, std::vector* members, - int64_t* ttl) { + int64_t* ttl_millsec) { rocksdb::ReadOptions read_options; const rocksdb::Snapshot* snapshot; @@ -771,13 +770,12 @@ Status Redis::SMembersWithTTL(const Slice& key, return Status::NotFound("Stale"); } else { // ttl - *ttl = parsed_sets_meta_value.Etime(); - if (*ttl == 0) { - *ttl = -1; + *ttl_millsec = parsed_sets_meta_value.Etime(); + if (*ttl_millsec == 0) { + *ttl_millsec = -1; } else { - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); - *ttl = *ttl - curtime >= 0 ? *ttl - curtime : -2; + pstd::TimeType curtime = pstd::NowMillis(); + *ttl_millsec = *ttl_millsec - curtime >= 0 ? *ttl_millsec - curtime : -2; } version = parsed_sets_meta_value.Version(); @@ -838,7 +836,7 @@ rocksdb::Status Redis::SMove(const Slice& source, const Slice& destination, cons s = db_->Get(default_read_options_, handles_[kSetsDataCF], sets_member_key.Encode(), &member_value); if (s.ok()) { *ret = 1; - if (!parsed_sets_meta_value.CheckModifyCount(-1)){ + if (!parsed_sets_meta_value.CheckModifyCount(-1)) { return Status::InvalidArgument("set size overflow"); } parsed_sets_meta_value.ModifyCount(-1); @@ -886,7 +884,7 @@ rocksdb::Status Redis::SMove(const Slice& source, const Slice& destination, cons SetsMemberKey sets_member_key(destination, version, member); s = db_->Get(default_read_options_, handles_[kSetsDataCF], sets_member_key.Encode(), &member_value); if (s.IsNotFound()) { - if (!parsed_sets_meta_value.CheckModifyCount(1)){ + if (!parsed_sets_meta_value.CheckModifyCount(1)) { return Status::InvalidArgument("set size overflow"); } parsed_sets_meta_value.ModifyCount(1); @@ -921,8 +919,6 @@ rocksdb::Status Redis::SPop(const Slice& key, std::vector* members, rocksdb::WriteBatch batch; ScopeRecordLock l(lock_mgr_, key); - uint64_t start_us = pstd::NowMicros(); - BaseMetaKey base_meta_key(key); Status s = db_->Get(default_read_options_, handles_[kMetaCF], base_meta_key.Encode(), &meta_value); if (s.ok() && !ExpectedMetaValue(DataType::kSets, meta_value)) { @@ -1000,7 +996,7 @@ rocksdb::Status Redis::SPop(const Slice& key, std::vector* members, } } - if (!parsed_sets_meta_value.CheckModifyCount(static_cast(-cnt))){ + if (!parsed_sets_meta_value.CheckModifyCount(static_cast(-cnt))) { return Status::InvalidArgument("set size overflow"); } parsed_sets_meta_value.ModifyCount(static_cast(-cnt)); @@ -1149,7 +1145,7 @@ rocksdb::Status Redis::SRem(const Slice& key, const std::vector& me } } *ret = cnt; - if (!parsed_sets_meta_value.CheckModifyCount(-cnt)){ + if (!parsed_sets_meta_value.CheckModifyCount(-cnt)) { return Status::InvalidArgument("set size overflow"); } parsed_sets_meta_value.ModifyCount(-cnt); @@ -1407,7 +1403,7 @@ rocksdb::Status Redis::SScan(const Slice& key, int64_t cursor, const std::string return rocksdb::Status::OK(); } -rocksdb::Status Redis::SetsExpire(const Slice& key, int64_t ttl, std::string&& prefetch_meta) { +rocksdb::Status Redis::SetsExpire(const Slice& key, int64_t ttl_millsec, std::string&& prefetch_meta) { std::string meta_value(std::move(prefetch_meta)); ScopeRecordLock l(lock_mgr_, key); BaseMetaKey base_meta_key(key); @@ -1436,8 +1432,8 @@ rocksdb::Status Redis::SetsExpire(const Slice& key, int64_t ttl, std::string&& p return rocksdb::Status::NotFound(); } - if (ttl > 0) { - parsed_sets_meta_value.SetRelativeTimestamp(ttl); + if (ttl_millsec > 0) { + parsed_sets_meta_value.SetRelativeTimestamp(ttl_millsec); s = db_->Put(default_write_options_, handles_[kMetaCF], base_meta_key.Encode(), meta_value); } else { parsed_sets_meta_value.InitialMetaValue(); @@ -1484,7 +1480,7 @@ rocksdb::Status Redis::SetsDel(const Slice& key, std::string&& prefetch_meta) { return s; } -rocksdb::Status Redis::SetsExpireat(const Slice& key, int64_t timestamp, std::string&& prefetch_meta) { +rocksdb::Status Redis::SetsExpireat(const Slice& key, int64_t timestamp_millsec, std::string&& prefetch_meta) { std::string meta_value(std::move(prefetch_meta)); ScopeRecordLock l(lock_mgr_, key); BaseMetaKey base_meta_key(key); @@ -1512,8 +1508,8 @@ rocksdb::Status Redis::SetsExpireat(const Slice& key, int64_t timestamp, std::st } else if (parsed_sets_meta_value.Count() == 0) { return rocksdb::Status::NotFound(); } else { - if (timestamp > 0) { - parsed_sets_meta_value.SetEtime(static_cast(timestamp)); + if (timestamp_millsec > 0) { + parsed_sets_meta_value.SetEtime(static_cast(timestamp_millsec)); } else { parsed_sets_meta_value.InitialMetaValue(); } @@ -1563,7 +1559,7 @@ rocksdb::Status Redis::SetsPersist(const Slice& key, std::string&& prefetch_meta return s; } -rocksdb::Status Redis::SetsTTL(const Slice& key, int64_t* timestamp, std::string&& prefetch_meta) { +rocksdb::Status Redis::SetsTTL(const Slice& key, int64_t* ttl_millsec, std::string&& prefetch_meta) { std::string meta_value(std::move(prefetch_meta)); BaseMetaKey base_meta_key(key); rocksdb::Status s; @@ -1586,23 +1582,22 @@ rocksdb::Status Redis::SetsTTL(const Slice& key, int64_t* timestamp, std::string if (s.ok()) { ParsedSetsMetaValue parsed_setes_meta_value(&meta_value); if (parsed_setes_meta_value.IsStale()) { - *timestamp = -2; + *ttl_millsec = -2; return rocksdb::Status::NotFound("Stale"); } else if (parsed_setes_meta_value.Count() == 0) { - *timestamp = -2; + *ttl_millsec = -2; return rocksdb::Status::NotFound(); } else { - *timestamp = parsed_setes_meta_value.Etime(); - if (*timestamp == 0) { - *timestamp = -1; + *ttl_millsec = parsed_setes_meta_value.Etime(); + if (*ttl_millsec == 0) { + *ttl_millsec = -1; } else { - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); - *timestamp = *timestamp - curtime >= 0 ? *timestamp - curtime : -2; + pstd::TimeType curtime = pstd::NowMillis(); + *ttl_millsec = *ttl_millsec - curtime >= 0 ? *ttl_millsec - curtime : -2; } } } else if (s.IsNotFound()) { - *timestamp = -2; + *ttl_millsec = -2; } return s; } diff --git a/src/storage/src/redis_streams.cc b/src/storage/src/redis_streams.cc index 606fb99c05..f3abdc5b08 100644 --- a/src/storage/src/redis_streams.cc +++ b/src/storage/src/redis_streams.cc @@ -338,9 +338,6 @@ Status Redis::ScanStreamsKeyNum(KeyInfo* key_info) { iterator_options.snapshot = snapshot; iterator_options.fill_cache = false; - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); - rocksdb::Iterator* iter = db_->NewIterator(iterator_options, handles_[kMetaCF]); for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { if (!ExpectedMetaValue(DataType::kStreams, iter->value().ToString())) { diff --git a/src/storage/src/redis_strings.cc b/src/storage/src/redis_strings.cc index c69be1d46e..e402f175ca 100644 --- a/src/storage/src/redis_strings.cc +++ b/src/storage/src/redis_strings.cc @@ -33,8 +33,7 @@ Status Redis::ScanStringsKeyNum(KeyInfo* key_info) { iterator_options.snapshot = snapshot; iterator_options.fill_cache = false; - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); + pstd::TimeType curtime = pstd::NowMillis(); // Note: This is a string type and does not need to pass the column family as // a parameter, use the default column family @@ -63,10 +62,10 @@ Status Redis::ScanStringsKeyNum(KeyInfo* key_info) { return Status::OK(); } -Status Redis::Append(const Slice& key, const Slice& value, int32_t* ret, int64_t* expired_timestamp_sec, std::string& out_new_value) { +Status Redis::Append(const Slice& key, const Slice& value, int32_t* ret, int64_t* expired_timestamp_millsec, std::string& out_new_value) { std::string old_value; *ret = 0; - *expired_timestamp_sec = 0; + *expired_timestamp_millsec = 0; ScopeRecordLock l(lock_mgr_, key); BaseKey base_key(key); @@ -95,13 +94,13 @@ Status Redis::Append(const Slice& key, const Slice& value, int32_t* ret, int64_t StringsValue strings_value(new_value); strings_value.SetEtime(timestamp); *ret = static_cast(new_value.size()); - *expired_timestamp_sec = timestamp; + *expired_timestamp_millsec = timestamp; return db_->Put(default_write_options_, base_key.Encode(), strings_value.Encode()); } } else if (s.IsNotFound()) { *ret = static_cast(value.size()); StringsValue strings_value(value); - *expired_timestamp_sec = 0; + *expired_timestamp_millsec = 0; return db_->Put(default_write_options_, base_key.Encode(), strings_value.Encode()); } return s; @@ -382,24 +381,23 @@ void ClearValueAndSetTTL(std::string* value, int64_t* ttl, int64_t ttl_value) { } int64_t CalculateTTL(int64_t expiry_time) { - int64_t current_time; - rocksdb::Env::Default()->GetCurrentTime(¤t_time); + pstd::TimeType current_time = pstd::NowMillis(); return expiry_time - current_time >= 0 ? expiry_time - current_time : -2; } -Status HandleParsedStringsValue(ParsedStringsValue& parsed_strings_value, std::string* value, int64_t* ttl) { +Status HandleParsedStringsValue(ParsedStringsValue& parsed_strings_value, std::string* value, int64_t* ttl_millsec) { if (parsed_strings_value.IsStale()) { - ClearValueAndSetTTL(value, ttl, -2); + ClearValueAndSetTTL(value, ttl_millsec, -2); return Status::NotFound("Stale"); } else { parsed_strings_value.StripSuffix(); int64_t expiry_time = parsed_strings_value.Etime(); - *ttl = (expiry_time == 0) ? -1 : CalculateTTL(expiry_time); + *ttl_millsec = (expiry_time == 0) ? -1 : CalculateTTL(expiry_time); } return Status::OK(); } -Status Redis::GetWithTTL(const Slice& key, std::string* value, int64_t* ttl) { +Status Redis::GetWithTTL(const Slice& key, std::string* value, int64_t* ttl_millsec) { value->clear(); BaseKey base_key(key); Status s = db_->Get(default_read_options_, base_key.Encode(), value); @@ -418,15 +416,15 @@ Status Redis::GetWithTTL(const Slice& key, std::string* value, int64_t* ttl) { if (s.ok()) { ParsedStringsValue parsed_strings_value(value); - return HandleParsedStringsValue(parsed_strings_value, value, ttl); + return HandleParsedStringsValue(parsed_strings_value, value, ttl_millsec); } else if (s.IsNotFound()) { - ClearValueAndSetTTL(value, ttl, -2); + ClearValueAndSetTTL(value, ttl_millsec, -2); } return s; } -Status Redis::MGetWithTTL(const Slice& key, std::string* value, int64_t* ttl) { +Status Redis::MGetWithTTL(const Slice& key, std::string* value, int64_t* ttl_millsec) { value->clear(); BaseKey base_key(key); Status s = db_->Get(default_read_options_, base_key.Encode(), value); @@ -438,9 +436,9 @@ Status Redis::MGetWithTTL(const Slice& key, std::string* value, int64_t* ttl) { if (s.ok()) { ParsedStringsValue parsed_strings_value(value); - return HandleParsedStringsValue(parsed_strings_value, value, ttl); + return HandleParsedStringsValue(parsed_strings_value, value, ttl_millsec); } else if (s.IsNotFound()) { - ClearValueAndSetTTL(value, ttl, -2); + ClearValueAndSetTTL(value, ttl_millsec, -2); } return s; @@ -531,7 +529,7 @@ Status Redis::Getrange(const Slice& key, int64_t start_offset, int64_t end_offse } Status Redis::GetrangeWithValue(const Slice& key, int64_t start_offset, int64_t end_offset, - std::string* ret, std::string* value, int64_t* ttl) { + std::string* ret, std::string* value, int64_t* ttl_millsec) { *ret = ""; BaseKey base_key(key); Status s = db_->Get(default_read_options_, base_key.Encode(), value); @@ -550,18 +548,17 @@ Status Redis::GetrangeWithValue(const Slice& key, int64_t start_offset, int64_t ParsedStringsValue parsed_strings_value(value); if (parsed_strings_value.IsStale()) { value->clear(); - *ttl = -2; + *ttl_millsec = -2; return Status::NotFound("Stale"); } else { parsed_strings_value.StripSuffix(); // get ttl - *ttl = parsed_strings_value.Etime(); - if (*ttl == 0) { - *ttl = -1; + *ttl_millsec = parsed_strings_value.Etime(); + if (*ttl_millsec == 0) { + *ttl_millsec = -1; } else { - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); - *ttl = *ttl - curtime >= 0 ? *ttl - curtime : -2; + pstd::TimeType curtime = pstd::NowMillis(); + *ttl_millsec = *ttl_millsec - curtime >= 0 ? *ttl_millsec - curtime : -2; } int64_t size = value->size(); @@ -587,7 +584,7 @@ Status Redis::GetrangeWithValue(const Slice& key, int64_t start_offset, int64_t } } else if (s.IsNotFound()) { value->clear(); - *ttl = -2; + *ttl_millsec = -2; } return s; } @@ -622,7 +619,7 @@ Status Redis::GetSet(const Slice& key, const Slice& value, std::string* old_valu return db_->Put(default_write_options_, base_key.Encode(), strings_value.Encode()); } -Status Redis::Incrby(const Slice& key, int64_t value, int64_t* ret, int64_t* expired_timestamp_sec) { +Status Redis::Incrby(const Slice& key, int64_t value, int64_t* ret, int64_t* expired_timestamp_millsec) { std::string old_value; std::string new_value; ScopeRecordLock l(lock_mgr_, key); @@ -660,7 +657,7 @@ Status Redis::Incrby(const Slice& key, int64_t value, int64_t* ret, int64_t* exp new_value = std::to_string(*ret); StringsValue strings_value(new_value); strings_value.SetEtime(timestamp); - *expired_timestamp_sec = timestamp; + *expired_timestamp_millsec = timestamp; return db_->Put(default_write_options_, base_key.Encode(), strings_value.Encode()); } } else if (s.IsNotFound()) { @@ -781,7 +778,7 @@ Status Redis::Set(const Slice& key, const Slice& value) { return db_->Put(default_write_options_, base_key.Encode(), strings_value.Encode()); } -Status Redis::Setxx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl) { +Status Redis::Setxx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl_millsec) { bool not_found = true; std::string old_value; StringsValue strings_value(value); @@ -813,8 +810,8 @@ Status Redis::Setxx(const Slice& key, const Slice& value, int32_t* ret, int64_t return s; } else { *ret = 1; - if (ttl > 0) { - strings_value.SetRelativeTimestamp(ttl); + if (ttl_millsec > 0) { + strings_value.SetRelativeTimeInMillsec(ttl_millsec); } return db_->Put(default_write_options_, base_key.Encode(), strings_value.Encode()); } @@ -879,12 +876,12 @@ Status Redis::SetBit(const Slice& key, int64_t offset, int32_t on, int32_t* ret) } } -Status Redis::Setex(const Slice& key, const Slice& value, int64_t ttl) { - if (ttl <= 0) { +Status Redis::Setex(const Slice& key, const Slice& value, int64_t ttl_millsec) { + if (ttl_millsec <= 0) { return Status::InvalidArgument("invalid expire time"); } StringsValue strings_value(value); - auto s = strings_value.SetRelativeTimestamp(ttl); + auto s = strings_value.SetRelativeTimeInMillsec(ttl_millsec); if (s != Status::OK()) { return s; } @@ -894,7 +891,7 @@ Status Redis::Setex(const Slice& key, const Slice& value, int64_t ttl) { return db_->Put(default_write_options_, base_key.Encode(), strings_value.Encode()); } -Status Redis::Setnx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl) { +Status Redis::Setnx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl_millsec) { *ret = 0; std::string old_value; @@ -911,8 +908,8 @@ Status Redis::Setnx(const Slice& key, const Slice& value, int32_t* ret, int64_t s = Status::NotFound(); StringsValue strings_value(value); - if (ttl > 0) { - strings_value.SetRelativeTimestamp(ttl); + if (ttl_millsec > 0) { + strings_value.SetRelativeTimeInMillsec(ttl_millsec); } s = db_->Put(default_write_options_, base_key.Encode(), strings_value.Encode()); if (s.ok()) { @@ -922,7 +919,7 @@ Status Redis::Setnx(const Slice& key, const Slice& value, int32_t* ret, int64_t } Status Redis::Setvx(const Slice& key, const Slice& value, const Slice& new_value, int32_t* ret, - int64_t ttl) { + int64_t ttl_millsec) { *ret = 0; std::string old_value; @@ -946,8 +943,8 @@ Status Redis::Setvx(const Slice& key, const Slice& value, const Slice& new_value } else { if (value.compare(parsed_strings_value.UserValue()) == 0) { StringsValue strings_value(new_value); - if (ttl > 0) { - strings_value.SetRelativeTimestamp(ttl); + if (ttl_millsec > 0) { + strings_value.SetRelativeTimeInMillsec(ttl_millsec); } s = db_->Put(default_write_options_, base_key.Encode(), strings_value.Encode()); if (!s.ok()) { @@ -1292,16 +1289,18 @@ Status Redis::BitPos(const Slice& key, int32_t bit, int64_t start_offset, int64_ } //TODO(wangshaoyi): timestamp uint64_t -Status Redis::PKSetexAt(const Slice& key, const Slice& value, int64_t timestamp) { +Status Redis::PKSetexAt(const Slice& key, const Slice& value, int64_t time_stamp_millsec_) { StringsValue strings_value(value); - + if (time_stamp_millsec_ < 0) { + time_stamp_millsec_ = pstd::NowMillis() - 1; + } BaseKey base_key(key); ScopeRecordLock l(lock_mgr_, key); - strings_value.SetEtime(uint64_t(timestamp)); + strings_value.SetEtime(uint64_t(time_stamp_millsec_)); return db_->Put(default_write_options_, base_key.Encode(), strings_value.Encode()); } -Status Redis::StringsExpire(const Slice& key, int64_t ttl, std::string&& prefetch_meta) { +Status Redis::StringsExpire(const Slice& key, int64_t ttl_millsec, std::string&& prefetch_meta) { std::string value(std::move(prefetch_meta)); BaseKey base_key(key); @@ -1327,8 +1326,8 @@ Status Redis::StringsExpire(const Slice& key, int64_t ttl, std::string&& prefetc if (parsed_strings_value.IsStale()) { return Status::NotFound("Stale"); } - if (ttl > 0) { - parsed_strings_value.SetRelativeTimestamp(ttl); + if (ttl_millsec > 0) { + parsed_strings_value.SetRelativeTimestamp(ttl_millsec); return db_->Put(default_write_options_, base_key.Encode(), value); } else { return db_->Delete(default_write_options_, base_key.Encode()); @@ -1368,7 +1367,7 @@ Status Redis::StringsDel(const Slice& key, std::string&& prefetch_meta) { return s; } -Status Redis::StringsExpireat(const Slice& key, int64_t timestamp, std::string&& prefetch_meta) { +Status Redis::StringsExpireat(const Slice& key, int64_t timestamp_millsec, std::string&& prefetch_meta) { std::string value(std::move(prefetch_meta)); ScopeRecordLock l(lock_mgr_, key); BaseKey base_key(key); @@ -1394,8 +1393,8 @@ Status Redis::StringsExpireat(const Slice& key, int64_t timestamp, std::string&& if (parsed_strings_value.IsStale()) { return Status::NotFound("Stale"); } else { - if (timestamp > 0) { - parsed_strings_value.SetEtime(static_cast(timestamp)); + if (timestamp_millsec > 0) { + parsed_strings_value.SetEtime(static_cast(timestamp_millsec)); return db_->Put(default_write_options_, base_key.Encode(), value); } else { return db_->Delete(default_write_options_, base_key.Encode()); @@ -1443,7 +1442,7 @@ Status Redis::StringsPersist(const Slice& key, std::string&& prefetch_meta) { return s; } -Status Redis::StringsTTL(const Slice& key, int64_t* timestamp, std::string&& prefetch_meta) { +Status Redis::StringsTTL(const Slice& key, int64_t* ttl_millsec, std::string&& prefetch_meta) { std::string value(std::move(prefetch_meta)); ScopeRecordLock l(lock_mgr_, key); BaseKey base_key(key); @@ -1467,20 +1466,19 @@ Status Redis::StringsTTL(const Slice& key, int64_t* timestamp, std::string&& pre if (s.ok()) { ParsedStringsValue parsed_strings_value(&value); if (parsed_strings_value.IsStale()) { - *timestamp = -2; + *ttl_millsec = -2; return Status::NotFound("Stale"); } else { - *timestamp = parsed_strings_value.Etime(); - if (*timestamp == 0) { - *timestamp = -1; + *ttl_millsec = parsed_strings_value.Etime(); + if (*ttl_millsec == 0) { + *ttl_millsec = -1; } else { - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); - *timestamp = *timestamp - curtime >= 0 ? *timestamp - curtime : -2; + pstd::TimeType curtime = pstd::NowMillis(); + *ttl_millsec = *ttl_millsec - curtime >= 0 ? *ttl_millsec - curtime : -2; } } } else if (s.IsNotFound()) { - *timestamp = -2; + *ttl_millsec = -2; } return s; } @@ -1572,7 +1570,7 @@ rocksdb::Status Redis::Del(const Slice& key) { return rocksdb::Status::NotFound(); } -rocksdb::Status Redis::Expire(const Slice& key, int64_t ttl) { +rocksdb::Status Redis::Expire(const Slice& key, int64_t ttl_millsec) { std::string meta_value; BaseMetaKey base_meta_key(key); rocksdb::Status s = db_->Get(default_read_options_, handles_[kMetaCF], base_meta_key.Encode(), &meta_value); @@ -1580,15 +1578,15 @@ rocksdb::Status Redis::Expire(const Slice& key, int64_t ttl) { auto type = static_cast(static_cast(meta_value[0])); switch (type) { case DataType::kSets: - return SetsExpire(key, ttl, std::move(meta_value)); + return SetsExpire(key, ttl_millsec, std::move(meta_value)); case DataType::kZSets: - return ZsetsExpire(key, ttl, std::move(meta_value)); + return ZsetsExpire(key, ttl_millsec, std::move(meta_value)); case DataType::kHashes: - return HashesExpire(key, ttl, std::move(meta_value)); + return HashesExpire(key, ttl_millsec, std::move(meta_value)); case DataType::kLists: - return ListsExpire(key, ttl, std::move(meta_value)); + return ListsExpire(key, ttl_millsec, std::move(meta_value)); case DataType::kStrings: - return StringsExpire(key, ttl, std::move(meta_value)); + return StringsExpire(key, ttl_millsec, std::move(meta_value)); default: return rocksdb::Status::NotFound(); } @@ -1596,7 +1594,7 @@ rocksdb::Status Redis::Expire(const Slice& key, int64_t ttl) { return rocksdb::Status::NotFound(); } -rocksdb::Status Redis::Expireat(const Slice& key, int64_t ttl) { +rocksdb::Status Redis::Expireat(const Slice& key, int64_t timestamp_millsec) { std::string meta_value; BaseMetaKey base_meta_key(key); rocksdb::Status s = db_->Get(default_read_options_, handles_[kMetaCF], base_meta_key.Encode(), &meta_value); @@ -1604,15 +1602,15 @@ rocksdb::Status Redis::Expireat(const Slice& key, int64_t ttl) { auto type = static_cast(static_cast(meta_value[0])); switch (type) { case DataType::kSets: - return SetsExpireat(key, ttl, std::move(meta_value)); + return SetsExpireat(key, timestamp_millsec, std::move(meta_value)); case DataType::kZSets: - return ZsetsExpireat(key, ttl, std::move(meta_value)); + return ZsetsExpireat(key, timestamp_millsec, std::move(meta_value)); case DataType::kHashes: - return HashesExpireat(key, ttl, std::move(meta_value)); + return HashesExpireat(key, timestamp_millsec, std::move(meta_value)); case DataType::kLists: - return ListsExpireat(key, ttl, std::move(meta_value)); + return ListsExpireat(key, timestamp_millsec, std::move(meta_value)); case DataType::kStrings: - return StringsExpireat(key, ttl, std::move(meta_value)); + return StringsExpireat(key, timestamp_millsec, std::move(meta_value)); default: return rocksdb::Status::NotFound(); } @@ -1644,7 +1642,7 @@ rocksdb::Status Redis::Persist(const Slice& key) { return rocksdb::Status::NotFound(); } -rocksdb::Status Redis::TTL(const Slice& key, int64_t* timestamp) { +rocksdb::Status Redis::TTL(const Slice& key, int64_t* ttl_millsec) { std::string meta_value; BaseMetaKey base_meta_key(key); rocksdb::Status s = db_->Get(default_read_options_, handles_[kMetaCF], base_meta_key.Encode(), &meta_value); @@ -1652,15 +1650,15 @@ rocksdb::Status Redis::TTL(const Slice& key, int64_t* timestamp) { auto type = static_cast(static_cast(meta_value[0])); switch (type) { case DataType::kSets: - return SetsTTL(key, timestamp, std::move(meta_value)); + return SetsTTL(key, ttl_millsec, std::move(meta_value)); case DataType::kZSets: - return ZsetsTTL(key, timestamp, std::move(meta_value)); + return ZsetsTTL(key, ttl_millsec, std::move(meta_value)); case DataType::kHashes: - return HashesTTL(key, timestamp, std::move(meta_value)); + return HashesTTL(key, ttl_millsec, std::move(meta_value)); case DataType::kLists: - return ListsTTL(key, timestamp, std::move(meta_value)); + return ListsTTL(key, ttl_millsec, std::move(meta_value)); case DataType::kStrings: - return StringsTTL(key, timestamp, std::move(meta_value)); + return StringsTTL(key, ttl_millsec, std::move(meta_value)); default: return rocksdb::Status::NotFound(); } diff --git a/src/storage/src/redis_zsets.cc b/src/storage/src/redis_zsets.cc index 632f7fb80a..fa6c78f912 100644 --- a/src/storage/src/redis_zsets.cc +++ b/src/storage/src/redis_zsets.cc @@ -36,8 +36,7 @@ Status Redis::ScanZsetsKeyNum(KeyInfo* key_info) { iterator_options.snapshot = snapshot; iterator_options.fill_cache = false; - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); + pstd::TimeType curtime = pstd::NowMillis(); rocksdb::Iterator* iter = db_->NewIterator(iterator_options, handles_[kMetaCF]); for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { @@ -108,7 +107,7 @@ Status Redis::ZPopMax(const Slice& key, const int64_t count, std::vectorkey()); } delete iter; - if (!parsed_zsets_meta_value.CheckModifyCount(-del_cnt)){ + if (!parsed_zsets_meta_value.CheckModifyCount(-del_cnt)) { return Status::InvalidArgument("zset size overflow"); } parsed_zsets_meta_value.ModifyCount(-del_cnt); @@ -166,7 +165,7 @@ Status Redis::ZPopMin(const Slice& key, const int64_t count, std::vectorkey()); } delete iter; - if (!parsed_zsets_meta_value.CheckModifyCount(-del_cnt)){ + if (!parsed_zsets_meta_value.CheckModifyCount(-del_cnt)) { return Status::InvalidArgument("zset size overflow"); } parsed_zsets_meta_value.ModifyCount(-del_cnt); @@ -261,7 +260,7 @@ Status Redis::ZAdd(const Slice& key, const std::vector& score_membe cnt++; } } - if (!parsed_zsets_meta_value.CheckModifyCount(cnt)){ + if (!parsed_zsets_meta_value.CheckModifyCount(cnt)) { return Status::InvalidArgument("zset size overflow"); } parsed_zsets_meta_value.ModifyCount(cnt); @@ -444,7 +443,7 @@ Status Redis::ZIncrby(const Slice& key, const Slice& member, double increment, d statistic++; } else if (s.IsNotFound()) { score = increment; - if (!parsed_zsets_meta_value.CheckModifyCount(1)){ + if (!parsed_zsets_meta_value.CheckModifyCount(1)) { return Status::InvalidArgument("zset size overflow"); } parsed_zsets_meta_value.ModifyCount(1); @@ -535,7 +534,7 @@ Status Redis::ZRange(const Slice& key, int32_t start, int32_t stop, std::vector< } Status Redis::ZRangeWithTTL(const Slice& key, int32_t start, int32_t stop, std::vector* score_members, - int64_t* ttl) { + int64_t* ttl_millsec) { score_members->clear(); rocksdb::ReadOptions read_options; const rocksdb::Snapshot* snapshot = nullptr; @@ -564,13 +563,12 @@ Status Redis::ZRangeWithTTL(const Slice& key, int32_t start, int32_t stop, std:: return Status::NotFound("Stale"); } else { // ttl - *ttl = parsed_zsets_meta_value.Etime(); - if (*ttl == 0) { - *ttl = -1; + *ttl_millsec = parsed_zsets_meta_value.Etime(); + if (*ttl_millsec == 0) { + *ttl_millsec = -1; } else { - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); - *ttl = *ttl - curtime >= 0 ? *ttl - curtime : -2; + pstd::TimeType curtime = pstd::NowMillis(); + *ttl_millsec = *ttl_millsec - curtime >= 0 ? *ttl_millsec - curtime : -2; } int32_t count = parsed_zsets_meta_value.Count(); @@ -797,7 +795,7 @@ Status Redis::ZRem(const Slice& key, const std::vector& members, in } } *ret = del_cnt; - if (!parsed_zsets_meta_value.CheckModifyCount(-del_cnt)){ + if (!parsed_zsets_meta_value.CheckModifyCount(-del_cnt)) { return Status::InvalidArgument("zset size overflow"); } parsed_zsets_meta_value.ModifyCount(-del_cnt); @@ -864,7 +862,7 @@ Status Redis::ZRemrangebyrank(const Slice& key, int32_t start, int32_t stop, int } delete iter; *ret = del_cnt; - if (!parsed_zsets_meta_value.CheckModifyCount(-del_cnt)){ + if (!parsed_zsets_meta_value.CheckModifyCount(-del_cnt)) { return Status::InvalidArgument("zset size overflow"); } parsed_zsets_meta_value.ModifyCount(-del_cnt); @@ -944,7 +942,7 @@ Status Redis::ZRemrangebyscore(const Slice& key, double min, double max, bool le } delete iter; *ret = del_cnt; - if (!parsed_zsets_meta_value.CheckModifyCount(-del_cnt)){ + if (!parsed_zsets_meta_value.CheckModifyCount(-del_cnt)) { return Status::InvalidArgument("zset size overflow"); } parsed_zsets_meta_value.ModifyCount(-del_cnt); @@ -1656,7 +1654,7 @@ Status Redis::ZRemrangebylex(const Slice& key, const Slice& min, const Slice& ma delete iter; } if (del_cnt > 0) { - if (!parsed_zsets_meta_value.CheckModifyCount(-del_cnt)){ + if (!parsed_zsets_meta_value.CheckModifyCount(-del_cnt)) { return Status::InvalidArgument("zset size overflow"); } parsed_zsets_meta_value.ModifyCount(-del_cnt); @@ -1671,7 +1669,7 @@ Status Redis::ZRemrangebylex(const Slice& key, const Slice& min, const Slice& ma return s; } -Status Redis::ZsetsExpire(const Slice& key, int64_t ttl, std::string&& prefetch_meta) { +Status Redis::ZsetsExpire(const Slice& key, int64_t ttl_millsec, std::string&& prefetch_meta) { std::string meta_value(std::move(prefetch_meta)); ScopeRecordLock l(lock_mgr_, key); BaseMetaKey base_meta_key(key); @@ -1700,8 +1698,8 @@ Status Redis::ZsetsExpire(const Slice& key, int64_t ttl, std::string&& prefetch_ return Status::NotFound(); } - if (ttl > 0) { - parsed_zsets_meta_value.SetRelativeTimestamp(ttl); + if (ttl_millsec > 0) { + parsed_zsets_meta_value.SetRelativeTimestamp(ttl_millsec); } else { parsed_zsets_meta_value.InitialMetaValue(); } @@ -1747,7 +1745,7 @@ Status Redis::ZsetsDel(const Slice& key, std::string&& prefetch_meta) { return s; } -Status Redis::ZsetsExpireat(const Slice& key, int64_t timestamp, std::string&& prefetch_meta) { +Status Redis::ZsetsExpireat(const Slice& key, int64_t timestamp_millsec, std::string&& prefetch_meta) { std::string meta_value(std::move(prefetch_meta)); ScopeRecordLock l(lock_mgr_, key); BaseMetaKey base_meta_key(key); @@ -1775,8 +1773,8 @@ Status Redis::ZsetsExpireat(const Slice& key, int64_t timestamp, std::string&& p } else if (parsed_zsets_meta_value.Count() == 0) { return Status::NotFound(); } else { - if (timestamp > 0) { - parsed_zsets_meta_value.SetEtime(uint64_t(timestamp)); + if (timestamp_millsec > 0) { + parsed_zsets_meta_value.SetEtime(uint64_t(timestamp_millsec)); } else { parsed_zsets_meta_value.InitialMetaValue(); } @@ -1912,7 +1910,7 @@ Status Redis::ZsetsPersist(const Slice& key, std::string&& prefetch_meta) { return s; } -Status Redis::ZsetsTTL(const Slice& key, int64_t* timestamp, std::string&& prefetch_meta) { +Status Redis::ZsetsTTL(const Slice& key, int64_t* ttl_millsec, std::string&& prefetch_meta) { std::string meta_value(std::move(prefetch_meta)); BaseMetaKey base_meta_key(key); Status s; @@ -1935,23 +1933,22 @@ Status Redis::ZsetsTTL(const Slice& key, int64_t* timestamp, std::string&& prefe if (s.ok()) { ParsedZSetsMetaValue parsed_zsets_meta_value(&meta_value); if (parsed_zsets_meta_value.IsStale()) { - *timestamp = -2; + *ttl_millsec = -2; return Status::NotFound("Stale"); } else if (parsed_zsets_meta_value.Count() == 0) { - *timestamp = -2; + *ttl_millsec = -2; return Status::NotFound(); } else { - *timestamp = parsed_zsets_meta_value.Etime(); - if (*timestamp == 0) { - *timestamp = -1; + *ttl_millsec = parsed_zsets_meta_value.Etime(); + if (*ttl_millsec == 0) { + *ttl_millsec = -1; } else { - int64_t curtime; - rocksdb::Env::Default()->GetCurrentTime(&curtime); - *timestamp = *timestamp - curtime >= 0 ? *timestamp - curtime : -2; + pstd::TimeType curtime = pstd::NowMillis(); + *ttl_millsec = *ttl_millsec - curtime >= 0 ? *ttl_millsec - curtime : -2; } } } else if (s.IsNotFound()) { - *timestamp = -2; + *ttl_millsec = -2; } return s; } diff --git a/src/storage/src/storage.cc b/src/storage/src/storage.cc index 006a6d00fb..84ac061850 100644 --- a/src/storage/src/storage.cc +++ b/src/storage/src/storage.cc @@ -133,9 +133,7 @@ Status Storage::StoreCursorStartKey(const DataType& dtype, int64_t cursor, char return cursors_store_->Insert(index_key, index_value); } -std::unique_ptr& Storage::GetDBInstance(const Slice& key) { - return GetDBInstance(key.ToString()); -} +std::unique_ptr& Storage::GetDBInstance(const Slice& key) { return GetDBInstance(key.ToString()); } std::unique_ptr& Storage::GetDBInstance(const std::string& key) { auto inst_index = slot_indexer_->GetInstanceID(GetSlotID(slot_num_, key)); @@ -148,9 +146,9 @@ Status Storage::Set(const Slice& key, const Slice& value) { return inst->Set(key, value); } -Status Storage::Setxx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl) { +Status Storage::Setxx(const Slice& key, const Slice& value, int32_t* ret, int64_t ttl_millsec) { auto& inst = GetDBInstance(key); - return inst->Setxx(key, value, ret, ttl); + return inst->Setxx(key, value, ret, ttl_millsec); } Status Storage::Get(const Slice& key, std::string* value) { @@ -158,14 +156,14 @@ Status Storage::Get(const Slice& key, std::string* value) { return inst->Get(key, value); } -Status Storage::GetWithTTL(const Slice& key, std::string* value, int64_t* ttl) { +Status Storage::GetWithTTL(const Slice& key, std::string* value, int64_t* ttl_millsec) { auto& inst = GetDBInstance(key); - return inst->GetWithTTL(key, value, ttl); + return inst->GetWithTTL(key, value, ttl_millsec); } -Status Storage::MGetWithTTL(const Slice& key, std::string* value, int64_t* ttl) { +Status Storage::MGetWithTTL(const Slice& key, std::string* value, int64_t* ttl_millsec) { auto& inst = GetDBInstance(key); - return inst->MGetWithTTL(key, value, ttl); + return inst->MGetWithTTL(key, value, ttl_millsec); } Status Storage::GetSet(const Slice& key, const Slice& value, std::string* old_value) { @@ -204,7 +202,7 @@ Status Storage::MGet(const std::vector& keys, std::vectorMGet(key, &value); if (s.ok()) { vss->push_back({value, Status::OK()}); - } else if(s.IsNotFound()) { + } else if (s.IsNotFound()) { vss->push_back({std::string(), Status::NotFound()}); } else { vss->clear(); @@ -220,12 +218,12 @@ Status Storage::MGetWithTTL(const std::vector& keys, std::vectorMGetWithTTL(key, &value, &ttl); + int64_t ttl_millsec; + s = inst->MGetWithTTL(key, &value, &ttl_millsec); if (s.ok()) { - vss->push_back({value, Status::OK(), ttl}); + vss->push_back({value, Status::OK(), ttl_millsec}); } else if (s.IsNotFound()) { - vss->push_back({std::string(), Status::NotFound(), ttl}); + vss->push_back({std::string(), Status::NotFound(), ttl_millsec}); } else { vss->clear(); return s; @@ -234,9 +232,9 @@ Status Storage::MGetWithTTL(const std::vector& keys, std::vectorSetnx(key, value, ret, ttl); + return inst->Setnx(key, value, ret, ttl_millsec); } // disallowed in codis, only runs in pika classic mode @@ -265,9 +263,9 @@ Status Storage::MSetnx(const std::vector& kvs, int32_t* ret) { return s; } -Status Storage::Setvx(const Slice& key, const Slice& value, const Slice& new_value, int32_t* ret, int64_t ttl) { +Status Storage::Setvx(const Slice& key, const Slice& value, const Slice& new_value, int32_t* ret, int64_t ttl_millsec) { auto& inst = GetDBInstance(key); - return inst->Setvx(key, value, new_value, ret, ttl); + return inst->Setvx(key, value, new_value, ret, ttl_millsec); } Status Storage::Delvx(const Slice& key, const Slice& value, int32_t* ret) { @@ -286,14 +284,14 @@ Status Storage::Getrange(const Slice& key, int64_t start_offset, int64_t end_off } Status Storage::GetrangeWithValue(const Slice& key, int64_t start_offset, int64_t end_offset, - std::string* ret, std::string* value, int64_t* ttl) { + std::string* ret, std::string* value, int64_t* ttl_millsec) { auto& inst = GetDBInstance(key); - return inst->GetrangeWithValue(key, start_offset, end_offset, ret, value, ttl); + return inst->GetrangeWithValue(key, start_offset, end_offset, ret, value, ttl_millsec); } -Status Storage::Append(const Slice& key, const Slice& value, int32_t* ret, int64_t* expired_timestamp_sec, std::string& out_new_value) { +Status Storage::Append(const Slice& key, const Slice& value, int32_t* ret, int64_t* expired_timestamp_millsec, std::string& out_new_value) { auto& inst = GetDBInstance(key); - return inst->Append(key, value, ret, expired_timestamp_sec, out_new_value); + return inst->Append(key, value, ret, expired_timestamp_millsec, out_new_value); } Status Storage::BitCount(const Slice& key, int64_t start_offset, int64_t end_offset, int32_t* ret, bool have_range) { @@ -355,9 +353,9 @@ Status Storage::Decrby(const Slice& key, int64_t value, int64_t* ret) { return inst->Decrby(key, value, ret); } -Status Storage::Incrby(const Slice& key, int64_t value, int64_t* ret, int64_t* expired_timestamp_sec) { +Status Storage::Incrby(const Slice& key, int64_t value, int64_t* ret, int64_t* expired_timestamp_millsec) { auto& inst = GetDBInstance(key); - return inst->Incrby(key, value, ret, expired_timestamp_sec); + return inst->Incrby(key, value, ret, expired_timestamp_millsec); } Status Storage::Incrbyfloat(const Slice& key, const Slice& value, std::string* ret, int64_t* expired_timestamp_sec) { @@ -365,9 +363,9 @@ Status Storage::Incrbyfloat(const Slice& key, const Slice& value, std::string* r return inst->Incrbyfloat(key, value, ret, expired_timestamp_sec); } -Status Storage::Setex(const Slice& key, const Slice& value, int64_t ttl) { +Status Storage::Setex(const Slice& key, const Slice& value, int64_t ttl_millsec) { auto& inst = GetDBInstance(key); - return inst->Setex(key, value, ttl); + return inst->Setex(key, value, ttl_millsec); } Status Storage::Strlen(const Slice& key, int32_t* len) { @@ -375,9 +373,12 @@ Status Storage::Strlen(const Slice& key, int32_t* len) { return inst->Strlen(key, len); } -Status Storage::PKSetexAt(const Slice& key, const Slice& value, int64_t timestamp) { +Status Storage::PKSetexAt(const Slice& key, const Slice& value, int64_t time_stamp_millsec_) { auto& inst = GetDBInstance(key); - return inst->PKSetexAt(key, value, timestamp); + if (time_stamp_millsec_ < 0) { + time_stamp_millsec_ = pstd::NowMillis() - 1; + } + return inst->PKSetexAt(key, value, time_stamp_millsec_); } // Hashes Commands @@ -406,9 +407,9 @@ Status Storage::HGetall(const Slice& key, std::vector* fvs) { return inst->HGetall(key, fvs); } -Status Storage::HGetallWithTTL(const Slice& key, std::vector* fvs, int64_t* ttl) { +Status Storage::HGetallWithTTL(const Slice& key, std::vector* fvs, int64_t* ttl_millsec) { auto& inst = GetDBInstance(key); - return inst->HGetallWithTTL(key, fvs, ttl); + return inst->HGetallWithTTL(key, fvs, ttl_millsec); } Status Storage::HKeys(const Slice& key, std::vector* fields) { @@ -634,9 +635,9 @@ Status Storage::SMembers(const Slice& key, std::vector* members) { return inst->SMembers(key, members); } -Status Storage::SMembersWithTTL(const Slice& key, std::vector* members, int64_t *ttl) { +Status Storage::SMembersWithTTL(const Slice& key, std::vector* members, int64_t * ttl_millsec) { auto& inst = GetDBInstance(key); - return inst->SMembersWithTTL(key, members, ttl); + return inst->SMembersWithTTL(key, members, ttl_millsec); } Status Storage::SMove(const Slice& source, const Slice& destination, const Slice& member, int32_t* ret) { @@ -761,9 +762,9 @@ Status Storage::LRange(const Slice& key, int64_t start, int64_t stop, std::vecto return inst->LRange(key, start, stop, ret); } -Status Storage::LRangeWithTTL(const Slice& key, int64_t start, int64_t stop, std::vector* ret, int64_t *ttl) { +Status Storage::LRangeWithTTL(const Slice& key, int64_t start, int64_t stop, std::vector* ret, int64_t * ttl_millsec) { auto& inst = GetDBInstance(key); - return inst->LRangeWithTTL(key, start, stop, ret, ttl); + return inst->LRangeWithTTL(key, start, stop, ret, ttl_millsec); } Status Storage::LTrim(const Slice& key, int64_t start, int64_t stop) { @@ -893,10 +894,10 @@ Status Storage::ZRange(const Slice& key, int32_t start, int32_t stop, std::vecto return inst->ZRange(key, start, stop, score_members); } Status Storage::ZRangeWithTTL(const Slice& key, int32_t start, int32_t stop, std::vector* score_members, - int64_t *ttl) { + int64_t * ttl_millsec) { score_members->clear(); auto& inst = GetDBInstance(key); - return inst->ZRangeWithTTL(key, start, stop, score_members, ttl); + return inst->ZRangeWithTTL(key, start, stop, score_members, ttl_millsec); } Status Storage::ZRangebyscore(const Slice& key, double min, double max, bool left_close, bool right_close, @@ -1178,10 +1179,10 @@ Status Storage::XInfo(const Slice& key, StreamInfoResult &result) { } // Keys Commands -int32_t Storage::Expire(const Slice& key, int64_t ttl) { +int32_t Storage::Expire(const Slice& key, int64_t ttl_millsec) { auto& inst = GetDBInstance(key); int32_t ret = 0; - Status s = inst->Expire(key, ttl); + Status s = inst->Expire(key, ttl_millsec); if (s.ok()) { ret++; } else if (!s.IsNotFound()) { @@ -1457,11 +1458,11 @@ Status Storage::Scanx(const DataType& data_type, const std::string& start_key, c return Status::OK(); } -int32_t Storage::Expireat(const Slice& key, int64_t timestamp) { +int32_t Storage::Expireat(const Slice& key, int64_t timestamp_millsec) { Status s; int32_t count = 0; auto& inst = GetDBInstance(key); - s = inst->Expireat(key, timestamp); + s = inst->Expireat(key, timestamp_millsec); if (s.ok()) { count++; } else if (!s.IsNotFound()) { @@ -1482,16 +1483,28 @@ int32_t Storage::Persist(const Slice& key) { return count; } +int64_t Storage::PTTL(const Slice& key) { + int64_t ttl_millsec = 0; + auto& inst = GetDBInstance(key); + Status s = inst->TTL(key, &ttl_millsec); + if (s.ok() || s.IsNotFound()) { + return ttl_millsec; + } else if (!s.IsNotFound()) { + return -3; + } + return ttl_millsec; +} + int64_t Storage::TTL(const Slice& key) { - int64_t timestamp = 0; + int64_t ttl_millsec = 0; auto& inst = GetDBInstance(key); - Status s = inst->TTL(key, ×tamp); + Status s = inst->TTL(key, &ttl_millsec); if (s.ok() || s.IsNotFound()) { - return timestamp; + return ttl_millsec > 0 ? ttl_millsec / 1000 : ttl_millsec; } else if (!s.IsNotFound()) { return -3; } - return timestamp; + return ttl_millsec > 0 ? ttl_millsec / 1000 : ttl_millsec; } Status Storage::GetType(const std::string& key, enum DataType& type) { @@ -1787,7 +1800,7 @@ Status Storage::SetMaxCacheStatisticKeys(uint32_t max_cache_statistic_keys) { } Status Storage::SetSmallCompactionThreshold(uint32_t small_compaction_threshold) { - for (const auto& inst: insts_) { + for (const auto& inst : insts_) { inst->SetSmallCompactionThreshold(small_compaction_threshold); } return Status::OK(); diff --git a/src/storage/src/strings_filter.h b/src/storage/src/strings_filter.h index fc03595d82..c53478bb11 100644 --- a/src/storage/src/strings_filter.h +++ b/src/storage/src/strings_filter.h @@ -20,8 +20,7 @@ class StringsFilter : public rocksdb::CompactionFilter { StringsFilter() = default; bool Filter(int level, const rocksdb::Slice& key, const rocksdb::Slice& value, std::string* new_value, bool* value_changed) const override { - int64_t unix_time; - rocksdb::Env::Default()->GetCurrentTime(&unix_time); + pstd::TimeType unix_time = pstd::NowMillis(); auto cur_time = static_cast(unix_time); ParsedStringsValue parsed_strings_value(value); TRACE("==========================START=========================="); diff --git a/src/storage/src/strings_value_format.h b/src/storage/src/strings_value_format.h index 6e001d7475..550104b339 100644 --- a/src/storage/src/strings_value_format.h +++ b/src/storage/src/strings_value_format.h @@ -35,9 +35,13 @@ class StringsValue : public InternalValue { dst += usize; memcpy(dst, reserve_, kSuffixReserveLength); dst += kSuffixReserveLength; - EncodeFixed64(dst, ctime_); + // The most significant bit is 1 for milliseconds and 0 for seconds. + // The previous data was stored in seconds, but the subsequent data was stored in milliseconds + uint64_t ctime = ctime_ > 0 ? (ctime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, ctime); dst += kTimestampLength; - EncodeFixed64(dst, etime_); + uint64_t etime = etime_ > 0 ? (etime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, etime); return {start_, needed}; } }; @@ -78,9 +82,20 @@ class ParsedStringsValue : public ParsedInternalValue { offset += user_value_.size(); memcpy(reserve_, internal_value_str->data() + offset, kSuffixReserveLength); offset += kSuffixReserveLength; - ctime_ = DecodeFixed64(internal_value_str->data() + offset); + uint64_t ctime = DecodeFixed64(internal_value_str->data() + offset); offset += sizeof(ctime_); - etime_ = DecodeFixed64(internal_value_str->data() + offset); + uint64_t etime = DecodeFixed64(internal_value_str->data() + offset); + + ctime_ = (ctime & ~(1ULL << 63)); + // if ctime_==ctime, means ctime_ storaged in seconds + if (ctime_ == ctime) { + ctime_ *= 1000; + } + etime_ = (etime & ~(1ULL << 63)); + // if etime_==etime, means etime_ storaged in seconds + if (etime == etime_) { + etime_ *= 1000; + } } } @@ -94,9 +109,20 @@ class ParsedStringsValue : public ParsedInternalValue { offset += user_value_.size(); memcpy(reserve_, internal_value_slice.data() + offset, kSuffixReserveLength); offset += kSuffixReserveLength; - ctime_ = DecodeFixed64(internal_value_slice.data() + offset); + uint64_t ctime = DecodeFixed64(internal_value_slice.data() + offset); offset += kTimestampLength; - etime_ = DecodeFixed64(internal_value_slice.data() + offset); + uint64_t etime = DecodeFixed64(internal_value_slice.data() + offset); + + ctime_ = (ctime & ~(1ULL << 63)); + // if ctime_==ctime, means ctime_ storaged in seconds + if (ctime_ == ctime) { + ctime_ *= 1000; + } + etime_ = (etime & ~(1ULL << 63)); + // if etime_==etime, means etime_ storaged in seconds + if (etime == etime_) { + etime_ *= 1000; + } } } @@ -114,7 +140,8 @@ class ParsedStringsValue : public ParsedInternalValue { if (value_) { char* dst = const_cast(value_->data()) + value_->size() - kStringsValueSuffixLength + kSuffixReserveLength; - EncodeFixed64(dst, ctime_); + uint64_t ctime = ctime_ > 0 ? (ctime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, ctime); } } @@ -122,7 +149,8 @@ class ParsedStringsValue : public ParsedInternalValue { if (value_) { char* dst = const_cast(value_->data()) + value_->size() - kStringsValueSuffixLength + kSuffixReserveLength + kTimestampLength; - EncodeFixed64(dst, etime_); + uint64_t etime = etime_ > 0 ? (etime_ | (1ULL << 63)) : 0; + EncodeFixed64(dst, etime); } } diff --git a/src/storage/src/zsets_filter.h b/src/storage/src/zsets_filter.h index 8c046c7d3b..629f12e669 100644 --- a/src/storage/src/zsets_filter.h +++ b/src/storage/src/zsets_filter.h @@ -80,8 +80,7 @@ class ZSetsScoreFilter : public rocksdb::CompactionFilter { return true; } - int64_t unix_time; - rocksdb::Env::Default()->GetCurrentTime(&unix_time); + pstd::TimeType unix_time = pstd::NowMillis(); if (cur_meta_etime_ != 0 && cur_meta_etime_ < static_cast(unix_time)) { TRACE("Drop[Timeout]"); return true; diff --git a/src/storage/tests/keys_test.cc b/src/storage/tests/keys_test.cc index 09292872f0..eeb7f8d9db 100644 --- a/src/storage/tests/keys_test.cc +++ b/src/storage/tests/keys_test.cc @@ -5179,8 +5179,7 @@ TEST_F(KeysTest, ExpireatTest) { s = db.Set("EXPIREAT_KEY", "VALUE"); ASSERT_TRUE(s.ok()); - int64_t unix_time; - rocksdb::Env::Default()->GetCurrentTime(&unix_time); + pstd::TimeType unix_time = pstd::NowMillis(); int64_t timestamp = unix_time + 1; ret = db.Expireat("EXPIREAT_KEY", timestamp); ASSERT_EQ(ret, 1); diff --git a/src/storage/tests/lists_filter_test.cc b/src/storage/tests/lists_filter_test.cc index 18e979d803..5197260d2c 100644 --- a/src/storage/tests/lists_filter_test.cc +++ b/src/storage/tests/lists_filter_test.cc @@ -102,7 +102,7 @@ TEST_F(ListsFilterTest, DataFilterTest) { EncodeFixed64(str, 1); ListsMetaValue lists_meta_value2(Slice(str, sizeof(uint64_t))); version = lists_meta_value2.UpdateVersion(); - lists_meta_value2.SetRelativeTimestamp(1); + lists_meta_value2.SetRelativeTimeInMillsec(1); s = meta_db->Put(rocksdb::WriteOptions(), handles[0], bmk.Encode(), lists_meta_value2.Encode()); ASSERT_TRUE(s.ok()); ListsDataKey lists_data_key2("FILTER_TEST_KEY", version, 1); @@ -119,7 +119,7 @@ TEST_F(ListsFilterTest, DataFilterTest) { EncodeFixed64(str, 1); ListsMetaValue lists_meta_value3(Slice(str, sizeof(uint64_t))); version = lists_meta_value3.UpdateVersion(); - lists_meta_value3.SetRelativeTimestamp(1); + lists_meta_value3.SetRelativeTimeInMillsec(1); s = meta_db->Put(rocksdb::WriteOptions(), handles[0], bmk.Encode(), lists_meta_value3.Encode()); ASSERT_TRUE(s.ok()); std::this_thread::sleep_for(std::chrono::milliseconds(2000)); diff --git a/src/storage/tests/strings_filter_test.cc b/src/storage/tests/strings_filter_test.cc index 26af189877..df5ac7b898 100644 --- a/src/storage/tests/strings_filter_test.cc +++ b/src/storage/tests/strings_filter_test.cc @@ -21,7 +21,7 @@ TEST(StringsFilterTest, FilterTest) { int64_t ttl = 1; StringsValue strings_value("FILTER_VALUE"); - strings_value.SetRelativeTimestamp(ttl); + strings_value.SetRelativeTimeInMillsec(ttl); is_stale = filter->Filter(0, "FILTER_KEY", strings_value.Encode(), &new_value, &value_changed); ASSERT_FALSE(is_stale); std::this_thread::sleep_for(std::chrono::milliseconds(2000)); diff --git a/src/storage/tests/strings_test.cc b/src/storage/tests/strings_test.cc index 361f6d082b..ebab6a2ac3 100644 --- a/src/storage/tests/strings_test.cc +++ b/src/storage/tests/strings_test.cc @@ -44,7 +44,7 @@ class StringsTest : public ::testing::Test { static bool make_expired(storage::Storage* const db, const Slice& key) { std::map type_status; - int ret = db->Expire(key, 1); + int ret = db->Expire(key, 1 * 100); if ((ret == 0) || !type_status[storage::DataType::kStrings].ok()) { return false; } @@ -71,15 +71,19 @@ TEST_F(StringsTest, AppendTest) { std::string value; std::string new_value; std::map type_status; - int64_t type_ttl; + int64_t expired_timestamp_millsec = 0; + int64_t expired_ttl_sec = 0; + // ***************** Group 1 Test ***************** - s = db.Append("GP1_APPEND_KEY", "HELLO", &ret, &type_ttl, new_value); + s = db.Append("GP1_APPEND_KEY", "HELLO", &ret, &expired_timestamp_millsec, new_value); ASSERT_TRUE(s.ok()); ASSERT_EQ(ret, 5); + ASSERT_EQ(expired_timestamp_millsec, 0); - s = db.Append("GP1_APPEND_KEY", " WORLD", &ret, &type_ttl, new_value); + s = db.Append("GP1_APPEND_KEY", " WORLD", &ret, &expired_timestamp_millsec, new_value); ASSERT_TRUE(s.ok()); ASSERT_EQ(ret, 11); + ASSERT_EQ(expired_timestamp_millsec, 0); s = db.Get("GP1_APPEND_KEY", &value); ASSERT_STREQ(value.c_str(), "HELLO WORLD"); @@ -87,38 +91,44 @@ TEST_F(StringsTest, AppendTest) { // ***************** Group 2 Test ***************** s = db.Set("GP2_APPEND_KEY", "VALUE"); ASSERT_TRUE(s.ok()); - ret = db.Expire("GP2_APPEND_KEY", 100); + + int64_t expect_expired_timestamp_millsec = pstd::NowMillis() + 1000 * 100; + ret = db.Expire("GP2_APPEND_KEY", 100 * 1000); ASSERT_EQ(ret, 1); type_status.clear(); - type_ttl = db.TTL("GP2_APPEND_KEY"); - ASSERT_LE(type_ttl, 100); - ASSERT_GE(type_ttl, 0); + expired_ttl_sec = db.TTL("GP2_APPEND_KEY"); + ASSERT_LE(expired_ttl_sec, 100); + ASSERT_GE(expired_ttl_sec, 0); - s = db.Append("GP2_APPEND_KEY", "VALUE", &ret, &type_ttl, new_value); + std::this_thread::sleep_for(std::chrono::milliseconds(5 * 1000)); + s = db.Append("GP2_APPEND_KEY", "VALUE", &ret, &expired_timestamp_millsec, new_value); ASSERT_TRUE(s.ok()); ASSERT_EQ(ret, 10); s = db.Get("GP2_APPEND_KEY", &value); ASSERT_STREQ(value.c_str(), "VALUEVALUE"); + ASSERT_GE(expired_timestamp_millsec, expect_expired_timestamp_millsec); + ASSERT_LT(expired_timestamp_millsec, expect_expired_timestamp_millsec + 1000); type_status.clear(); - type_ttl = db.TTL("GP2_APPEND_KEY"); - ASSERT_LE(type_ttl, 100); - ASSERT_GE(type_ttl, 0); + expired_ttl_sec = db.TTL("GP2_APPEND_KEY"); + ASSERT_LE(expired_ttl_sec, 95); + ASSERT_GT(expired_ttl_sec, 85); // ***************** Group 3 Test ***************** s = db.Set("GP3_APPEND_KEY", "VALUE"); ASSERT_TRUE(s.ok()); make_expired(&db, "GP3_APPEND_KEY"); - s = db.Append("GP3_APPEND_KEY", "VALUE", &ret, &type_ttl, new_value); + s = db.Append("GP3_APPEND_KEY", "VALUE", &ret, &expired_timestamp_millsec, new_value); ASSERT_TRUE(s.ok()); ASSERT_EQ(ret, 5); + ASSERT_EQ(expired_timestamp_millsec, 0); s = db.Get("GP3_APPEND_KEY", &value); ASSERT_STREQ(value.c_str(), "VALUE"); type_status.clear(); - type_ttl = db.TTL("GP3_APPEND_KEY"); - ASSERT_EQ(type_ttl, -1); + expired_ttl_sec = db.TTL("GP3_APPEND_KEY"); + ASSERT_EQ(expired_ttl_sec, -1); } // BitCount @@ -350,70 +360,86 @@ TEST_F(StringsTest, IncrbyTest) { int64_t ret; std::string value; std::map type_status; - int64_t type_ttl; + int64_t expired_timestamp_millsec = 0; + int64_t expired_ttl_sec = 0; // ***************** Group 1 Test ***************** // If the key is not exist - s = db.Incrby("GP1_INCRBY_KEY", 5, &ret, &type_ttl); + s = db.Incrby("GP1_INCRBY_KEY", 5, &ret, &expired_timestamp_millsec); ASSERT_TRUE(s.ok()); ASSERT_EQ(ret, 5); + ASSERT_EQ(expired_timestamp_millsec, 0); // If the key contains a string that can not be represented as integer s = db.Set("GP1_INCRBY_KEY", "INCRBY_VALUE"); ASSERT_TRUE(s.ok()); - s = db.Incrby("GP1_INCRBY_KEY", 5, &ret, &type_ttl); + s = db.Incrby("GP1_INCRBY_KEY", 5, &ret, &expired_timestamp_millsec); ASSERT_TRUE(s.IsCorruption()); + ASSERT_EQ(expired_timestamp_millsec, 0); s = db.Set("GP1_INCRBY_KEY", "1"); ASSERT_TRUE(s.ok()); // Less than the maximum number 9223372036854775807 - s = db.Incrby("GP1_INCRBY_KEY", 9223372036854775807, &ret, &type_ttl); + s = db.Incrby("GP1_INCRBY_KEY", 9223372036854775807, &ret, &expired_timestamp_millsec); ASSERT_TRUE(s.IsInvalidArgument()); + ASSERT_EQ(expired_timestamp_millsec, 0); // ***************** Group 2 Test ***************** s = db.Set("GP2_INCRBY_KEY", "10"); ASSERT_TRUE(s.ok()); - ret = db.Expire("GP2_INCRBY_KEY", 100); + int64_t expect_expired_timestamp_millsec = pstd::NowMillis() + 1000 * 100; + ret = db.Expire("GP2_INCRBY_KEY", 1000 * 100); ASSERT_EQ(ret, 1); type_status.clear(); - type_ttl = db.TTL("GP2_INCRBY_KEY"); - ASSERT_LE(type_ttl, 100); - ASSERT_GE(type_ttl, 0); - s = db.Incrby("GP2_INCRBY_KEY", 5, &ret, &type_ttl); + std::this_thread::sleep_for(std::chrono::seconds (5)); + expired_ttl_sec = db.TTL("GP2_INCRBY_KEY"); + ASSERT_LE(expired_ttl_sec, 95); + ASSERT_GT(expired_ttl_sec, 0); + + s = db.Incrby("GP2_INCRBY_KEY", 5, &ret, &expired_timestamp_millsec); ASSERT_TRUE(s.ok()); ASSERT_EQ(ret, 15); s = db.Get("GP2_INCRBY_KEY", &value); ASSERT_EQ(value, "15"); + ASSERT_GE(expired_timestamp_millsec, expect_expired_timestamp_millsec); + ASSERT_LT(expired_timestamp_millsec, expect_expired_timestamp_millsec + 1000); - type_ttl = db.TTL("GP2_INCRBY_KEY"); - ASSERT_LE(type_ttl, 100); - ASSERT_GE(type_ttl, 0); + std::this_thread::sleep_for(std::chrono::seconds (1)); + expired_ttl_sec = db.TTL("GP2_INCRBY_KEY"); + ASSERT_LE(expired_ttl_sec, 94); + ASSERT_GT(expired_ttl_sec, 0); // ***************** Group 3 Test ***************** s = db.Set("GP3_INCRBY_KEY", "10"); ASSERT_TRUE(s.ok()); make_expired(&db, "GP3_INCRBY_KEY"); - s = db.Incrby("GP3_INCRBY_KEY", 5, &ret, &type_ttl); + s = db.Get("GP3_INCRBY_KEY", &value); + ASSERT_EQ(value, ""); + + expired_timestamp_millsec = 0; + s = db.Incrby("GP3_INCRBY_KEY", 5, &ret, &expired_timestamp_millsec); ASSERT_TRUE(s.ok()); ASSERT_EQ(ret, 5); s = db.Get("GP3_INCRBY_KEY", &value); ASSERT_EQ(value, "5"); + ASSERT_EQ(expired_timestamp_millsec, 0); type_status.clear(); - type_ttl = db.TTL("GP3_INCRBY_KEY"); - ASSERT_EQ(type_ttl, -1); + expired_ttl_sec = db.TTL("GP3_INCRBY_KEY"); + ASSERT_EQ(expired_ttl_sec, -1); // ***************** Group 4 Test ***************** s = db.Set("GP4_INCRBY_KEY", "50000"); ASSERT_TRUE(s.ok()); - s = db.Incrby("GP4_INCRBY_KEY", 50000, &ret, &type_ttl); + s = db.Incrby("GP4_INCRBY_KEY", 50000, &ret, &expired_timestamp_millsec); ASSERT_TRUE(s.ok()); ASSERT_EQ(ret, 100000); s = db.Get("GP4_INCRBY_KEY", &value); ASSERT_EQ(value, "100000"); + ASSERT_EQ(expired_timestamp_millsec, 0); } // Incrbyfloat @@ -422,69 +448,80 @@ TEST_F(StringsTest, IncrbyfloatTest) { std::string value; std::map type_status; - int64_t type_ttl; double eps = 0.1; + int64_t expired_timestamp_millsec = 0; + int64_t expired_ttl_sec = 0; // ***************** Group 1 Test ***************** s = db.Set("GP1_INCRBYFLOAT_KEY", "10.50"); ASSERT_TRUE(s.ok()); - s = db.Incrbyfloat("GP1_INCRBYFLOAT_KEY", "0.1", &value, &type_ttl); + s = db.Incrbyfloat("GP1_INCRBYFLOAT_KEY", "0.1", &value, &expired_timestamp_millsec); ASSERT_TRUE(s.ok()); ASSERT_NEAR(std::stod(value), 10.6, eps); - s = db.Incrbyfloat("GP1_INCRBYFLOAT_KEY", "-5", &value, &type_ttl); + ASSERT_EQ(expired_timestamp_millsec, 0); + s = db.Incrbyfloat("GP1_INCRBYFLOAT_KEY", "-5", &value, &expired_timestamp_millsec); ASSERT_TRUE(s.ok()); ASSERT_NEAR(std::stod(value), 5.6, eps); + ASSERT_EQ(expired_timestamp_millsec, 0); // If the key contains a string that can not be represented as integer s = db.Set("GP1_INCRBYFLOAT_KEY", "INCRBY_VALUE"); ASSERT_TRUE(s.ok()); - s = db.Incrbyfloat("GP1_INCRBYFLOAT_KEY", "5", &value, &type_ttl); + s = db.Incrbyfloat("GP1_INCRBYFLOAT_KEY", "5", &value, &expired_timestamp_millsec); ASSERT_TRUE(s.IsCorruption()); + ASSERT_EQ(expired_timestamp_millsec, 0); // ***************** Group 2 Test ***************** s = db.Set("GP2_INCRBYFLOAT_KEY", "10.11111"); ASSERT_TRUE(s.ok()); - ret = db.Expire("GP2_INCRBYFLOAT_KEY", 100); + int64_t expect_expired_timestamp_millsec = pstd::NowMillis() + 1000 * 100; + ret = db.Expire("GP2_INCRBYFLOAT_KEY", 100 * 1000); ASSERT_EQ(ret, 1); type_status.clear(); - type_ttl = db.TTL("GP2_INCRBYFLOAT_KEY"); - ASSERT_LE(type_ttl, 100); - ASSERT_GE(type_ttl, 0); + std::this_thread::sleep_for(std::chrono::milliseconds(5 * 1000)); + expired_ttl_sec = db.TTL("GP2_INCRBYFLOAT_KEY"); + ASSERT_LE(expired_ttl_sec, 95); + ASSERT_GT(expired_ttl_sec, 90); - s = db.Incrbyfloat("GP2_INCRBYFLOAT_KEY", "10.22222", &value, &type_ttl); + s = db.Incrbyfloat("GP2_INCRBYFLOAT_KEY", "10.22222", &value, &expired_timestamp_millsec); ASSERT_TRUE(s.ok()); ASSERT_NEAR(std::stod(value), 20.33333, eps); + ASSERT_GE(expired_timestamp_millsec, expect_expired_timestamp_millsec); + ASSERT_LT(expired_timestamp_millsec, expect_expired_timestamp_millsec + 1000); s = db.Get("GP2_INCRBYFLOAT_KEY", &value); ASSERT_NEAR(std::stod(value), 20.33333, eps); - type_ttl = db.TTL("GP2_INCRBYFLOAT_KEY"); - ASSERT_LE(type_ttl, 100); - ASSERT_GE(type_ttl, 0); + std::this_thread::sleep_for(std::chrono::milliseconds(2 * 1000)); + expired_ttl_sec = db.TTL("GP2_INCRBYFLOAT_KEY"); + ASSERT_LE(expired_ttl_sec, 93); + ASSERT_GE(expired_ttl_sec, 90); // ***************** Group 3 Test ***************** s = db.Set("GP3_INCRBYFLOAT_KEY", "10"); ASSERT_TRUE(s.ok()); make_expired(&db, "GP3_INCRBYFLOAT_KEY"); - s = db.Incrbyfloat("GP3_INCRBYFLOAT_KEY", "0.123456", &value, &type_ttl); + s = db.Incrbyfloat("GP3_INCRBYFLOAT_KEY", "0.123456", &value, &expired_timestamp_millsec); ASSERT_TRUE(s.ok()); ASSERT_NEAR(std::stod(value), 0.123456, eps); s = db.Get("GP3_INCRBYFLOAT_KEY", &value); ASSERT_NEAR(std::stod(value), 0.123456, eps); + ASSERT_EQ(expired_timestamp_millsec, 0); type_status.clear(); - type_ttl = db.TTL("GP3_INCRBYFLOAT_KEY"); - ASSERT_EQ(type_ttl, -1); + expired_ttl_sec = db.TTL("GP3_INCRBYFLOAT_KEY"); + ASSERT_EQ(expired_ttl_sec, -1); // ***************** Group 4 Test ***************** s = db.Set("GP4_INCRBYFLOAT_KEY", "100.001"); ASSERT_TRUE(s.ok()); - s = db.Incrbyfloat("GP4_INCRBYFLOAT_KEY", "11.11", &value, &type_ttl); + s = db.Incrbyfloat("GP4_INCRBYFLOAT_KEY", "11.11", &value, &expired_timestamp_millsec); ASSERT_TRUE(s.ok()); ASSERT_NEAR(std::stod(value), 111.111, eps); s = db.Get("GP4_INCRBYFLOAT_KEY", &value); + ASSERT_EQ(expired_timestamp_millsec, 0); ASSERT_NEAR(std::stod(value), 111.111, eps); } @@ -764,7 +801,7 @@ TEST_F(StringsTest, SetvxTest) { ASSERT_TRUE(s.ok()); std::map type_status; - ret = db.Expire("GP6_SETVX_KEY", 10); + ret = db.Expire("GP6_SETVX_KEY", 10 * 1000); ASSERT_EQ(ret, 1); sleep(1); @@ -772,7 +809,7 @@ TEST_F(StringsTest, SetvxTest) { ASSERT_LT(0, ttl); ASSERT_GT(10, ttl); - s = db.Setvx("GP6_SETVX_KEY", "GP6_SETVX_VALUE", "GP6_SETVX_NEW_VALUE", &ret, 20); + s = db.Setvx("GP6_SETVX_KEY", "GP6_SETVX_VALUE", "GP6_SETVX_NEW_VALUE", &ret, 20 * 1000); ASSERT_TRUE(s.ok()); ASSERT_EQ(ret, 1); @@ -941,16 +978,13 @@ TEST_F(StringsTest, BitPosTest) { // PKSetexAt TEST_F(StringsTest, PKSetexAtTest) { -#ifdef OS_MACOSX - return ; -#endif - int64_t unix_time; - rocksdb::Env::Default()->GetCurrentTime(&unix_time); + pstd::TimeType unix_time; int64_t ttl_ret; std::map type_status; // ***************** Group 1 Test ***************** - s = db.PKSetexAt("GP1_PKSETEX_KEY", "VALUE", unix_time + 100); + unix_time = pstd::NowMillis(); + s = db.PKSetexAt("GP1_PKSETEX_KEY", "VALUE", unix_time + 100*1000); ASSERT_TRUE(s.ok()); type_status.clear(); @@ -960,9 +994,10 @@ TEST_F(StringsTest, PKSetexAtTest) { ASSERT_GE(ttl_ret, 90); // ***************** Group 2 Test ***************** + unix_time = pstd::NowMillis(); s = db.Set("GP2_PKSETEX_KEY", "VALUE"); ASSERT_TRUE(s.ok()); - s = db.PKSetexAt("GP2_PKSETEX_KEY", "VALUE", unix_time + 100); + s = db.PKSetexAt("GP2_PKSETEX_KEY", "VALUE", unix_time + 100*1000); ASSERT_TRUE(s.ok()); type_status.clear(); @@ -972,7 +1007,8 @@ TEST_F(StringsTest, PKSetexAtTest) { ASSERT_GE(ttl_ret, 90); // ***************** Group 3 Test ***************** - s = db.PKSetexAt("GP3_PKSETEX_KEY", "VALUE", unix_time - 100); + unix_time = pstd::NowMillis(); + s = db.PKSetexAt("GP3_PKSETEX_KEY", "VALUE", unix_time - 100*1000); ASSERT_TRUE(s.ok()); type_status.clear(); @@ -980,9 +1016,10 @@ TEST_F(StringsTest, PKSetexAtTest) { ASSERT_EQ(ttl_ret, -2); // ***************** Group 4 Test ***************** + unix_time = pstd::NowMillis(); s = db.Set("GP4_PKSETEX_KEY", "VALUE"); ASSERT_TRUE(s.ok()); - s = db.PKSetexAt("GP4_PKSETEX_KEY", "VALUE", unix_time - 100); + s = db.PKSetexAt("GP4_PKSETEX_KEY", "VALUE", unix_time - 100*1000); ASSERT_TRUE(s.ok()); type_status.clear(); @@ -990,6 +1027,7 @@ TEST_F(StringsTest, PKSetexAtTest) { ASSERT_EQ(ttl_ret, -2); // ***************** Group 5 Test ***************** + unix_time = pstd::NowMillis(); s = db.PKSetexAt("GP5_PKSETEX_KEY", "VALUE", -unix_time); ASSERT_TRUE(s.ok()); @@ -998,6 +1036,7 @@ TEST_F(StringsTest, PKSetexAtTest) { ASSERT_EQ(ttl_ret, -2); // ***************** Group 6 Test ***************** + unix_time = pstd::NowMillis(); s = db.Set("GP6_PKSETEX_KEY", "VALUE"); ASSERT_TRUE(s.ok()); s = db.PKSetexAt("GP6_PKSETEX_KEY", "VALUE", -unix_time);