Speedup keyIsExpired by removing subkey search
Former-commit-id: a01564158e40300ab4a0338c0a6e924972385407
This commit is contained in:
parent
9a2d6cbad2
commit
bafd03f53c
12
src/db.cpp
12
src/db.cpp
@ -1626,17 +1626,9 @@ int keyIsExpired(redisDb *db, robj *key) {
|
|||||||
/* Don't expire anything while loading. It will be done later. */
|
/* Don't expire anything while loading. It will be done later. */
|
||||||
if (g_pserver->loading) return 0;
|
if (g_pserver->loading) return 0;
|
||||||
|
|
||||||
long long when = -1;
|
long long when = pexpire->whenFull();
|
||||||
for (auto &exp : *pexpire)
|
|
||||||
{
|
|
||||||
if (exp.subkey() == nullptr)
|
|
||||||
{
|
|
||||||
when = exp.when();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (when == -1)
|
if (when == INVALID_EXPIRE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* If we are in the context of a Lua script, we pretend that time is
|
/* If we are in the context of a Lua script, we pretend that time is
|
||||||
|
@ -153,7 +153,7 @@ int activeExpireCycleExpire(redisDb *db, expireEntry &e, long long now, size_t &
|
|||||||
|
|
||||||
pfat->popfrontExpireEntry();
|
pfat->popfrontExpireEntry();
|
||||||
fTtlChanged = true;
|
fTtlChanged = true;
|
||||||
if ((tried % ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP) == 0) {
|
if ((tried % ACTIVE_EXPIRE_CYCLE_SUBKEY_LOOKUPS_PER_LOOP) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
32
src/expire.h
32
src/expire.h
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define INVALID_EXPIRE LLONG_MIN
|
||||||
|
|
||||||
class expireEntryFat
|
class expireEntryFat
|
||||||
{
|
{
|
||||||
friend class expireEntry;
|
friend class expireEntry;
|
||||||
@ -31,6 +33,14 @@ public:
|
|||||||
~expireEntryFat();
|
~expireEntryFat();
|
||||||
|
|
||||||
long long when() const noexcept { return m_vecexpireEntries.front().when; }
|
long long when() const noexcept { return m_vecexpireEntries.front().when; }
|
||||||
|
long long whenFull() const noexcept {
|
||||||
|
for (size_t i = 0; i < size(); ++i) {
|
||||||
|
if (m_vecexpireEntries[i].spsubkey == nullptr) {
|
||||||
|
return m_vecexpireEntries[i].when;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return INVALID_EXPIRE;
|
||||||
|
}
|
||||||
const char *key() const noexcept { return m_keyPrimary; }
|
const char *key() const noexcept { return m_keyPrimary; }
|
||||||
|
|
||||||
bool operator<(long long when) const noexcept { return this->when() < when; }
|
bool operator<(long long when) const noexcept { return this->when() < when; }
|
||||||
@ -51,7 +61,7 @@ class expireEntry {
|
|||||||
expireEntryFat *m_pfatentry;
|
expireEntryFat *m_pfatentry;
|
||||||
} u;
|
} u;
|
||||||
long long m_when; // LLONG_MIN means this is a fat entry and we should use the pointer
|
long long m_when; // LLONG_MIN means this is a fat entry and we should use the pointer
|
||||||
|
long long m_whenFull;
|
||||||
public:
|
public:
|
||||||
class iter
|
class iter
|
||||||
{
|
{
|
||||||
@ -91,7 +101,8 @@ public:
|
|||||||
{
|
{
|
||||||
if (subkey != nullptr)
|
if (subkey != nullptr)
|
||||||
{
|
{
|
||||||
m_when = LLONG_MIN;
|
m_when = INVALID_EXPIRE;
|
||||||
|
m_whenFull = INVALID_EXPIRE;
|
||||||
u.m_pfatentry = new (MALLOC_LOCAL) expireEntryFat(key);
|
u.m_pfatentry = new (MALLOC_LOCAL) expireEntryFat(key);
|
||||||
u.m_pfatentry->expireSubKey(subkey, when);
|
u.m_pfatentry->expireSubKey(subkey, when);
|
||||||
}
|
}
|
||||||
@ -99,19 +110,22 @@ public:
|
|||||||
{
|
{
|
||||||
u.m_key = key;
|
u.m_key = key;
|
||||||
m_when = when;
|
m_when = when;
|
||||||
|
m_whenFull = when;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expireEntry(expireEntryFat *pfatentry)
|
expireEntry(expireEntryFat *pfatentry)
|
||||||
{
|
{
|
||||||
u.m_pfatentry = pfatentry;
|
u.m_pfatentry = pfatentry;
|
||||||
m_when = LLONG_MIN;
|
m_when = INVALID_EXPIRE;
|
||||||
|
m_whenFull = pfatentry->whenFull();
|
||||||
}
|
}
|
||||||
|
|
||||||
expireEntry(expireEntry &&e)
|
expireEntry(expireEntry &&e)
|
||||||
{
|
{
|
||||||
u.m_key = e.u.m_key;
|
u.m_key = e.u.m_key;
|
||||||
m_when = e.m_when;
|
m_when = e.m_when;
|
||||||
|
m_whenFull = e.m_whenFull;
|
||||||
e.u.m_key = (char*)key(); // we do this so it can still be found in the set
|
e.u.m_key = (char*)key(); // we do this so it can still be found in the set
|
||||||
e.m_when = 0;
|
e.m_when = 0;
|
||||||
}
|
}
|
||||||
@ -130,7 +144,7 @@ public:
|
|||||||
u.m_key = key;
|
u.m_key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool FFat() const noexcept { return m_when == LLONG_MIN; }
|
inline bool FFat() const noexcept { return m_when == INVALID_EXPIRE; }
|
||||||
expireEntryFat *pfatentry() { assert(FFat()); return u.m_pfatentry; }
|
expireEntryFat *pfatentry() { assert(FFat()); return u.m_pfatentry; }
|
||||||
|
|
||||||
|
|
||||||
@ -160,9 +174,17 @@ public:
|
|||||||
return u.m_pfatentry->when();
|
return u.m_pfatentry->when();
|
||||||
return m_when;
|
return m_when;
|
||||||
}
|
}
|
||||||
|
long long whenFull() const noexcept
|
||||||
|
{
|
||||||
|
return m_whenFull;
|
||||||
|
}
|
||||||
|
|
||||||
void update(const char *subkey, long long when)
|
void update(const char *subkey, long long when)
|
||||||
{
|
{
|
||||||
|
if (subkey == nullptr)
|
||||||
|
{
|
||||||
|
m_whenFull = when;
|
||||||
|
}
|
||||||
if (!FFat())
|
if (!FFat())
|
||||||
{
|
{
|
||||||
if (subkey == nullptr)
|
if (subkey == nullptr)
|
||||||
@ -175,7 +197,7 @@ public:
|
|||||||
// we have to upgrade to a fat entry
|
// we have to upgrade to a fat entry
|
||||||
long long whenT = m_when;
|
long long whenT = m_when;
|
||||||
sds keyPrimary = u.m_key;
|
sds keyPrimary = u.m_key;
|
||||||
m_when = LLONG_MIN;
|
m_when = INVALID_EXPIRE;
|
||||||
u.m_pfatentry = new (MALLOC_LOCAL) expireEntryFat(keyPrimary);
|
u.m_pfatentry = new (MALLOC_LOCAL) expireEntryFat(keyPrimary);
|
||||||
u.m_pfatentry->expireSubKey(nullptr, whenT);
|
u.m_pfatentry->expireSubKey(nullptr, whenT);
|
||||||
// at this point we're fat so fall through
|
// at this point we're fat so fall through
|
||||||
|
@ -303,6 +303,7 @@ inline bool operator!=(const void *p, const robj_sharedptr &rhs)
|
|||||||
#define CONFIG_DEFAULT_ENABLE_MULTIMASTER 0
|
#define CONFIG_DEFAULT_ENABLE_MULTIMASTER 0
|
||||||
|
|
||||||
#define ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 64 /* Loopkups per loop. */
|
#define ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 64 /* Loopkups per loop. */
|
||||||
|
#define ACTIVE_EXPIRE_CYCLE_SUBKEY_LOOKUPS_PER_LOOP 16384 /* Subkey loopkups per loop. */
|
||||||
#define ACTIVE_EXPIRE_CYCLE_FAST_DURATION 1000 /* Microseconds */
|
#define ACTIVE_EXPIRE_CYCLE_FAST_DURATION 1000 /* Microseconds */
|
||||||
#define ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC 25 /* CPU max % for keys collection */
|
#define ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC 25 /* CPU max % for keys collection */
|
||||||
#define ACTIVE_EXPIRE_CYCLE_SLOW 0
|
#define ACTIVE_EXPIRE_CYCLE_SLOW 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user