summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cluster.c6
-rw-r--r--src/config.c8
-rw-r--r--src/db.c9
-rw-r--r--src/debug.c2
-rw-r--r--src/defrag.c61
-rw-r--r--src/dict.c108
-rw-r--r--src/dict.h76
-rw-r--r--src/eval.c4
-rw-r--r--src/expire.c6
-rw-r--r--src/functions.c7
-rw-r--r--src/object.c14
-rw-r--r--src/pubsub.c6
-rw-r--r--src/redis-cli.c2
-rw-r--r--src/t_zset.c5
14 files changed, 195 insertions, 119 deletions
diff --git a/src/cluster.c b/src/cluster.c
index 71c45d742..ecebc511b 100644
--- a/src/cluster.c
+++ b/src/cluster.c
@@ -7288,7 +7288,7 @@ int clusterRedirectBlockedClientIfNeeded(client *c) {
* understand if we have keys for a given hash slot. */
void slotToKeyAddEntry(dictEntry *entry, redisDb *db) {
- sds key = entry->key;
+ sds key = dictGetKey(entry);
unsigned int hashslot = keyHashSlot(key, sdslen(key));
slotToKeys *slot_to_keys = &(*db->slots_to_keys).by_slot[hashslot];
slot_to_keys->count++;
@@ -7305,7 +7305,7 @@ void slotToKeyAddEntry(dictEntry *entry, redisDb *db) {
}
void slotToKeyDelEntry(dictEntry *entry, redisDb *db) {
- sds key = entry->key;
+ sds key = dictGetKey(entry);
unsigned int hashslot = keyHashSlot(key, sdslen(key));
slotToKeys *slot_to_keys = &(*db->slots_to_keys).by_slot[hashslot];
slot_to_keys->count--;
@@ -7337,7 +7337,7 @@ void slotToKeyReplaceEntry(dictEntry *entry, redisDb *db) {
dictEntryNextInSlot(prev) = entry;
} else {
/* The replaced entry was the first in the list. */
- sds key = entry->key;
+ sds key = dictGetKey(entry);
unsigned int hashslot = keyHashSlot(key, sdslen(key));
slotToKeys *slot_to_keys = &(*db->slots_to_keys).by_slot[hashslot];
slot_to_keys->head = entry;
diff --git a/src/config.c b/src/config.c
index 90baed9ee..9de4ecd41 100644
--- a/src/config.c
+++ b/src/config.c
@@ -989,8 +989,8 @@ void configGetCommand(client *c) {
/* Note that hidden configs require an exact match (not a pattern) */
if (config->flags & HIDDEN_CONFIG) continue;
if (dictFind(matches, config->name)) continue;
- if (stringmatch(name, de->key, 1)) {
- dictAdd(matches, de->key, config);
+ if (stringmatch(name, dictGetKey(de), 1)) {
+ dictAdd(matches, dictGetKey(de), config);
}
}
dictReleaseIterator(di);
@@ -1000,7 +1000,7 @@ void configGetCommand(client *c) {
addReplyMapLen(c, dictSize(matches));
while ((de = dictNext(di)) != NULL) {
standardConfig *config = (standardConfig *) dictGetVal(de);
- addReplyBulkCString(c, de->key);
+ addReplyBulkCString(c, dictGetKey(de));
addReplyBulkSds(c, config->interface.get(config));
}
dictReleaseIterator(di);
@@ -1754,7 +1754,7 @@ int rewriteConfig(char *path, int force_write) {
standardConfig *config = dictGetVal(de);
/* Only rewrite the primary names */
if (config->flags & ALIAS_CONFIG) continue;
- if (config->interface.rewrite) config->interface.rewrite(config, de->key, state);
+ if (config->interface.rewrite) config->interface.rewrite(config, dictGetKey(de), state);
}
dictReleaseIterator(di);
diff --git a/src/db.c b/src/db.c
index aad822630..abe717ace 100644
--- a/src/db.c
+++ b/src/db.c
@@ -228,7 +228,6 @@ static void dbSetValue(redisDb *db, robj *key, robj *val, int overwrite) {
dictEntry *de = dictFind(db->dict,key->ptr);
serverAssertWithInfo(NULL,key,de != NULL);
- dictEntry auxentry = *de;
robj *old = dictGetVal(de);
if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
val->lru = old->lru;
@@ -246,17 +245,15 @@ static void dbSetValue(redisDb *db, robj *key, robj *val, int overwrite) {
decrRefCount(old);
/* Because of RM_StringDMA, old may be changed, so we need get old again */
old = dictGetVal(de);
- /* Entry in auxentry may be changed, so we need update auxentry */
- auxentry = *de;
}
dictSetVal(db->dict, de, val);
if (server.lazyfree_lazy_server_del) {
freeObjAsync(key,old,db->id);
- dictSetVal(db->dict, &auxentry, NULL);
+ } else {
+ /* This is just decrRefCount(old); */
+ db->dict->type->valDestructor(db->dict, old);
}
-
- dictFreeVal(db->dict, &auxentry);
}
/* Replace an existing key with a new value, we just replace value and don't
diff --git a/src/debug.c b/src/debug.c
index c9495e5d8..fe46b5c62 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -868,7 +868,7 @@ NULL
sds sizes = sdsempty();
sizes = sdscatprintf(sizes,"bits:%d ",(sizeof(void*) == 8)?64:32);
sizes = sdscatprintf(sizes,"robj:%d ",(int)sizeof(robj));
- sizes = sdscatprintf(sizes,"dictentry:%d ",(int)sizeof(dictEntry));
+ sizes = sdscatprintf(sizes,"dictentry:%d ",(int)dictEntryMemUsage());
sizes = sdscatprintf(sizes,"sdshdr5:%d ",(int)sizeof(struct sdshdr5));
sizes = sdscatprintf(sizes,"sdshdr8:%d ",(int)sizeof(struct sdshdr8));
sizes = sdscatprintf(sizes,"sdshdr16:%d ",(int)sizeof(struct sdshdr16));
diff --git a/src/defrag.c b/src/defrag.c
index dbdf2ab62..e258d38c0 100644
--- a/src/defrag.c
+++ b/src/defrag.c
@@ -163,7 +163,7 @@ long dictIterDefragEntry(dictIterator *iter) {
if (newde) {
defragged++;
iter->nextEntry = newde;
- iter->entry->next = newde;
+ dictSetNext(iter->entry, newde);
}
}
/* handle the case of the first entry in the hash bucket. */
@@ -264,7 +264,7 @@ long activeDefragZsetEntry(zset *zs, dictEntry *de) {
long defragged = 0;
sds sdsele = dictGetKey(de);
if ((newsds = activeDefragSds(sdsele)))
- defragged++, de->key = newsds;
+ defragged++, dictSetKey(zs->dict, de, newsds);
newscore = zslDefrag(zs->zsl, *(double*)dictGetVal(de), sdsele, newsds);
if (newscore) {
dictSetVal(zs->dict, de, newscore);
@@ -288,24 +288,24 @@ long activeDefragSdsDict(dict* d, int val_type) {
while((de = dictNext(di)) != NULL) {
sds sdsele = dictGetKey(de), newsds;
if ((newsds = activeDefragSds(sdsele)))
- de->key = newsds, defragged++;
+ dictSetKey(d, de, newsds), defragged++;
/* defrag the value */
if (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) {
sdsele = dictGetVal(de);
if ((newsds = activeDefragSds(sdsele)))
- de->v.val = newsds, defragged++;
+ dictSetVal(d, de, newsds), defragged++;
} else if (val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) {
robj *newele, *ele = dictGetVal(de);
if ((newele = activeDefragStringOb(ele, &defragged)))
- de->v.val = newele;
+ dictSetVal(d, de, newele);
} else if (val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) {
void *newptr, *ptr = dictGetVal(de);
if ((newptr = activeDefragAlloc(ptr)))
- de->v.val = newptr, defragged++;
+ dictSetVal(d, de, newptr), defragged++;
} else if (val_type == DEFRAG_SDS_DICT_VAL_LUA_SCRIPT) {
void *newptr, *ptr = dictGetVal(de);
if ((newptr = activeDefragLuaScript(ptr, &defragged)))
- de->v.val = newptr;
+ dictSetVal(d, de, newptr);
}
defragged += dictIterDefragEntry(di);
}
@@ -374,7 +374,7 @@ long activeDefragSdsListAndDict(list *l, dict *d, int dict_val_type) {
uint64_t hash = dictGetHash(d, newsds);
dictEntry **deref = dictFindEntryRefByPtrAndHash(d, sdsele, hash);
if (deref)
- (*deref)->key = newsds;
+ dictSetKey(d, *deref, newsds);
ln->value = newsds;
defragged++;
}
@@ -386,15 +386,15 @@ long activeDefragSdsListAndDict(list *l, dict *d, int dict_val_type) {
if (dict_val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) {
sds newsds, sdsele = dictGetVal(de);
if ((newsds = activeDefragSds(sdsele)))
- de->v.val = newsds, defragged++;
+ dictSetVal(d, de, newsds), defragged++;
} else if (dict_val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) {
robj *newele, *ele = dictGetVal(de);
if ((newele = activeDefragStringOb(ele, &defragged)))
- de->v.val = newele;
+ dictSetVal(d, de, newele);
} else if (dict_val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) {
void *newptr, *ptr = dictGetVal(de);
if ((newptr = activeDefragAlloc(ptr)))
- de->v.val = newptr, defragged++;
+ dictSetVal(d, de, newptr), defragged++;
}
defragged += dictIterDefragEntry(di);
}
@@ -420,7 +420,7 @@ dictEntry* replaceSatelliteDictKeyPtrAndOrDefragDictEntry(dict *d, sds oldkey, s
(*defragged)++;
}
if (newkey)
- de->key = newkey;
+ dictSetKey(d, de, newkey);
return de;
}
return NULL;
@@ -531,43 +531,48 @@ long scanLaterZset(robj *ob, unsigned long *cursor) {
return data.defragged;
}
+typedef struct {
+ dict *dict;
+ long defragged;
+} scanLaterDictData;
+
void scanLaterSetCallback(void *privdata, const dictEntry *_de) {
dictEntry *de = (dictEntry*)_de;
- long *defragged = privdata;
+ scanLaterDictData *data = privdata;
sds sdsele = dictGetKey(de), newsds;
if ((newsds = activeDefragSds(sdsele)))
- (*defragged)++, de->key = newsds;
+ data->defragged++, dictSetKey(data->dict, de, newsds);
server.stat_active_defrag_scanned++;
}
long scanLaterSet(robj *ob, unsigned long *cursor) {
- long defragged = 0;
if (ob->type != OBJ_SET || ob->encoding != OBJ_ENCODING_HT)
return 0;
dict *d = ob->ptr;
- *cursor = dictScan(d, *cursor, scanLaterSetCallback, defragDictBucketCallback, &defragged);
- return defragged;
+ scanLaterDictData data = {d, 0};
+ *cursor = dictScan(d, *cursor, scanLaterSetCallback, defragDictBucketCallback, &data);
+ return data.defragged;
}
void scanLaterHashCallback(void *privdata, const dictEntry *_de) {
dictEntry *de = (dictEntry*)_de;
- long *defragged = privdata;
+ scanLaterDictData *data = privdata;
sds sdsele = dictGetKey(de), newsds;
if ((newsds = activeDefragSds(sdsele)))
- (*defragged)++, de->key = newsds;
+ data->defragged++, dictSetKey(data->dict, de, newsds);
sdsele = dictGetVal(de);
if ((newsds = activeDefragSds(sdsele)))
- (*defragged)++, de->v.val = newsds;
+ data->defragged++, dictSetVal(data->dict, de, newsds);
server.stat_active_defrag_scanned++;
}
long scanLaterHash(robj *ob, unsigned long *cursor) {
- long defragged = 0;
if (ob->type != OBJ_HASH || ob->encoding != OBJ_ENCODING_HT)
return 0;
dict *d = ob->ptr;
- *cursor = dictScan(d, *cursor, scanLaterHashCallback, defragDictBucketCallback, &defragged);
- return defragged;
+ scanLaterDictData data = {d, 0};
+ *cursor = dictScan(d, *cursor, scanLaterHashCallback, defragDictBucketCallback, &data);
+ return data.defragged;
}
long defragQuicklist(redisDb *db, dictEntry *kde) {
@@ -847,19 +852,19 @@ long defragKey(redisDb *db, dictEntry *de) {
/* Try to defrag the key name. */
newsds = activeDefragSds(keysds);
if (newsds)
- defragged++, de->key = newsds;
+ defragged++, dictSetKey(db->dict, de, newsds);
if (dictSize(db->expires)) {
/* Dirty code:
* I can't search in db->expires for that key after i already released
* the pointer it holds it won't be able to do the string compare */
- uint64_t hash = dictGetHash(db->dict, de->key);
+ uint64_t hash = dictGetHash(db->dict, dictGetKey(de));
replaceSatelliteDictKeyPtrAndOrDefragDictEntry(db->expires, keysds, newsds, hash, &defragged);
}
/* Try to defrag robj and / or string value. */
ob = dictGetVal(de);
if ((newob = activeDefragStringOb(ob, &defragged))) {
- de->v.val = newob;
+ dictSetVal(db->dict, de, newob);
ob = newob;
}
@@ -928,7 +933,7 @@ void defragScanCallback(void *privdata, const dictEntry *de) {
/* Defrag scan callback for each hash table bucket,
* used in order to defrag the dictEntry allocations. */
void defragDictBucketCallback(dict *d, dictEntry **bucketref) {
- while(*bucketref) {
+ while (bucketref && *bucketref) {
dictEntry *de = *bucketref, *newde;
if ((newde = activeDefragAlloc(de))) {
*bucketref = newde;
@@ -937,7 +942,7 @@ void defragDictBucketCallback(dict *d, dictEntry **bucketref) {
slotToKeyReplaceEntry(newde, server.db);
}
}
- bucketref = &(*bucketref)->next;
+ bucketref = dictGetNextRef(*bucketref);
}
}
diff --git a/src/dict.c b/src/dict.c
index 90fd4f52e..418c42bbb 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -58,6 +58,22 @@
static dictResizeEnable dict_can_resize = DICT_RESIZE_ENABLE;
static unsigned int dict_force_resize_ratio = 5;
+/* -------------------------- types ----------------------------------------- */
+
+struct dictEntry {
+ void *key;
+ union {
+ void *val;
+ uint64_t u64;
+ int64_t s64;
+ double d;
+ } v;
+ struct dictEntry *next; /* Next entry in the same hash bucket. */
+ void *metadata[]; /* An arbitrary number of bytes (starting at a
+ * pointer-aligned address) of size as returned
+ * by dictType's dictEntryMetadataBytes(). */
+};
+
/* -------------------------- private prototypes ---------------------------- */
static int _dictExpandIfNeeded(dict *d);
@@ -596,6 +612,98 @@ void dictTwoPhaseUnlinkFree(dict *d, dictEntry *he, dictEntry **plink, int table
dictResumeRehashing(d);
}
+void dictSetKey(dict *d, dictEntry* de, void *key) {
+ if (d->type->keyDup)
+ de->key = d->type->keyDup(d, key);
+ else
+ de->key = key;
+}
+
+void dictSetVal(dict *d, dictEntry *de, void *val) {
+ de->v.val = d->type->valDup ? d->type->valDup(d, val) : val;
+}
+
+void dictSetSignedIntegerVal(dictEntry *de, int64_t val) {
+ de->v.s64 = val;
+}
+
+void dictSetUnsignedIntegerVal(dictEntry *de, uint64_t val) {
+ de->v.u64 = val;
+}
+
+void dictSetDoubleVal(dictEntry *de, double val) {
+ de->v.d = val;
+}
+
+int64_t dictIncrSignedIntegerVal(dictEntry *de, int64_t val) {
+ return de->v.s64 += val;
+}
+
+uint64_t dictIncrUnsignedIntegerVal(dictEntry *de, uint64_t val) {
+ return de->v.u64 += val;
+}
+
+double dictIncrDoubleVal(dictEntry *de, double val) {
+ return de->v.d += val;
+}
+
+/* Only used when the next in hash bucket has been reallocated. */
+void dictSetNext(dictEntry *de, dictEntry *next) {
+ de->next = next;
+}
+
+/* A pointer to the metadata section within the dict entry. */
+void *dictMetadata(dictEntry *de) {
+ return &de->metadata;
+}
+
+void *dictGetKey(const dictEntry *de) {
+ return de->key;
+}
+
+void *dictGetVal(const dictEntry *de) {
+ return de->v.val;
+}
+
+int64_t dictGetSignedIntegerVal(const dictEntry *de) {
+ return de->v.s64;
+}
+
+uint64_t dictGetUnsignedIntegerVal(const dictEntry *de) {
+ return de->v.u64;
+}
+
+double dictGetDoubleVal(const dictEntry *de) {
+ return de->v.d;
+}
+
+/* Returns a mutable reference to the value as a double within the entry. */
+double *dictGetDoubleValPtr(dictEntry *de) {
+ return &de->v.d;
+}
+
+/* The next entry in same hash bucket. */
+dictEntry *dictGetNext(const dictEntry *de) {
+ return de->next;
+}
+
+/* A pointer to the 'next' field within the entry, or NULL if there is no next
+ * field. */
+dictEntry **dictGetNextRef(dictEntry *de) {
+ return &de->next;
+}
+
+/* Returns the memory usage in bytes of the dict, excluding the size of the keys
+ * and values. */
+size_t dictMemUsage(const dict *d) {
+ return dictSize(d) * sizeof(dictEntry) +
+ dictSlots(d) * sizeof(dictEntry*);
+}
+
+size_t dictEntryMemUsage(void) {
+ return sizeof(dictEntry);
+}
+
/* A fingerprint is a 64 bit number that represents the state of the dictionary
* at a given time, it's just a few dict properties xored together.
* When an unsafe iterator is initialized, we get the dict fingerprint, and check
diff --git a/src/dict.h b/src/dict.h
index 00b721d3d..a7ee282da 100644
--- a/src/dict.h
+++ b/src/dict.h
@@ -44,19 +44,7 @@
#define DICT_OK 0
#define DICT_ERR 1
-typedef struct dictEntry {
- void *key;
- union {
- void *val;
- uint64_t u64;
- int64_t s64;
- double d;
- } v;
- struct dictEntry *next; /* Next entry in the same hash bucket. */
- void *metadata[]; /* An arbitrary number of bytes (starting at a
- * pointer-aligned address) of size as returned
- * by dictType's dictEntryMetadataBytes(). */
-} dictEntry;
+typedef struct dictEntry dictEntry; /* opaque */
typedef struct dict dict;
@@ -112,60 +100,22 @@ typedef void (dictScanBucketFunction)(dict *d, dictEntry **bucketref);
/* ------------------------------- Macros ------------------------------------*/
#define dictFreeVal(d, entry) do { \
if ((d)->type->valDestructor) \
- (d)->type->valDestructor((d), (entry)->v.val); \
+ (d)->type->valDestructor((d), dictGetVal(entry)); \
} while(0)
-#define dictSetVal(d, entry, _val_) do { \
- if ((d)->type->valDup) \
- (entry)->v.val = (d)->type->valDup((d), _val_); \
- else \
- (entry)->v.val = (_val_); \
-} while(0)
-
-#define dictSetSignedIntegerVal(entry, _val_) \
- do { (entry)->v.s64 = _val_; } while(0)
-
-#define dictSetUnsignedIntegerVal(entry, _val_) \
- do { (entry)->v.u64 = _val_; } while(0)
-
-#define dictSetDoubleVal(entry, _val_) \
- do { (entry)->v.d = _val_; } while(0)
-
-#define dictIncrSignedIntegerVal(entry, _val_) \
- ((entry)->v.s64 += _val_)
-
-#define dictIncrUnsignedIntegerVal(entry, _val_) \
- ((entry)->v.u64 += _val_)
-
-#define dictIncrDoubleVal(entry, _val_) \
- ((entry)->v.d += _val_)
-
#define dictFreeKey(d, entry) \
if ((d)->type->keyDestructor) \
- (d)->type->keyDestructor((d), (entry)->key)
-
-#define dictSetKey(d, entry, _key_) do { \
- if ((d)->type->keyDup) \
- (entry)->key = (d)->type->keyDup((d), _key_); \
- else \
- (entry)->key = (_key_); \
-} while(0)
+ (d)->type->keyDestructor((d), dictGetKey(entry))
#define dictCompareKeys(d, key1, key2) \
(((d)->type->keyCompare) ? \
(d)->type->keyCompare((d), key1, key2) : \
(key1) == (key2))
-#define dictMetadata(entry) (&(entry)->metadata)
#define dictMetadataSize(d) ((d)->type->dictEntryMetadataBytes \
? (d)->type->dictEntryMetadataBytes(d) : 0)
#define dictHashKey(d, key) ((d)->type->hashFunction(key))
-#define dictGetKey(he) ((he)->key)
-#define dictGetVal(he) ((he)->v.val)
-#define dictGetSignedIntegerVal(he) ((he)->v.s64)
-#define dictGetUnsignedIntegerVal(he) ((he)->v.u64)
-#define dictGetDoubleVal(he) ((he)->v.d)
#define dictSlots(d) (DICTHT_SIZE((d)->ht_size_exp[0])+DICTHT_SIZE((d)->ht_size_exp[1]))
#define dictSize(d) ((d)->ht_used[0]+(d)->ht_used[1])
#define dictIsRehashing(d) ((d)->rehashidx != -1)
@@ -202,6 +152,26 @@ void dictRelease(dict *d);
dictEntry * dictFind(dict *d, const void *key);
void *dictFetchValue(dict *d, const void *key);
int dictResize(dict *d);
+void dictSetKey(dict *d, dictEntry* de, void *key);
+void dictSetVal(dict *d, dictEntry *de, void *val);
+void dictSetSignedIntegerVal(dictEntry *de, int64_t val);
+void dictSetUnsignedIntegerVal(dictEntry *de, uint64_t val);
+void dictSetDoubleVal(dictEntry *de, double val);
+int64_t dictIncrSignedIntegerVal(dictEntry *de, int64_t val);
+uint64_t dictIncrUnsignedIntegerVal(dictEntry *de, uint64_t val);
+double dictIncrDoubleVal(dictEntry *de, double val);
+void dictSetNext(dictEntry *de, dictEntry *next);
+void *dictMetadata(dictEntry *de);
+void *dictGetKey(const dictEntry *de);
+void *dictGetVal(const dictEntry *de);
+int64_t dictGetSignedIntegerVal(const dictEntry *de);
+uint64_t dictGetUnsignedIntegerVal(const dictEntry *de);
+double dictGetDoubleVal(const dictEntry *de);
+double *dictGetDoubleValPtr(dictEntry *de);
+dictEntry *dictGetNext(const dictEntry *de);
+dictEntry **dictGetNextRef(dictEntry *de);
+size_t dictMemUsage(const dict *d);
+size_t dictEntryMemUsage(void);
dictIterator *dictGetIterator(dict *d);
dictIterator *dictGetSafeIterator(dict *d);
void dictInitIterator(dictIterator *iter, dict *d);
diff --git a/src/eval.c b/src/eval.c
index 6eb6ed1d4..1fa08c9dd 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -677,8 +677,8 @@ dict* evalScriptsDict() {
unsigned long evalScriptsMemory() {
return lctx.lua_scripts_mem +
- dictSize(lctx.lua_scripts) * (sizeof(dictEntry) + sizeof(luaScript)) +
- dictSlots(lctx.lua_scripts) * sizeof(dictEntry*);
+ dictMemUsage(lctx.lua_scripts) +
+ dictSize(lctx.lua_scripts) * sizeof(luaScript);
}
/* ---------------------------------------------------------------------------
diff --git a/src/expire.c b/src/expire.c
index 7b6b3bc9c..d819dad37 100644
--- a/src/expire.c
+++ b/src/expire.c
@@ -258,7 +258,7 @@ void activeExpireCycle(int type) {
/* Get the next entry now since this entry may get
* deleted. */
dictEntry *e = de;
- de = de->next;
+ de = dictGetNext(de);
ttl = dictGetSignedIntegerVal(e)-now;
if (activeExpireCycleTryExpire(db,e,now)) {
@@ -444,8 +444,8 @@ void rememberSlaveKeyWithExpire(redisDb *db, robj *key) {
* representing the key: we don't want to need to take those keys
* in sync with the main DB. The keys will be removed by expireSlaveKeys()
* as it scans to find keys to remove. */
- if (de->key == key->ptr) {
- de->key = sdsdup(key->ptr);
+ if (dictGetKey(de) == key->ptr) {
+ dictSetKey(slaveKeysWithExpire, de, sdsdup(key->ptr));
dictSetUnsignedIntegerVal(de,0);
}
diff --git a/src/functions.c b/src/functions.c
index 3f7b3a7ef..c60d40d3c 100644
--- a/src/functions.c
+++ b/src/functions.c
@@ -1091,10 +1091,9 @@ unsigned long functionsMemory() {
/* Return memory overhead of all the engines combine */
unsigned long functionsMemoryOverhead() {
- size_t memory_overhead = dictSize(engines) * sizeof(dictEntry) +
- dictSlots(engines) * sizeof(dictEntry*);
- memory_overhead += dictSize(curr_functions_lib_ctx->functions) * sizeof(dictEntry) +
- dictSlots(curr_functions_lib_ctx->functions) * sizeof(dictEntry*) + sizeof(functionsLibCtx);
+ size_t memory_overhead = dictMemUsage(engines);
+ memory_overhead += dictMemUsage(curr_functions_lib_ctx->functions);
+ memory_overhead += sizeof(functionsLibCtx);
memory_overhead += curr_functions_lib_ctx->cache_memory;
memory_overhead += engine_cache_memory;
diff --git a/src/object.c b/src/object.c
index 54ed57958..ca9a24088 100644
--- a/src/object.c
+++ b/src/object.c
@@ -1029,7 +1029,7 @@ size_t objectComputeSize(robj *key, robj *o, size_t sample_size, int dbid) {
asize = sizeof(*o)+sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d));
while((de = dictNext(di)) != NULL && samples < sample_size) {
ele = dictGetKey(de);
- elesize += sizeof(struct dictEntry) + sdsZmallocSize(ele);
+ elesize += dictEntryMemUsage() + sdsZmallocSize(ele);
samples++;
}
dictReleaseIterator(di);
@@ -1053,7 +1053,7 @@ size_t objectComputeSize(robj *key, robj *o, size_t sample_size, int dbid) {
zmalloc_size(zsl->header);
while(znode != NULL && samples < sample_size) {
elesize += sdsZmallocSize(znode->ele);
- elesize += sizeof(struct dictEntry)+zmalloc_size(znode);
+ elesize += dictEntryMemUsage()+zmalloc_size(znode);
samples++;
znode = znode->level[0].forward;
}
@@ -1072,7 +1072,7 @@ size_t objectComputeSize(robj *key, robj *o, size_t sample_size, int dbid) {
ele = dictGetKey(de);
ele2 = dictGetVal(de);
elesize += sdsZmallocSize(ele) + sdsZmallocSize(ele2);
- elesize += sizeof(struct dictEntry);
+ elesize += dictEntryMemUsage();
samples++;
}
dictReleaseIterator(di);
@@ -1242,14 +1242,12 @@ struct redisMemOverhead *getMemoryOverheadData(void) {
mh->db = zrealloc(mh->db,sizeof(mh->db[0])*(mh->num_dbs+1));
mh->db[mh->num_dbs].dbid = j;
- mem = dictSize(db->dict) * sizeof(dictEntry) +
- dictSlots(db->dict) * sizeof(dictEntry*) +
+ mem = dictMemUsage(db->dict) +
dictSize(db->dict) * sizeof(robj);
mh->db[mh->num_dbs].overhead_ht_main = mem;
mem_total+=mem;
- mem = dictSize(db->expires) * sizeof(dictEntry) +
- dictSlots(db->expires) * sizeof(dictEntry*);
+ mem = dictMemUsage(db->expires);
mh->db[mh->num_dbs].overhead_ht_expires = mem;
mem_total+=mem;
@@ -1547,7 +1545,7 @@ NULL
}
size_t usage = objectComputeSize(c->argv[2],dictGetVal(de),samples,c->db->id);
usage += sdsZmallocSize(dictGetKey(de));
- usage += sizeof(dictEntry);
+ usage += dictEntryMemUsage();
usage += dictMetadataSize(c->db->dict);
addReplyLongLong(c,usage);
} else if (!strcasecmp(c->argv[1]->ptr,"stats") && c->argc == 2) {
diff --git a/src/pubsub.c b/src/pubsub.c
index 2e2522c57..a257a8af3 100644
--- a/src/pubsub.c
+++ b/src/pubsub.c
@@ -727,10 +727,8 @@ size_t pubsubMemOverhead(client *c) {
/* PubSub patterns */
size_t mem = listLength(c->pubsub_patterns) * sizeof(listNode);
/* Global PubSub channels */
- mem += dictSize(c->pubsub_channels) * sizeof(dictEntry) +
- dictSlots(c->pubsub_channels) * sizeof(dictEntry*);
+ mem += dictMemUsage(c->pubsub_channels);
/* Sharded PubSub channels */
- mem += dictSize(c->pubsubshard_channels) * sizeof(dictEntry) +
- dictSlots(c->pubsubshard_channels) * sizeof(dictEntry*);
+ mem += dictMemUsage(c->pubsubshard_channels);
return mem;
}
diff --git a/src/redis-cli.c b/src/redis-cli.c
index c8576702c..b9d84c6d9 100644
--- a/src/redis-cli.c
+++ b/src/redis-cli.c
@@ -762,7 +762,7 @@ void cliInitGroupHelpEntries(dict *groups) {
for (entry = dictNext(iter); entry != NULL; entry = dictNext(iter)) {
tmp.argc = 1;
tmp.argv = zmalloc(sizeof(sds));
- tmp.argv[0] = sdscatprintf(sdsempty(),"@%s",(char *)entry->key);
+ tmp.argv[0] = sdscatprintf(sdsempty(),"@%s",(char *)dictGetKey(entry));
tmp.full = tmp.argv[0];
tmp.type = CLI_HELP_GROUP;
tmp.org.name = NULL;
diff --git a/src/t_zset.c b/src/t_zset.c
index 048759d1f..5dadd58fd 100644
--- a/src/t_zset.c
+++ b/src/t_zset.c
@@ -1428,7 +1428,7 @@ int zsetAdd(robj *zobj, double score, sds ele, int in_flags, int *out_flags, dou
/* Note that we did not removed the original element from
* the hash table representing the sorted set, so we just
* update the score. */
- dictGetVal(de) = &znode->score; /* Update score ptr. */
+ dictSetVal(zs->dict, de, &znode->score); /* Update score ptr. */
*out_flags |= ZADD_OUT_UPDATED;
}
return 1;
@@ -2741,7 +2741,8 @@ void zunionInterDiffGenericCommand(client *c, robj *dstkey, int numkeysIndex, in
* Here we access directly the dictEntry double
* value inside the union as it is a big speedup
* compared to using the getDouble/setDouble API. */
- zunionInterAggregate(&existing->v.d,score,aggregate);
+ double *existing_score_ptr = dictGetDoubleValPtr(existing);
+ zunionInterAggregate(existing_score_ptr, score, aggregate);
}
}
zuiClearIterator(&src[i]);