mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2024-12-14 11:58:02 +00:00
Use DashTable for ExpireTable
This commit is contained in:
parent
d086341996
commit
97fbf69260
2 changed files with 41 additions and 13 deletions
|
@ -48,7 +48,7 @@ void DbSlice::Reserve(DbIndex db_ind, size_t key_size) {
|
|||
|
||||
auto DbSlice::Find(DbIndex db_index, std::string_view key, unsigned req_obj_type) const
|
||||
-> OpResult<MainIterator> {
|
||||
auto [it, expire_it] = FindExt(db_index, key);
|
||||
auto it = FindExt(db_index, key).first;
|
||||
|
||||
if (!IsValid(it))
|
||||
return OpStatus::KEY_NOTFOUND;
|
||||
|
@ -72,11 +72,11 @@ pair<MainIterator, ExpireIterator> DbSlice::FindExt(DbIndex db_ind, std::string_
|
|||
|
||||
ExpireIterator expire_it;
|
||||
if (it->second.HasExpire()) { // check expiry state
|
||||
expire_it = db->expire_table.find(it->first);
|
||||
expire_it = db->expire_table.Find(CompactObj{it->first});
|
||||
|
||||
CHECK(IsValid(expire_it));
|
||||
if (expire_it->second <= now_ms_) {
|
||||
db->expire_table.erase(expire_it);
|
||||
db->expire_table.Erase(expire_it);
|
||||
|
||||
db->stats.obj_memory_usage -= (it->first.capacity() + it->second.MallocUsed());
|
||||
db->main_table.erase(it);
|
||||
|
@ -103,7 +103,7 @@ OpResult<pair<MainIterator, unsigned>> DbSlice::FindFirst(DbIndex db_index, cons
|
|||
return OpStatus::KEY_NOTFOUND;
|
||||
}
|
||||
|
||||
auto DbSlice::AddOrFind(DbIndex db_index, std::string_view key) -> pair<MainIterator, bool> {
|
||||
auto DbSlice::AddOrFind(DbIndex db_index, string_view key) -> pair<MainIterator, bool> {
|
||||
DCHECK(IsDbValid(db_index));
|
||||
|
||||
auto& db = db_arr_[db_index];
|
||||
|
@ -120,11 +120,11 @@ auto DbSlice::AddOrFind(DbIndex db_index, std::string_view key) -> pair<MainIter
|
|||
DCHECK(IsValid(existing));
|
||||
|
||||
if (existing->second.HasExpire()) {
|
||||
auto expire_it = db->expire_table.find(existing->first);
|
||||
auto expire_it = db->expire_table.Find(CompactObj{existing->first});
|
||||
CHECK(IsValid(expire_it));
|
||||
|
||||
if (expire_it->second <= now_ms_) {
|
||||
db->expire_table.erase(expire_it);
|
||||
db->expire_table.Erase(expire_it);
|
||||
|
||||
// Keep the entry but free the object.
|
||||
db->stats.obj_memory_usage -= existing->second.MallocUsed();
|
||||
|
@ -157,7 +157,8 @@ bool DbSlice::Del(DbIndex db_ind, const MainIterator& it) {
|
|||
}
|
||||
|
||||
if (it->second.HasExpire()) {
|
||||
CHECK_EQ(1u, db->expire_table.erase(it->first));
|
||||
CompactObj cobj{it->first};
|
||||
CHECK_EQ(1u, db->expire_table.Erase(cobj));
|
||||
}
|
||||
|
||||
db->stats.obj_memory_usage -= (it->first.capacity() + it->second.MallocUsed());
|
||||
|
@ -174,7 +175,7 @@ size_t DbSlice::FlushDb(DbIndex db_ind) {
|
|||
|
||||
size_t removed = db->main_table.size();
|
||||
db->main_table.clear();
|
||||
db->expire_table.clear();
|
||||
db->expire_table.Clear();
|
||||
|
||||
db->stats.obj_memory_usage = 0;
|
||||
|
||||
|
@ -200,14 +201,15 @@ size_t DbSlice::FlushDb(DbIndex db_ind) {
|
|||
bool DbSlice::Expire(DbIndex db_ind, MainIterator it, uint64_t at) {
|
||||
auto& db = db_arr_[db_ind];
|
||||
if (at == 0 && it->second.HasExpire()) {
|
||||
CHECK_EQ(1u, db->expire_table.erase(it->first));
|
||||
CompactObj cobj(it->first);
|
||||
CHECK_EQ(1u, db->expire_table.Erase(cobj));
|
||||
it->second.SetExpire(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!it->second.HasExpire() && at) {
|
||||
CHECK(db->expire_table.emplace(it->first, at).second);
|
||||
CHECK(db->expire_table.Insert(CompactObj{it->first}, at).second);
|
||||
it->second.SetExpire(true);
|
||||
|
||||
return true;
|
||||
|
@ -233,7 +235,8 @@ bool DbSlice::AddIfNotExist(DbIndex db_ind, string_view key, MainValue obj, uint
|
|||
|
||||
if (expire_at_ms) {
|
||||
new_entry->second.SetExpire(true);
|
||||
CHECK(db->expire_table.emplace(new_entry->first, expire_at_ms).second);
|
||||
|
||||
CHECK(db->expire_table.Insert(CompactObj{new_entry->first}, expire_at_ms).second);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -7,12 +7,37 @@
|
|||
#include <absl/container/flat_hash_map.h>
|
||||
|
||||
#include "core/compact_object.h"
|
||||
#include "core/dash.h"
|
||||
|
||||
namespace dfly {
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct ExpireTablePolicy {
|
||||
enum { kSlotNum = 12, kBucketNum = 64, kStashBucketNum = 2 };
|
||||
static constexpr bool kUseVersion = false;
|
||||
|
||||
static uint64_t HashFn(const CompactObj& s) {
|
||||
return s.HashCode();
|
||||
}
|
||||
|
||||
static void DestroyKey(CompactObj& cs) {
|
||||
cs.Reset();
|
||||
}
|
||||
|
||||
static void DestroyValue(uint64_t) {
|
||||
}
|
||||
|
||||
static bool Equal(const CompactObj& s1, const CompactObj& s2) {
|
||||
return s1 == s2;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
using MainValue = CompactObj;
|
||||
using MainTable = absl::flat_hash_map<std::string, MainValue>;
|
||||
using ExpireTable = absl::flat_hash_map<std::string, uint64_t>;
|
||||
using ExpireTable = DashTable<CompactObj, uint64_t, detail::ExpireTablePolicy>;
|
||||
|
||||
/// Iterators are invalidated when new keys are added to the table or some entries are deleted.
|
||||
/// Iterators are still valid if a different entry in the table was mutated.
|
||||
|
@ -24,7 +49,7 @@ inline bool IsValid(MainIterator it) {
|
|||
}
|
||||
|
||||
inline bool IsValid(ExpireIterator it) {
|
||||
return it != ExpireIterator{};
|
||||
return !it.is_done();
|
||||
}
|
||||
|
||||
} // namespace dfly
|
||||
|
|
Loading…
Reference in a new issue