From cec6f0e934111103c0eedfc11a54536097ac0495 Mon Sep 17 00:00:00 2001 From: John Sully Date: Wed, 16 Oct 2019 13:45:36 -0400 Subject: [PATCH] Cleanup inheritance Former-commit-id: e8debc83e8271cf8d76c5084923cf6e1ea7af3b4 --- src/db.cpp | 36 ++++++++++++++--------------- src/evict.cpp | 6 ++--- src/expire.cpp | 12 +++++----- src/lazyfree.cpp | 2 +- src/server.h | 60 ++++++++++++++++++------------------------------ 5 files changed, 50 insertions(+), 66 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index ddb85a642..db5380ad2 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -230,12 +230,12 @@ void redisDb::dbOverwriteCore(redisDb::iter itr, robj *key, robj *val, bool fUpd if (old->FExpires()) { if (fRemoveExpire) { - removeExpire(this, key); + ::removeExpire(this, key); } else { if (val->getrefcount(std::memory_order_relaxed) == OBJ_SHARED_REFCOUNT) 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 decrRefCount(itr.val()); - m_persistentData.updateValue(itr, val); + updateValue(itr, val); } /* 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 */ 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 @@ -628,7 +628,7 @@ void randomkeyCommand(client *c) { } -bool redisDbPersistentData::iterate(std::function &fn) +bool redisDbPersistentData::iterate(std::function fn) { dictIterator *di = dictGetSafeIterator(m_pdict); dictEntry *de = nullptr; @@ -1154,7 +1154,7 @@ int dbSwapDatabases(int id1, int id2) { /* Swap hash tables. Note that we don't swap blocking_keys, * ready_keys and watched_keys, since we want clients to * 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->last_expire_set = db2->last_expire_set; db1->expireitr = db2->expireitr; @@ -1211,7 +1211,7 @@ void swapdbCommand(client *c) { *----------------------------------------------------------------------------*/ int removeExpire(redisDb *db, robj *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) { /* 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; /* 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; 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) { // 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()) removeExpire(db, key); e.setKeyUnsafe(kde.key()); - db->m_persistentData.setExpire(std::move(e)); + db->setExpire(std::move(e)); kde.val()->SetFExpires(true); @@ -1332,7 +1332,7 @@ expireEntry *redisDb::getExpire(robj_roptr key) { if (!itr.val()->FExpires()) return nullptr; - auto itrExpire = m_persistentData.findExpire(itr.key()); + auto itrExpire = findExpire(itr.key()); return itrExpire.operator->(); } @@ -1811,8 +1811,8 @@ void redisDbPersistentData::initialize() void redisDb::initialize(int id) { - m_persistentData.initialize(); - this->expireitr = m_persistentData.setexpire()->end(); + redisDbPersistentData::initialize(); + this->expireitr = setexpire()->end(); this->blocking_keys = dictCreate(&keylistDictType,NULL); this->ready_keys = dictCreate(&objectKeyPointerValueDictType,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 removed = m_persistentData.size(); + size_t removed = size(); if (fAsync) { - m_persistentData.emptyDbAsync(); + redisDbPersistentData::emptyDbAsync(); } else { - m_persistentData.clear(callback); + redisDbPersistentData::clear(callback); } - expireitr = m_persistentData.setexpire()->end(); + expireitr = setexpire()->end(); return removed; } @@ -1913,7 +1913,7 @@ void redisDbPersistentData::setExpire(expireEntry &&e) 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) diff --git a/src/evict.cpp b/src/evict.cpp index c2da5e926..63b26ce72 100644 --- a/src/evict.cpp +++ b/src/evict.cpp @@ -256,13 +256,13 @@ void evictionPoolPopulate(int dbid, redisDb *db, expireset *setexpire, struct ev { if (setexpire != nullptr) { - visitFunctor visitor { dbid, db->m_persistentData.dictUnsafeKeyOnly(), pool, 0 }; + visitFunctor visitor { dbid, db->dictUnsafeKeyOnly(), pool, 0 }; setexpire->random_visit(visitor); } else { 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++) { robj *o = (robj*)dictGetVal(samples[j]); 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(); if (keys != 0) - evictionPoolPopulate(i, db, db->m_persistentData.setexpireUnsafe(), pool); + evictionPoolPopulate(i, db, db->setexpireUnsafe(), pool); total_keys += keys; } } diff --git a/src/expire.cpp b/src/expire.cpp index 7af20b850..ce906b292 100644 --- a/src/expire.cpp +++ b/src/expire.cpp @@ -295,7 +295,7 @@ void activeExpireCycle(int type) { now = mstime(); /* 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->last_expire_set = now; @@ -305,7 +305,7 @@ void activeExpireCycle(int type) { size_t expired = 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 - 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) { 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 auto itrDB = db->find(keyname); - auto itrExpire = db->m_persistentData.setexpire()->end(); + auto itrExpire = db->setexpire()->end(); if (itrDB != nullptr) - itrExpire = db->m_persistentData.setexpireUnsafe()->find(itrDB.key()); + itrExpire = db->setexpireUnsafe()->find(itrDB.key()); int expired = 0; - if (itrExpire != db->m_persistentData.setexpire()->end()) + if (itrExpire != db->setexpire()->end()) { if (itrExpire->when() < 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. * At the end of the loop if the bitmap is zero, it means we * no longer need to keep track of this key. */ - if (itrExpire != db->m_persistentData.setexpire()->end() && !expired) { + if (itrExpire != db->setexpire()->end() && !expired) { noexpire++; new_dbids |= (uint64_t)1 << dbid; } diff --git a/src/lazyfree.cpp b/src/lazyfree.cpp index 89cd65540..247c5b961 100644 --- a/src/lazyfree.cpp +++ b/src/lazyfree.cpp @@ -94,7 +94,7 @@ bool redisDbPersistentData::asyncDelete(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. */ diff --git a/src/server.h b/src/server.h index 854665c6d..3bb2c7584 100644 --- a/src/server.h +++ b/src/server.h @@ -1138,7 +1138,7 @@ public: int removeSubkeyExpire(robj *key, robj *subkey); void clear(void(callback)(void*)); void emptyDbAsync(); - bool iterate(std::function &fn); + bool iterate(std::function fn); void setExpire(robj *key, robj *subkey, long long when); void setExpire(expireEntry &&e); void initialize(); @@ -1172,7 +1172,8 @@ private: /* Redis database representation. There are multiple databases identified * by integers from 0 (the default database) up to the max configured * 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 friend void tryResizeHashTables(int); friend int dbSyncDelete(redisDb *db, robj *key); @@ -1195,57 +1196,40 @@ typedef struct redisDb { redisDb() : expireitr(nullptr) {} - void initialize(int id); - size_t slots() const { return m_persistentData.slots(); } - size_t size() const { return m_persistentData.size(); } - size_t expireSize() const { return m_persistentData.expireSize(); } - void expand(uint64_t slots) { m_persistentData.expand(slots); } - void tryResize() { m_persistentData.tryResize(); } - const expireset *setexpire() { return m_persistentData.setexpire(); } - - void trackChanges() { m_persistentData.trackChanges(); } - void processChanges() { m_persistentData.processChanges(); } - void trackkey(robj_roptr o) { m_persistentData.trackkey(o); } + // Forward Persistent Data APIs + using redisDbPersistentData::slots; + using redisDbPersistentData::size; + using redisDbPersistentData::expireSize; + using redisDbPersistentData::expand; + using redisDbPersistentData::random; + using redisDbPersistentData::incrementallyRehash; + using redisDbPersistentData::trackkey; + using redisDbPersistentData::setexpire; + 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) { - return 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(); + return redisDbPersistentData::find(szFromObj(key)); } const_iter end() { return const_iter(nullptr); } - bool iterate(std::function 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); - int incrementallyRehash() { return m_persistentData.incrementallyRehash(); }; - int removeSubkeyExpire(robj *key, robj *subkey) { return m_persistentData.removeSubkeyExpire(key, subkey); } bool FKeyExpires(const char *key); size_t clear(bool fAsync, void(callback)(void*)); - dict *dictUnsafeKeyOnly() { return m_persistentData.dictUnsafeKeyOnly(); } expireEntry *getExpire(robj_roptr key); -private: - redisDbPersistentData m_persistentData; + public: expireset::setiter expireitr; dict *blocking_keys; /* Keys with clients waiting for data (BLPOP)*/