Cleanup inheritance
Former-commit-id: e8debc83e8271cf8d76c5084923cf6e1ea7af3b4
This commit is contained in:
parent
afa487ca54
commit
cec6f0e934
36
src/db.cpp
36
src/db.cpp
@ -230,12 +230,12 @@ void redisDb::dbOverwriteCore(redisDb::iter itr, robj *key, robj *val, bool fUpd
|
|||||||
|
|
||||||
if (old->FExpires()) {
|
if (old->FExpires()) {
|
||||||
if (fRemoveExpire) {
|
if (fRemoveExpire) {
|
||||||
removeExpire(this, key);
|
::removeExpire(this, key);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (val->getrefcount(std::memory_order_relaxed) == OBJ_SHARED_REFCOUNT)
|
if (val->getrefcount(std::memory_order_relaxed) == OBJ_SHARED_REFCOUNT)
|
||||||
val = dupStringObject(val);
|
val = dupStringObject(val);
|
||||||
updateExpire(this, itr.key(), old, val);
|
::updateExpire(this, itr.key(), old, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ void redisDb::dbOverwriteCore(redisDb::iter itr, robj *key, robj *val, bool fUpd
|
|||||||
else
|
else
|
||||||
decrRefCount(itr.val());
|
decrRefCount(itr.val());
|
||||||
|
|
||||||
m_persistentData.updateValue(itr, val);
|
updateValue(itr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Overwrite an existing key with a new value. Incrementing the reference
|
/* Overwrite an existing key with a new value. Incrementing the reference
|
||||||
@ -379,7 +379,7 @@ bool redisDbPersistentData::syncDelete(robj *key)
|
|||||||
|
|
||||||
/* Delete a key, value, and associated expiration entry if any, from the DB */
|
/* Delete a key, value, and associated expiration entry if any, from the DB */
|
||||||
int dbSyncDelete(redisDb *db, robj *key) {
|
int dbSyncDelete(redisDb *db, robj *key) {
|
||||||
return db->m_persistentData.syncDelete(key);
|
return db->syncDelete(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a wrapper whose behavior depends on the Redis lazy free
|
/* This is a wrapper whose behavior depends on the Redis lazy free
|
||||||
@ -628,7 +628,7 @@ void randomkeyCommand(client *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool redisDbPersistentData::iterate(std::function<bool(const char*, robj*)> &fn)
|
bool redisDbPersistentData::iterate(std::function<bool(const char*, robj*)> fn)
|
||||||
{
|
{
|
||||||
dictIterator *di = dictGetSafeIterator(m_pdict);
|
dictIterator *di = dictGetSafeIterator(m_pdict);
|
||||||
dictEntry *de = nullptr;
|
dictEntry *de = nullptr;
|
||||||
@ -1154,7 +1154,7 @@ int dbSwapDatabases(int id1, int id2) {
|
|||||||
/* Swap hash tables. Note that we don't swap blocking_keys,
|
/* Swap hash tables. Note that we don't swap blocking_keys,
|
||||||
* ready_keys and watched_keys, since we want clients to
|
* ready_keys and watched_keys, since we want clients to
|
||||||
* remain in the same DB they were. */
|
* remain in the same DB they were. */
|
||||||
redisDbPersistentData::swap(&db1->m_persistentData, &db2->m_persistentData);
|
redisDbPersistentData::swap(db1, db2);
|
||||||
db1->avg_ttl = db2->avg_ttl;
|
db1->avg_ttl = db2->avg_ttl;
|
||||||
db1->last_expire_set = db2->last_expire_set;
|
db1->last_expire_set = db2->last_expire_set;
|
||||||
db1->expireitr = db2->expireitr;
|
db1->expireitr = db2->expireitr;
|
||||||
@ -1211,7 +1211,7 @@ void swapdbCommand(client *c) {
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
int removeExpire(redisDb *db, robj *key) {
|
int removeExpire(redisDb *db, robj *key) {
|
||||||
auto itr = db->find(key);
|
auto itr = db->find(key);
|
||||||
return db->m_persistentData.removeExpire(key, itr);
|
return db->removeExpire(key, itr);
|
||||||
}
|
}
|
||||||
int redisDbPersistentData::removeExpire(robj *key, dict_iter itr) {
|
int redisDbPersistentData::removeExpire(robj *key, dict_iter itr) {
|
||||||
/* An expire may only be removed if there is a corresponding entry in the
|
/* An expire may only be removed if there is a corresponding entry in the
|
||||||
@ -1285,7 +1285,7 @@ void setExpire(client *c, redisDb *db, robj *key, robj *subkey, long long when)
|
|||||||
db->last_expire_set = now;
|
db->last_expire_set = now;
|
||||||
|
|
||||||
/* Update the expire set */
|
/* Update the expire set */
|
||||||
db->m_persistentData.setExpire(key, subkey, when);
|
db->setExpire(key, subkey, when);
|
||||||
|
|
||||||
int writable_slave = listLength(g_pserver->masters) && g_pserver->repl_slave_ro == 0;
|
int writable_slave = listLength(g_pserver->masters) && g_pserver->repl_slave_ro == 0;
|
||||||
if (c && writable_slave && !(c->flags & CLIENT_MASTER))
|
if (c && writable_slave && !(c->flags & CLIENT_MASTER))
|
||||||
@ -1303,14 +1303,14 @@ void setExpire(client *c, redisDb *db, robj *key, expireEntry &&e)
|
|||||||
if (kde.val()->getrefcount(std::memory_order_relaxed) == OBJ_SHARED_REFCOUNT)
|
if (kde.val()->getrefcount(std::memory_order_relaxed) == OBJ_SHARED_REFCOUNT)
|
||||||
{
|
{
|
||||||
// shared objects cannot have the expire bit set, create a real object
|
// shared objects cannot have the expire bit set, create a real object
|
||||||
db->m_persistentData.updateValue(kde, dupStringObject(kde.val()));
|
db->updateValue(kde, dupStringObject(kde.val()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kde.val()->FExpires())
|
if (kde.val()->FExpires())
|
||||||
removeExpire(db, key);
|
removeExpire(db, key);
|
||||||
|
|
||||||
e.setKeyUnsafe(kde.key());
|
e.setKeyUnsafe(kde.key());
|
||||||
db->m_persistentData.setExpire(std::move(e));
|
db->setExpire(std::move(e));
|
||||||
kde.val()->SetFExpires(true);
|
kde.val()->SetFExpires(true);
|
||||||
|
|
||||||
|
|
||||||
@ -1332,7 +1332,7 @@ expireEntry *redisDb::getExpire(robj_roptr key) {
|
|||||||
if (!itr.val()->FExpires())
|
if (!itr.val()->FExpires())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto itrExpire = m_persistentData.findExpire(itr.key());
|
auto itrExpire = findExpire(itr.key());
|
||||||
return itrExpire.operator->();
|
return itrExpire.operator->();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1811,8 +1811,8 @@ void redisDbPersistentData::initialize()
|
|||||||
|
|
||||||
void redisDb::initialize(int id)
|
void redisDb::initialize(int id)
|
||||||
{
|
{
|
||||||
m_persistentData.initialize();
|
redisDbPersistentData::initialize();
|
||||||
this->expireitr = m_persistentData.setexpire()->end();
|
this->expireitr = setexpire()->end();
|
||||||
this->blocking_keys = dictCreate(&keylistDictType,NULL);
|
this->blocking_keys = dictCreate(&keylistDictType,NULL);
|
||||||
this->ready_keys = dictCreate(&objectKeyPointerValueDictType,NULL);
|
this->ready_keys = dictCreate(&objectKeyPointerValueDictType,NULL);
|
||||||
this->watched_keys = dictCreate(&keylistDictType,NULL);
|
this->watched_keys = dictCreate(&keylistDictType,NULL);
|
||||||
@ -1838,13 +1838,13 @@ void redisDbPersistentData::tryResize()
|
|||||||
|
|
||||||
size_t redisDb::clear(bool fAsync, void(callback)(void*))
|
size_t redisDb::clear(bool fAsync, void(callback)(void*))
|
||||||
{
|
{
|
||||||
size_t removed = m_persistentData.size();
|
size_t removed = size();
|
||||||
if (fAsync) {
|
if (fAsync) {
|
||||||
m_persistentData.emptyDbAsync();
|
redisDbPersistentData::emptyDbAsync();
|
||||||
} else {
|
} else {
|
||||||
m_persistentData.clear(callback);
|
redisDbPersistentData::clear(callback);
|
||||||
}
|
}
|
||||||
expireitr = m_persistentData.setexpire()->end();
|
expireitr = setexpire()->end();
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1913,7 +1913,7 @@ void redisDbPersistentData::setExpire(expireEntry &&e)
|
|||||||
|
|
||||||
bool redisDb::FKeyExpires(const char *key)
|
bool redisDb::FKeyExpires(const char *key)
|
||||||
{
|
{
|
||||||
return m_persistentData.setexpireUnsafe()->find(key) != m_persistentData.setexpire()->end();
|
return setexpireUnsafe()->find(key) != setexpire()->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void redisDbPersistentData::updateValue(dict_iter itr, robj *val)
|
void redisDbPersistentData::updateValue(dict_iter itr, robj *val)
|
||||||
|
@ -256,13 +256,13 @@ void evictionPoolPopulate(int dbid, redisDb *db, expireset *setexpire, struct ev
|
|||||||
{
|
{
|
||||||
if (setexpire != nullptr)
|
if (setexpire != nullptr)
|
||||||
{
|
{
|
||||||
visitFunctor visitor { dbid, db->m_persistentData.dictUnsafeKeyOnly(), pool, 0 };
|
visitFunctor visitor { dbid, db->dictUnsafeKeyOnly(), pool, 0 };
|
||||||
setexpire->random_visit(visitor);
|
setexpire->random_visit(visitor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dictEntry **samples = (dictEntry**)alloca(g_pserver->maxmemory_samples * sizeof(dictEntry*));
|
dictEntry **samples = (dictEntry**)alloca(g_pserver->maxmemory_samples * sizeof(dictEntry*));
|
||||||
int count = dictGetSomeKeys(db->m_persistentData.dictUnsafeKeyOnly(),samples,g_pserver->maxmemory_samples);
|
int count = dictGetSomeKeys(db->dictUnsafeKeyOnly(),samples,g_pserver->maxmemory_samples);
|
||||||
for (int j = 0; j < count; j++) {
|
for (int j = 0; j < count; j++) {
|
||||||
robj *o = (robj*)dictGetVal(samples[j]);
|
robj *o = (robj*)dictGetVal(samples[j]);
|
||||||
serverAssert(o != nullptr); // BUG!!! We have to get the info we need here without permanently rehydrating the obj
|
serverAssert(o != nullptr); // BUG!!! We have to get the info we need here without permanently rehydrating the obj
|
||||||
@ -514,7 +514,7 @@ int freeMemoryIfNeeded(void) {
|
|||||||
{
|
{
|
||||||
keys = db->expireSize();
|
keys = db->expireSize();
|
||||||
if (keys != 0)
|
if (keys != 0)
|
||||||
evictionPoolPopulate(i, db, db->m_persistentData.setexpireUnsafe(), pool);
|
evictionPoolPopulate(i, db, db->setexpireUnsafe(), pool);
|
||||||
total_keys += keys;
|
total_keys += keys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,7 +295,7 @@ void activeExpireCycle(int type) {
|
|||||||
now = mstime();
|
now = mstime();
|
||||||
|
|
||||||
/* If there is nothing to expire try next DB ASAP. */
|
/* If there is nothing to expire try next DB ASAP. */
|
||||||
if (db->m_persistentData.setexpireUnsafe()->empty())
|
if (db->setexpireUnsafe()->empty())
|
||||||
{
|
{
|
||||||
db->avg_ttl = 0;
|
db->avg_ttl = 0;
|
||||||
db->last_expire_set = now;
|
db->last_expire_set = now;
|
||||||
@ -305,7 +305,7 @@ void activeExpireCycle(int type) {
|
|||||||
size_t expired = 0;
|
size_t expired = 0;
|
||||||
size_t tried = 0;
|
size_t tried = 0;
|
||||||
long long check = ACTIVE_EXPIRE_CYCLE_FAST_DURATION; // assume a check is roughly 1us. It isn't but good enough
|
long long check = ACTIVE_EXPIRE_CYCLE_FAST_DURATION; // assume a check is roughly 1us. It isn't but good enough
|
||||||
db->expireitr = db->m_persistentData.setexpireUnsafe()->enumerate(db->expireitr, now, [&](expireEntry &e) __attribute__((always_inline)) {
|
db->expireitr = db->setexpireUnsafe()->enumerate(db->expireitr, now, [&](expireEntry &e) __attribute__((always_inline)) {
|
||||||
if (e.when() < now)
|
if (e.when() < now)
|
||||||
{
|
{
|
||||||
activeExpireCycleExpire(db, e, now);
|
activeExpireCycleExpire(db, e, now);
|
||||||
@ -406,12 +406,12 @@ void expireSlaveKeys(void) {
|
|||||||
|
|
||||||
// the expire is hashed based on the key pointer, so we need the point in the main db
|
// the expire is hashed based on the key pointer, so we need the point in the main db
|
||||||
auto itrDB = db->find(keyname);
|
auto itrDB = db->find(keyname);
|
||||||
auto itrExpire = db->m_persistentData.setexpire()->end();
|
auto itrExpire = db->setexpire()->end();
|
||||||
if (itrDB != nullptr)
|
if (itrDB != nullptr)
|
||||||
itrExpire = db->m_persistentData.setexpireUnsafe()->find(itrDB.key());
|
itrExpire = db->setexpireUnsafe()->find(itrDB.key());
|
||||||
int expired = 0;
|
int expired = 0;
|
||||||
|
|
||||||
if (itrExpire != db->m_persistentData.setexpire()->end())
|
if (itrExpire != db->setexpire()->end())
|
||||||
{
|
{
|
||||||
if (itrExpire->when() < start) {
|
if (itrExpire->when() < start) {
|
||||||
activeExpireCycleExpire(g_pserver->db+dbid,*itrExpire,start);
|
activeExpireCycleExpire(g_pserver->db+dbid,*itrExpire,start);
|
||||||
@ -423,7 +423,7 @@ void expireSlaveKeys(void) {
|
|||||||
* corresponding bit in the new bitmap we set as value.
|
* corresponding bit in the new bitmap we set as value.
|
||||||
* At the end of the loop if the bitmap is zero, it means we
|
* At the end of the loop if the bitmap is zero, it means we
|
||||||
* no longer need to keep track of this key. */
|
* no longer need to keep track of this key. */
|
||||||
if (itrExpire != db->m_persistentData.setexpire()->end() && !expired) {
|
if (itrExpire != db->setexpire()->end() && !expired) {
|
||||||
noexpire++;
|
noexpire++;
|
||||||
new_dbids |= (uint64_t)1 << dbid;
|
new_dbids |= (uint64_t)1 << dbid;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ bool redisDbPersistentData::asyncDelete(robj *key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int dbAsyncDelete(redisDb *db, robj *key) {
|
int dbAsyncDelete(redisDb *db, robj *key) {
|
||||||
return db->m_persistentData.asyncDelete(key);
|
return db->asyncDelete(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free an object, if the object is huge enough, free it in async way. */
|
/* Free an object, if the object is huge enough, free it in async way. */
|
||||||
|
60
src/server.h
60
src/server.h
@ -1138,7 +1138,7 @@ public:
|
|||||||
int removeSubkeyExpire(robj *key, robj *subkey);
|
int removeSubkeyExpire(robj *key, robj *subkey);
|
||||||
void clear(void(callback)(void*));
|
void clear(void(callback)(void*));
|
||||||
void emptyDbAsync();
|
void emptyDbAsync();
|
||||||
bool iterate(std::function<bool(const char*, robj*)> &fn);
|
bool iterate(std::function<bool(const char*, robj*)> fn);
|
||||||
void setExpire(robj *key, robj *subkey, long long when);
|
void setExpire(robj *key, robj *subkey, long long when);
|
||||||
void setExpire(expireEntry &&e);
|
void setExpire(expireEntry &&e);
|
||||||
void initialize();
|
void initialize();
|
||||||
@ -1172,7 +1172,8 @@ private:
|
|||||||
/* Redis database representation. There are multiple databases identified
|
/* Redis database representation. There are multiple databases identified
|
||||||
* by integers from 0 (the default database) up to the max configured
|
* by integers from 0 (the default database) up to the max configured
|
||||||
* database. The database number is the 'id' field in the structure. */
|
* database. The database number is the 'id' field in the structure. */
|
||||||
typedef struct redisDb {
|
typedef struct redisDb : protected redisDbPersistentData
|
||||||
|
{
|
||||||
// Legacy C API, Do not add more
|
// Legacy C API, Do not add more
|
||||||
friend void tryResizeHashTables(int);
|
friend void tryResizeHashTables(int);
|
||||||
friend int dbSyncDelete(redisDb *db, robj *key);
|
friend int dbSyncDelete(redisDb *db, robj *key);
|
||||||
@ -1195,57 +1196,40 @@ typedef struct redisDb {
|
|||||||
redisDb()
|
redisDb()
|
||||||
: expireitr(nullptr)
|
: expireitr(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void initialize(int id);
|
void initialize(int id);
|
||||||
|
|
||||||
size_t slots() const { return m_persistentData.slots(); }
|
// Forward Persistent Data APIs
|
||||||
size_t size() const { return m_persistentData.size(); }
|
using redisDbPersistentData::slots;
|
||||||
size_t expireSize() const { return m_persistentData.expireSize(); }
|
using redisDbPersistentData::size;
|
||||||
void expand(uint64_t slots) { m_persistentData.expand(slots); }
|
using redisDbPersistentData::expireSize;
|
||||||
void tryResize() { m_persistentData.tryResize(); }
|
using redisDbPersistentData::expand;
|
||||||
const expireset *setexpire() { return m_persistentData.setexpire(); }
|
using redisDbPersistentData::random;
|
||||||
|
using redisDbPersistentData::incrementallyRehash;
|
||||||
void trackChanges() { m_persistentData.trackChanges(); }
|
using redisDbPersistentData::trackkey;
|
||||||
void processChanges() { m_persistentData.processChanges(); }
|
using redisDbPersistentData::setexpire;
|
||||||
void trackkey(robj_roptr o) { m_persistentData.trackkey(o); }
|
using redisDbPersistentData::insert;
|
||||||
|
using redisDbPersistentData::iterate;
|
||||||
|
using redisDbPersistentData::trackChanges;
|
||||||
|
using redisDbPersistentData::processChanges;
|
||||||
|
using redisDbPersistentData::getStats;
|
||||||
|
using redisDbPersistentData::getExpireStats;
|
||||||
|
using redisDbPersistentData::removeSubkeyExpire;
|
||||||
|
|
||||||
|
using redisDbPersistentData::find;
|
||||||
iter find(robj_roptr key)
|
iter find(robj_roptr key)
|
||||||
{
|
{
|
||||||
return find(szFromObj(key));
|
return redisDbPersistentData::find(szFromObj(key));
|
||||||
}
|
|
||||||
iter find(const char *key)
|
|
||||||
{
|
|
||||||
return m_persistentData.find(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
iter random()
|
|
||||||
{
|
|
||||||
return m_persistentData.random();
|
|
||||||
}
|
|
||||||
|
|
||||||
const expireEntry &random_expire()
|
|
||||||
{
|
|
||||||
return m_persistentData.random_expire();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iter end() { return const_iter(nullptr); }
|
const_iter end() { return const_iter(nullptr); }
|
||||||
|
|
||||||
bool iterate(std::function<bool(const char*, robj*)> fn) { return m_persistentData.iterate(fn); }
|
|
||||||
void getStats(char *buf, size_t bufsize) { m_persistentData.getStats(buf, bufsize); }
|
|
||||||
void getExpireStats(char *buf, size_t bufsize) { m_persistentData.getExpireStats(buf, bufsize); }
|
|
||||||
|
|
||||||
bool insert(char *key, robj *o) { return m_persistentData.insert(key, o); }
|
|
||||||
void dbOverwriteCore(redisDb::iter itr, robj *key, robj *val, bool fUpdateMvcc, bool fRemoveExpire);
|
void dbOverwriteCore(redisDb::iter itr, robj *key, robj *val, bool fUpdateMvcc, bool fRemoveExpire);
|
||||||
|
|
||||||
int incrementallyRehash() { return m_persistentData.incrementallyRehash(); };
|
|
||||||
int removeSubkeyExpire(robj *key, robj *subkey) { return m_persistentData.removeSubkeyExpire(key, subkey); }
|
|
||||||
|
|
||||||
bool FKeyExpires(const char *key);
|
bool FKeyExpires(const char *key);
|
||||||
size_t clear(bool fAsync, void(callback)(void*));
|
size_t clear(bool fAsync, void(callback)(void*));
|
||||||
dict *dictUnsafeKeyOnly() { return m_persistentData.dictUnsafeKeyOnly(); }
|
|
||||||
expireEntry *getExpire(robj_roptr key);
|
expireEntry *getExpire(robj_roptr key);
|
||||||
private:
|
|
||||||
redisDbPersistentData m_persistentData;
|
|
||||||
public:
|
public:
|
||||||
expireset::setiter expireitr;
|
expireset::setiter expireitr;
|
||||||
dict *blocking_keys; /* Keys with clients waiting for data (BLPOP)*/
|
dict *blocking_keys; /* Keys with clients waiting for data (BLPOP)*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user