Ensure RDB saving only uses data from the persistent data struct, and cleanup inheritance

Former-commit-id: fcdda67d87b3076023f459532c75392b72768a51
This commit is contained in:
John Sully 2019-10-17 17:20:47 -04:00
parent c2b5a8802e
commit 6ee58a3b21
8 changed files with 20 additions and 44 deletions

View File

@ -1318,7 +1318,7 @@ int rewriteAppendOnlyFileRio(rio *aof) {
initStaticStringObject(key,(sds)keystr);
expireEntry *pexpire = getExpire(db,&key);
expireEntry *pexpire = db->getExpire(&key);
/* Save the key and associated value */
if (o->type == OBJ_STRING) {

View File

@ -5194,7 +5194,7 @@ try_again:
/* Create RESTORE payload and generate the protocol to call the command. */
for (j = 0; j < num_keys; j++) {
long long ttl = 0;
expireEntry *pexpire = getExpire(c->db,kv[j]);
expireEntry *pexpire = c->db->getExpire(kv[j]);
long long expireat = -1;
if (pexpire != nullptr)
pexpire->FGetPrimaryExpire(&expireat);

View File

@ -1017,7 +1017,7 @@ void renameGenericCommand(client *c, int nx) {
std::unique_ptr<expireEntry> spexpire;
{ // scope pexpireOld since it will be invalid soon
expireEntry *pexpireOld = getExpire(c->db,c->argv[1]);
expireEntry *pexpireOld = c->db->getExpire(c->argv[1]);
if (pexpireOld != nullptr)
spexpire = std::make_unique<expireEntry>(std::move(*pexpireOld));
}
@ -1095,7 +1095,7 @@ void moveCommand(client *c) {
std::unique_ptr<expireEntry> spexpire;
{ // scope pexpireOld
expireEntry *pexpireOld = getExpire(c->db,c->argv[1]);
expireEntry *pexpireOld = c->db->getExpire(c->argv[1]);
if (pexpireOld != nullptr)
spexpire = std::make_unique<expireEntry>(std::move(*pexpireOld));
}
@ -1321,12 +1321,12 @@ void setExpire(client *c, redisDb *db, robj *key, expireEntry &&e)
/* Return the expire time of the specified key, or null if no expire
* is associated with this key (i.e. the key is non volatile) */
expireEntry *redisDb::getExpire(robj_roptr key) {
expireEntry *redisDbPersistentData::getExpire(robj_roptr key) {
/* No expire? return ASAP */
if (expireSize() == 0)
return nullptr;
auto itr = find(key);
auto itr = find(szFromObj(key));
if (itr == nullptr)
return nullptr;
if (!itr.val()->FExpires())
@ -1336,11 +1336,6 @@ expireEntry *redisDb::getExpire(robj_roptr key) {
return itrExpire.operator->();
}
expireEntry *getExpire(redisDb *db, robj_roptr key)
{
return db->getExpire(key);
}
/* Propagate expires into slaves and the AOF file.
* When a key expires in the master, a DEL operation for this key is sent
* to all the slaves and the AOF file if enabled.
@ -1368,7 +1363,7 @@ void propagateExpire(redisDb *db, robj *key, int lazy) {
/* Check if the key is expired. Note, this does not check subexpires */
int keyIsExpired(redisDb *db, robj *key) {
expireEntry *pexpire = getExpire(db,key);
expireEntry *pexpire = db->getExpire(key);
if (pexpire == nullptr) return 0; /* No expire for this key */

View File

@ -126,7 +126,7 @@ void mixStringObjectDigest(unsigned char *digest, robj_roptr o) {
void xorObjectDigest(redisDb *db, robj_roptr keyobj, unsigned char *digest, robj_roptr o) {
uint32_t aux = htonl(o->type);
mixDigest(digest,&aux,sizeof(aux));
expireEntry *pexpire = getExpire(db,keyobj);
expireEntry *pexpire = db->getExpire(keyobj);
long long expiretime = -1;
char buf[128];

View File

@ -591,7 +591,7 @@ void ttlGenericCommand(client *c, int output_ms) {
/* The key exists. Return -1 if it has no expire, or the actual
* TTL value otherwise. */
expireEntry *pexpire = getExpire(c->db,c->argv[1]);
expireEntry *pexpire = c->db->getExpire(c->argv[1]);
if (c->argc == 2) {
// primary expire

View File

@ -1644,7 +1644,7 @@ int RM_UnlinkKey(RedisModuleKey *key) {
* If no TTL is associated with the key or if the key is empty,
* REDISMODULE_NO_EXPIRE is returned. */
mstime_t RM_GetExpire(RedisModuleKey *key) {
expireEntry *pexpire = getExpire(key->db,key->key);
expireEntry *pexpire = key->db->getExpire(key->key);
mstime_t expire = -1;
if (pexpire != nullptr)
pexpire->FGetPrimaryExpire(&expire);

View File

@ -1112,12 +1112,12 @@ int rdbSaveInfoAuxFields(rio *rdb, int flags, rdbSaveInfo *rsi) {
return 1;
}
int saveKey(rio *rdb, redisDb *db, int flags, size_t *processed, const char *keystr, robj *o)
int saveKey(rio *rdb, redisDbPersistentData *db, int flags, size_t *processed, const char *keystr, robj *o)
{
robj key;
initStaticStringObject(key,(char*)keystr);
expireEntry *pexpire = getExpire(db, &key);
expireEntry *pexpire = db->getExpire(&key);
if (rdbSaveKeyValuePair(rdb,&key,o,pexpire) == -1)
return 0;
@ -1157,7 +1157,7 @@ int rdbSaveRio(rio *rdb, int *error, int flags, rdbSaveInfo *rsi) {
if (rdbSaveInfoAuxFields(rdb,flags,rsi) == -1) goto werr;
for (j = 0; j < cserver.dbnum; j++) {
redisDb *db = g_pserver->db+j;
redisDbPersistentData *db = static_cast<redisDbPersistentData*>(g_pserver->db+j);
if (db->size() == 0) continue;
/* Write the SELECT DB opcode */

View File

@ -1107,6 +1107,11 @@ public:
return dict_iter(de);
}
dict_iter find(robj_roptr key)
{
return find(szFromObj(key));
}
dict_iter random()
{
dictEntry *de = dictGetRandomKey(m_pdict);
@ -1141,6 +1146,7 @@ public:
bool iterate(std::function<bool(const char*, robj*)> fn);
void setExpire(robj *key, robj *subkey, long long when);
void setExpire(expireEntry &&e);
expireEntry *getExpire(robj_roptr key);
void initialize();
void trackChanges() { m_fTrackingChanges++; }
@ -1172,7 +1178,7 @@ 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 : protected redisDbPersistentData
typedef struct redisDb : public redisDbPersistentData
{
// Legacy C API, Do not add more
friend void tryResizeHashTables(int);
@ -1198,29 +1204,6 @@ typedef struct redisDb : protected redisDbPersistentData
{}
void initialize(int id);
// 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 redisDbPersistentData::find(szFromObj(key));
}
const_iter end() { return const_iter(nullptr); }
void dbOverwriteCore(redisDb::iter itr, robj *key, robj *val, bool fUpdateMvcc, bool fRemoveExpire);
@ -1228,7 +1211,6 @@ typedef struct redisDb : protected redisDbPersistentData
bool FKeyExpires(const char *key);
size_t clear(bool fAsync, void(callback)(void*));
expireEntry *getExpire(robj_roptr key);
public:
expireset::setiter expireitr;
@ -2626,7 +2608,6 @@ int removeExpire(redisDb *db, robj *key);
int removeSubkeyExpire(redisDb *db, robj *key, robj *subkey);
void propagateExpire(redisDb *db, robj *key, int lazy);
int expireIfNeeded(redisDb *db, robj *key);
expireEntry *getExpire(redisDb *db, robj_roptr key);
void setExpire(client *c, redisDb *db, robj *key, robj *subkey, long long when);
void setExpire(client *c, redisDb *db, robj *key, expireEntry &&entry);
robj_roptr lookupKeyRead(redisDb *db, robj *key);