summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorViktor Söderqvist <viktor.soderqvist@est.tech>2022-11-21 15:34:38 +0100
committerViktor Söderqvist <viktor.soderqvist@est.tech>2023-01-11 10:25:20 +0100
commit2bbc89196a4aab93cfa2f94c400aebd2841a2670 (patch)
tree840d8ea21302eb35ef8c9e760affb4dbca4a0daa
parentb60d33c91eef09aea34cecad789c552405737c55 (diff)
downloadredis-2bbc89196a4aab93cfa2f94c400aebd2841a2670.tar.gz
Move stat_active_defrag_hits increment to activeDefragAlloc
instead of passing it around to every defrag function
-rw-r--r--src/defrag.c268
-rw-r--r--src/module.c30
-rw-r--r--src/server.h8
3 files changed, 122 insertions, 184 deletions
diff --git a/src/defrag.c b/src/defrag.c
index 0d6c6b45a..b813ab74f 100644
--- a/src/defrag.c
+++ b/src/defrag.c
@@ -64,6 +64,7 @@ void* activeDefragAlloc(void *ptr) {
newptr = zmalloc_no_tcache(size);
memcpy(newptr, ptr, size);
zfree_no_tcache(ptr);
+ server.stat_active_defrag_hits++;
return newptr;
}
@@ -88,7 +89,7 @@ sds activeDefragSds(sds sdsptr) {
* returns NULL in case the allocation wasn't moved.
* when it returns a non-null value, the old pointer was already released
* and should NOT be accessed. */
-robj *activeDefragStringOb(robj* ob, long *defragged) {
+robj *activeDefragStringOb(robj* ob) {
robj *ret = NULL;
if (ob->refcount!=1)
return NULL;
@@ -97,7 +98,6 @@ robj *activeDefragStringOb(robj* ob, long *defragged) {
if (ob->type!=OBJ_STRING || ob->encoding!=OBJ_ENCODING_EMBSTR) {
if ((ret = activeDefragAlloc(ob))) {
ob = ret;
- (*defragged)++;
}
}
@@ -107,7 +107,6 @@ robj *activeDefragStringOb(robj* ob, long *defragged) {
sds newsds = activeDefragSds((sds)ob->ptr);
if (newsds) {
ob->ptr = newsds;
- (*defragged)++;
}
} else if (ob->encoding==OBJ_ENCODING_EMBSTR) {
/* The sds is embedded in the object allocation, calculate the
@@ -115,7 +114,6 @@ robj *activeDefragStringOb(robj* ob, long *defragged) {
long ofs = (intptr_t)ob->ptr - (intptr_t)ob;
if ((ret = activeDefragAlloc(ob))) {
ret->ptr = (void*)((intptr_t)ret + ofs);
- (*defragged)++;
}
} else if (ob->encoding!=OBJ_ENCODING_INT) {
serverPanic("Unknown string encoding");
@@ -129,17 +127,16 @@ robj *activeDefragStringOb(robj* ob, long *defragged) {
* returns NULL in case the allocation wasn't moved.
* when it returns a non-null value, the old pointer was already released
* and should NOT be accessed. */
-luaScript *activeDefragLuaScript(luaScript *script, long *defragged) {
+luaScript *activeDefragLuaScript(luaScript *script) {
luaScript *ret = NULL;
/* try to defrag script struct */
if ((ret = activeDefragAlloc(script))) {
script = ret;
- (*defragged)++;
}
/* try to defrag actual script object */
- robj *ob = activeDefragStringOb(script->body, defragged);
+ robj *ob = activeDefragStringOb(script->body);
if (ob) script->body = ob;
return ret;
@@ -148,20 +145,18 @@ luaScript *activeDefragLuaScript(luaScript *script, long *defragged) {
/* Defrag helper for dict main allocations (dict struct, and hash tables).
* receives a pointer to the dict* and implicitly updates it when the dict
* struct itself was moved. Returns a stat of how many pointers were moved. */
-long dictDefragTables(dict* d) {
+void dictDefragTables(dict* d) {
dictEntry **newtable;
- long defragged = 0;
/* handle the first hash table */
newtable = activeDefragAlloc(d->ht_table[0]);
if (newtable)
- defragged++, d->ht_table[0] = newtable;
+ d->ht_table[0] = newtable;
/* handle the second hash table */
if (d->ht_table[1]) {
newtable = activeDefragAlloc(d->ht_table[1]);
if (newtable)
- defragged++, d->ht_table[1] = newtable;
+ d->ht_table[1] = newtable;
}
- return defragged;
}
/* Internal function used by zslDefrag */
@@ -225,19 +220,16 @@ double *zslDefrag(zskiplist *zsl, double score, sds oldele, sds newele) {
/* Defrag helper for sorted set.
* Defrag a single dict entry key name, and corresponding skiplist struct */
-long activeDefragZsetEntry(zset *zs, dictEntry *de) {
+void activeDefragZsetEntry(zset *zs, dictEntry *de) {
sds newsds;
double* newscore;
- long defragged = 0;
sds sdsele = dictGetKey(de);
if ((newsds = activeDefragSds(sdsele)))
- defragged++, dictSetKey(zs->dict, de, newsds);
+ dictSetKey(zs->dict, de, newsds);
newscore = zslDefrag(zs->zsl, *(double*)dictGetVal(de), sdsele, newsds);
if (newscore) {
dictSetVal(zs->dict, de, newscore);
- defragged++;
}
- return defragged;
}
#define DEFRAG_SDS_DICT_NO_VAL 0
@@ -249,7 +241,6 @@ long activeDefragZsetEntry(zset *zs, dictEntry *de) {
typedef struct {
dict *dict;
int val_type;
- long defragged;
} activeDefragSdsDictData;
void activeDefragSdsDictCallback(void *privdata, const dictEntry *_de) {
@@ -259,41 +250,39 @@ void activeDefragSdsDictCallback(void *privdata, const dictEntry *_de) {
int val_type = data->val_type;
sds sdsele = dictGetKey(de), newsds;
if ((newsds = activeDefragSds(sdsele)))
- dictSetKey(d, de, newsds), data->defragged++;
+ dictSetKey(d, de, newsds);
/* defrag the value */
if (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) {
sdsele = dictGetVal(de);
if ((newsds = activeDefragSds(sdsele)))
- dictSetVal(d, de, newsds), data->defragged++;
+ dictSetVal(d, de, newsds);
} else if (val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) {
robj *newele, *ele = dictGetVal(de);
- if ((newele = activeDefragStringOb(ele, &data->defragged)))
+ if ((newele = activeDefragStringOb(ele)))
dictSetVal(d, de, newele);
} else if (val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) {
void *newptr, *ptr = dictGetVal(de);
if ((newptr = activeDefragAlloc(ptr)))
- dictSetVal(d, de, newptr), data->defragged++;
+ dictSetVal(d, de, newptr);
} else if (val_type == DEFRAG_SDS_DICT_VAL_LUA_SCRIPT) {
void *newptr, *ptr = dictGetVal(de);
- if ((newptr = activeDefragLuaScript(ptr, &data->defragged)))
+ if ((newptr = activeDefragLuaScript(ptr)))
dictSetVal(d, de, newptr);
}
}
/* Defrag a dict with sds key and optional value (either ptr, sds or robj string) */
-long activeDefragSdsDict(dict* d, int val_type) {
- activeDefragSdsDictData data = {d, val_type, 0};
+void activeDefragSdsDict(dict* d, int val_type) {
+ activeDefragSdsDictData data = {d, val_type};
unsigned long cursor = 0;
do {
cursor = dictScanDefrag(d, cursor, activeDefragSdsDictCallback,
activeDefragAlloc, &data);
} while (cursor != 0);
- return data.defragged;
}
/* Defrag a list of ptr, sds or robj string values */
-long activeDefragList(list *l, int val_type) {
- long defragged = 0;
+void activeDefragList(list *l, int val_type) {
listNode *ln, *newln;
for (ln = l->head; ln; ln = ln->next) {
if ((newln = activeDefragAlloc(ln))) {
@@ -306,28 +295,25 @@ long activeDefragList(list *l, int val_type) {
else
l->tail = newln;
ln = newln;
- defragged++;
}
if (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) {
sds newsds, sdsele = ln->value;
if ((newsds = activeDefragSds(sdsele)))
- ln->value = newsds, defragged++;
+ ln->value = newsds;
} else if (val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) {
robj *newele, *ele = ln->value;
- if ((newele = activeDefragStringOb(ele, &defragged)))
+ if ((newele = activeDefragStringOb(ele)))
ln->value = newele;
} else if (val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) {
void *newptr, *ptr = ln->value;
if ((newptr = activeDefragAlloc(ptr)))
- ln->value = newptr, defragged++;
+ ln->value = newptr;
}
}
- return defragged;
}
-long activeDefragQuickListNode(quicklist *ql, quicklistNode **node_ref) {
+void activeDefragQuickListNode(quicklist *ql, quicklistNode **node_ref) {
quicklistNode *newnode, *node = *node_ref;
- long defragged = 0;
unsigned char *newzl;
if ((newnode = activeDefragAlloc(node))) {
if (newnode->prev)
@@ -339,21 +325,17 @@ long activeDefragQuickListNode(quicklist *ql, quicklistNode **node_ref) {
else
ql->tail = newnode;
*node_ref = node = newnode;
- defragged++;
}
if ((newzl = activeDefragAlloc(node->entry)))
- defragged++, node->entry = newzl;
- return defragged;
+ node->entry = newzl;
}
-long activeDefragQuickListNodes(quicklist *ql) {
+void activeDefragQuickListNodes(quicklist *ql) {
quicklistNode *node = ql->head;
- long defragged = 0;
while (node) {
- defragged += activeDefragQuickListNode(ql, &node);
+ activeDefragQuickListNode(ql, &node);
node = node->next;
}
- return defragged;
}
/* when the value has lots of elements, we want to handle it later and not as
@@ -365,7 +347,7 @@ void defragLater(redisDb *db, dictEntry *kde) {
}
/* returns 0 if no more work needs to be been done, and 1 if time is up and more work is needed. */
-long scanLaterList(robj *ob, unsigned long *cursor, long long endtime, long long *defragged) {
+long scanLaterList(robj *ob, unsigned long *cursor, long long endtime) {
quicklist *ql = ob->ptr;
quicklistNode *node;
long iterations = 0;
@@ -388,7 +370,7 @@ long scanLaterList(robj *ob, unsigned long *cursor, long long endtime, long long
(*cursor)++;
while (node) {
- (*defragged) += activeDefragQuickListNode(ql, &node);
+ activeDefragQuickListNode(ql, &node);
server.stat_active_defrag_scanned++;
if (++iterations > 128 && !bookmark_failed) {
if (ustime() > endtime) {
@@ -410,29 +392,26 @@ long scanLaterList(robj *ob, unsigned long *cursor, long long endtime, long long
typedef struct {
zset *zs;
- long defragged;
} scanLaterZsetData;
void scanLaterZsetCallback(void *privdata, const dictEntry *_de) {
dictEntry *de = (dictEntry*)_de;
scanLaterZsetData *data = privdata;
- data->defragged += activeDefragZsetEntry(data->zs, de);
+ activeDefragZsetEntry(data->zs, de);
server.stat_active_defrag_scanned++;
}
-long scanLaterZset(robj *ob, unsigned long *cursor) {
+void scanLaterZset(robj *ob, unsigned long *cursor) {
if (ob->type != OBJ_ZSET || ob->encoding != OBJ_ENCODING_SKIPLIST)
- return 0;
+ return;
zset *zs = (zset*)ob->ptr;
dict *d = zs->dict;
- scanLaterZsetData data = {zs, 0};
+ scanLaterZsetData data = {zs};
*cursor = dictScanDefrag(d, *cursor, scanLaterZsetCallback, activeDefragAlloc, &data);
- return data.defragged;
}
typedef struct {
dict *dict;
- long defragged;
} scanLaterDictData;
void scanLaterSetCallback(void *privdata, const dictEntry *_de) {
@@ -440,17 +419,16 @@ void scanLaterSetCallback(void *privdata, const dictEntry *_de) {
scanLaterDictData *data = privdata;
sds sdsele = dictGetKey(de), newsds;
if ((newsds = activeDefragSds(sdsele)))
- data->defragged++, dictSetKey(data->dict, de, newsds);
+ dictSetKey(data->dict, de, newsds);
server.stat_active_defrag_scanned++;
}
-long scanLaterSet(robj *ob, unsigned long *cursor) {
+void scanLaterSet(robj *ob, unsigned long *cursor) {
if (ob->type != OBJ_SET || ob->encoding != OBJ_ENCODING_HT)
- return 0;
+ return;
dict *d = ob->ptr;
- scanLaterDictData data = {d, 0};
+ scanLaterDictData data = {d};
*cursor = dictScanDefrag(d, *cursor, scanLaterSetCallback, activeDefragAlloc, &data);
- return data.defragged;
}
void scanLaterHashCallback(void *privdata, const dictEntry *_de) {
@@ -458,39 +436,35 @@ void scanLaterHashCallback(void *privdata, const dictEntry *_de) {
scanLaterDictData *data = privdata;
sds sdsele = dictGetKey(de), newsds;
if ((newsds = activeDefragSds(sdsele)))
- data->defragged++, dictSetKey(data->dict, de, newsds);
+ dictSetKey(data->dict, de, newsds);
sdsele = dictGetVal(de);
if ((newsds = activeDefragSds(sdsele)))
- data->defragged++, dictSetVal(data->dict, de, newsds);
+ dictSetVal(data->dict, de, newsds);
server.stat_active_defrag_scanned++;
}
-long scanLaterHash(robj *ob, unsigned long *cursor) {
+void scanLaterHash(robj *ob, unsigned long *cursor) {
if (ob->type != OBJ_HASH || ob->encoding != OBJ_ENCODING_HT)
- return 0;
+ return;
dict *d = ob->ptr;
- scanLaterDictData data = {d, 0};
+ scanLaterDictData data = {d};
*cursor = dictScanDefrag(d, *cursor, scanLaterHashCallback, activeDefragAlloc, &data);
- return data.defragged;
}
-long defragQuicklist(redisDb *db, dictEntry *kde) {
+void defragQuicklist(redisDb *db, dictEntry *kde) {
robj *ob = dictGetVal(kde);
- long defragged = 0;
quicklist *ql = ob->ptr, *newql;
serverAssert(ob->type == OBJ_LIST && ob->encoding == OBJ_ENCODING_QUICKLIST);
if ((newql = activeDefragAlloc(ql)))
- defragged++, ob->ptr = ql = newql;
+ ob->ptr = ql = newql;
if (ql->len > server.active_defrag_max_scan_fields)
defragLater(db, kde);
else
- defragged += activeDefragQuickListNodes(ql);
- return defragged;
+ activeDefragQuickListNodes(ql);
}
-long defragZsetSkiplist(redisDb *db, dictEntry *kde) {
+void defragZsetSkiplist(redisDb *db, dictEntry *kde) {
robj *ob = dictGetVal(kde);
- long defragged = 0;
zset *zs = (zset*)ob->ptr;
zset *newzs;
zskiplist *newzsl;
@@ -499,30 +473,28 @@ long defragZsetSkiplist(redisDb *db, dictEntry *kde) {
struct zskiplistNode *newheader;
serverAssert(ob->type == OBJ_ZSET && ob->encoding == OBJ_ENCODING_SKIPLIST);
if ((newzs = activeDefragAlloc(zs)))
- defragged++, ob->ptr = zs = newzs;
+ ob->ptr = zs = newzs;
if ((newzsl = activeDefragAlloc(zs->zsl)))
- defragged++, zs->zsl = newzsl;
+ zs->zsl = newzsl;
if ((newheader = activeDefragAlloc(zs->zsl->header)))
- defragged++, zs->zsl->header = newheader;
+ zs->zsl->header = newheader;
if (dictSize(zs->dict) > server.active_defrag_max_scan_fields)
defragLater(db, kde);
else {
dictIterator *di = dictGetIterator(zs->dict);
while((de = dictNext(di)) != NULL) {
- defragged += activeDefragZsetEntry(zs, de);
+ activeDefragZsetEntry(zs, de);
}
dictReleaseIterator(di);
}
/* handle the dict struct */
if ((newdict = activeDefragAlloc(zs->dict)))
- defragged++, zs->dict = newdict;
+ zs->dict = newdict;
/* defrag the dict tables */
- defragged += dictDefragTables(zs->dict);
- return defragged;
+ dictDefragTables(zs->dict);
}
-long defragHash(redisDb *db, dictEntry *kde) {
- long defragged = 0;
+void defragHash(redisDb *db, dictEntry *kde) {
robj *ob = dictGetVal(kde);
dict *d, *newd;
serverAssert(ob->type == OBJ_HASH && ob->encoding == OBJ_ENCODING_HT);
@@ -530,17 +502,15 @@ long defragHash(redisDb *db, dictEntry *kde) {
if (dictSize(d) > server.active_defrag_max_scan_fields)
defragLater(db, kde);
else
- defragged += activeDefragSdsDict(d, DEFRAG_SDS_DICT_VAL_IS_SDS);
+ activeDefragSdsDict(d, DEFRAG_SDS_DICT_VAL_IS_SDS);
/* handle the dict struct */
if ((newd = activeDefragAlloc(ob->ptr)))
- defragged++, ob->ptr = newd;
+ ob->ptr = newd;
/* defrag the dict tables */
- defragged += dictDefragTables(ob->ptr);
- return defragged;
+ dictDefragTables(ob->ptr);
}
-long defragSet(redisDb *db, dictEntry *kde) {
- long defragged = 0;
+void defragSet(redisDb *db, dictEntry *kde) {
robj *ob = dictGetVal(kde);
dict *d, *newd;
serverAssert(ob->type == OBJ_SET && ob->encoding == OBJ_ENCODING_HT);
@@ -548,13 +518,12 @@ long defragSet(redisDb *db, dictEntry *kde) {
if (dictSize(d) > server.active_defrag_max_scan_fields)
defragLater(db, kde);
else
- defragged += activeDefragSdsDict(d, DEFRAG_SDS_DICT_NO_VAL);
+ activeDefragSdsDict(d, DEFRAG_SDS_DICT_NO_VAL);
/* handle the dict struct */
if ((newd = activeDefragAlloc(ob->ptr)))
- defragged++, ob->ptr = newd;
+ ob->ptr = newd;
/* defrag the dict tables */
- defragged += dictDefragTables(ob->ptr);
- return defragged;
+ dictDefragTables(ob->ptr);
}
/* Defrag callback for radix tree iterator, called for each node,
@@ -569,7 +538,7 @@ int defragRaxNode(raxNode **noderef) {
}
/* returns 0 if no more work needs to be been done, and 1 if time is up and more work is needed. */
-int scanLaterStreamListpacks(robj *ob, unsigned long *cursor, long long endtime, long long *defragged) {
+int scanLaterStreamListpacks(robj *ob, unsigned long *cursor, long long endtime) {
static unsigned char last[sizeof(streamID)];
raxIterator ri;
long iterations = 0;
@@ -603,7 +572,7 @@ int scanLaterStreamListpacks(robj *ob, unsigned long *cursor, long long endtime,
while (raxNext(&ri)) {
void *newdata = activeDefragAlloc(ri.data);
if (newdata)
- raxSetData(ri.node, ri.data=newdata), (*defragged)++;
+ raxSetData(ri.node, ri.data=newdata);
server.stat_active_defrag_scanned++;
if (++iterations > 128) {
if (ustime() > endtime) {
@@ -621,19 +590,18 @@ int scanLaterStreamListpacks(robj *ob, unsigned long *cursor, long long endtime,
}
/* optional callback used defrag each rax element (not including the element pointer itself) */
-typedef void *(raxDefragFunction)(raxIterator *ri, void *privdata, long *defragged);
+typedef void *(raxDefragFunction)(raxIterator *ri, void *privdata);
/* defrag radix tree including:
* 1) rax struct
* 2) rax nodes
* 3) rax entry data (only if defrag_data is specified)
* 4) call a callback per element, and allow the callback to return a new pointer for the element */
-long defragRadixTree(rax **raxref, int defrag_data, raxDefragFunction *element_cb, void *element_cb_data) {
- long defragged = 0;
+void defragRadixTree(rax **raxref, int defrag_data, raxDefragFunction *element_cb, void *element_cb_data) {
raxIterator ri;
rax* rax;
if ((rax = activeDefragAlloc(*raxref)))
- defragged++, *raxref = rax;
+ *raxref = rax;
rax = *raxref;
raxStart(&ri,rax);
ri.node_cb = defragRaxNode;
@@ -642,14 +610,13 @@ long defragRadixTree(rax **raxref, int defrag_data, raxDefragFunction *element_c
while (raxNext(&ri)) {
void *newdata = NULL;
if (element_cb)
- newdata = element_cb(&ri, element_cb_data, &defragged);
+ newdata = element_cb(&ri, element_cb_data);
if (defrag_data && !newdata)
newdata = activeDefragAlloc(ri.data);
if (newdata)
- raxSetData(ri.node, ri.data=newdata), defragged++;
+ raxSetData(ri.node, ri.data=newdata);
}
raxStop(&ri);
- return defragged;
}
typedef struct {
@@ -657,8 +624,7 @@ typedef struct {
streamConsumer *c;
} PendingEntryContext;
-void* defragStreamConsumerPendingEntry(raxIterator *ri, void *privdata, long *defragged) {
- UNUSED(defragged);
+void* defragStreamConsumerPendingEntry(raxIterator *ri, void *privdata) {
PendingEntryContext *ctx = privdata;
streamNACK *nack = ri->data, *newnack;
nack->consumer = ctx->c; /* update nack pointer to consumer */
@@ -668,90 +634,81 @@ void* defragStreamConsumerPendingEntry(raxIterator *ri, void *privdata, long *de
void *prev;
raxInsert(ctx->cg->pel, ri->key, ri->key_len, newnack, &prev);
serverAssert(prev==nack);
- /* note: we don't increment 'defragged' that's done by the caller */
}
return newnack;
}
-void* defragStreamConsumer(raxIterator *ri, void *privdata, long *defragged) {
+void* defragStreamConsumer(raxIterator *ri, void *privdata) {
streamConsumer *c = ri->data;
streamCG *cg = privdata;
void *newc = activeDefragAlloc(c);
if (newc) {
- /* note: we don't increment 'defragged' that's done by the caller */
c = newc;
}
sds newsds = activeDefragSds(c->name);
if (newsds)
- (*defragged)++, c->name = newsds;
+ c->name = newsds;
if (c->pel) {
PendingEntryContext pel_ctx = {cg, c};
- *defragged += defragRadixTree(&c->pel, 0, defragStreamConsumerPendingEntry, &pel_ctx);
+ defragRadixTree(&c->pel, 0, defragStreamConsumerPendingEntry, &pel_ctx);
}
return newc; /* returns NULL if c was not defragged */
}
-void* defragStreamConsumerGroup(raxIterator *ri, void *privdata, long *defragged) {
+void* defragStreamConsumerGroup(raxIterator *ri, void *privdata) {
streamCG *cg = ri->data;
UNUSED(privdata);
if (cg->consumers)
- *defragged += defragRadixTree(&cg->consumers, 0, defragStreamConsumer, cg);
+ defragRadixTree(&cg->consumers, 0, defragStreamConsumer, cg);
if (cg->pel)
- *defragged += defragRadixTree(&cg->pel, 0, NULL, NULL);
+ defragRadixTree(&cg->pel, 0, NULL, NULL);
return NULL;
}
-long defragStream(redisDb *db, dictEntry *kde) {
- long defragged = 0;
+void defragStream(redisDb *db, dictEntry *kde) {
robj *ob = dictGetVal(kde);
serverAssert(ob->type == OBJ_STREAM && ob->encoding == OBJ_ENCODING_STREAM);
stream *s = ob->ptr, *news;
/* handle the main struct */
if ((news = activeDefragAlloc(s)))
- defragged++, ob->ptr = s = news;
+ ob->ptr = s = news;
if (raxSize(s->rax) > server.active_defrag_max_scan_fields) {
rax *newrax = activeDefragAlloc(s->rax);
if (newrax)
- defragged++, s->rax = newrax;
+ s->rax = newrax;
defragLater(db, kde);
} else
- defragged += defragRadixTree(&s->rax, 1, NULL, NULL);
+ defragRadixTree(&s->rax, 1, NULL, NULL);
if (s->cgroups)
- defragged += defragRadixTree(&s->cgroups, 1, defragStreamConsumerGroup, NULL);
- return defragged;
+ defragRadixTree(&s->cgroups, 1, defragStreamConsumerGroup, NULL);
}
/* Defrag a module key. This is either done immediately or scheduled
* for later. Returns then number of pointers defragged.
*/
-long defragModule(redisDb *db, dictEntry *kde) {
+void defragModule(redisDb *db, dictEntry *kde) {
robj *obj = dictGetVal(kde);
serverAssert(obj->type == OBJ_MODULE);
- long defragged = 0;
- if (!moduleDefragValue(dictGetKey(kde), obj, &defragged, db->id))
+ if (!moduleDefragValue(dictGetKey(kde), obj, db->id))
defragLater(db, kde);
-
- return defragged;
}
/* for each key we scan in the main dict, this function will attempt to defrag
* all the various pointers it has. Returns a stat of how many pointers were
* moved. */
-long defragKey(redisDb *db, dictEntry *de) {
+void defragKey(redisDb *db, dictEntry *de) {
sds keysds = dictGetKey(de);
robj *newob, *ob;
unsigned char *newzl;
- long defragged = 0;
sds newsds;
/* Try to defrag the key name. */
newsds = activeDefragSds(keysds);
if (newsds) {
- defragged++;
dictSetKey(db->dict, de, newsds);
if (dictSize(db->expires)) {
/* We can't search in db->expires for that key after we've released
@@ -765,7 +722,7 @@ long defragKey(redisDb *db, dictEntry *de) {
/* Try to defrag robj and / or string value. */
ob = dictGetVal(de);
- if ((newob = activeDefragStringOb(ob, &defragged))) {
+ if ((newob = activeDefragStringOb(ob))) {
dictSetVal(db->dict, de, newob);
ob = newob;
}
@@ -774,58 +731,57 @@ long defragKey(redisDb *db, dictEntry *de) {
/* Already handled in activeDefragStringOb. */
} else if (ob->type == OBJ_LIST) {
if (ob->encoding == OBJ_ENCODING_QUICKLIST) {
- defragged += defragQuicklist(db, de);
+ defragQuicklist(db, de);
} else if (ob->encoding == OBJ_ENCODING_LISTPACK) {
if ((newzl = activeDefragAlloc(ob->ptr)))
- defragged++, ob->ptr = newzl;
+ ob->ptr = newzl;
} else {
serverPanic("Unknown list encoding");
}
} else if (ob->type == OBJ_SET) {
if (ob->encoding == OBJ_ENCODING_HT) {
- defragged += defragSet(db, de);
+ defragSet(db, de);
} else if (ob->encoding == OBJ_ENCODING_INTSET ||
ob->encoding == OBJ_ENCODING_LISTPACK)
{
void *newptr, *ptr = ob->ptr;
if ((newptr = activeDefragAlloc(ptr)))
- defragged++, ob->ptr = newptr;
+ ob->ptr = newptr;
} else {
serverPanic("Unknown set encoding");
}
} else if (ob->type == OBJ_ZSET) {
if (ob->encoding == OBJ_ENCODING_LISTPACK) {
if ((newzl = activeDefragAlloc(ob->ptr)))
- defragged++, ob->ptr = newzl;
+ ob->ptr = newzl;
} else if (ob->encoding == OBJ_ENCODING_SKIPLIST) {
- defragged += defragZsetSkiplist(db, de);
+ defragZsetSkiplist(db, de);
} else {
serverPanic("Unknown sorted set encoding");
}
} else if (ob->type == OBJ_HASH) {
if (ob->encoding == OBJ_ENCODING_LISTPACK) {
if ((newzl = activeDefragAlloc(ob->ptr)))
- defragged++, ob->ptr = newzl;
+ ob->ptr = newzl;
} else if (ob->encoding == OBJ_ENCODING_HT) {
- defragged += defragHash(db, de);
+ defragHash(db, de);
} else {
serverPanic("Unknown hash encoding");
}
} else if (ob->type == OBJ_STREAM) {
- defragged += defragStream(db, de);
+ defragStream(db, de);
} else if (ob->type == OBJ_MODULE) {
- defragged += defragModule(db, de);
+ defragModule(db, de);
} else {
serverPanic("Unknown object type");
}
- return defragged;
}
/* Defrag scan callback for the main db dictionary. */
void defragScanCallback(void *privdata, const dictEntry *de) {
- long defragged = defragKey((redisDb*)privdata, (dictEntry*)de);
- server.stat_active_defrag_hits += defragged;
- if(defragged)
+ long long hits_before = server.stat_active_defrag_hits;
+ defragKey((redisDb*)privdata, (dictEntry*)de);
+ if (server.stat_active_defrag_hits != hits_before)
server.stat_active_defrag_key_hits++;
else
server.stat_active_defrag_key_misses++;
@@ -863,15 +819,13 @@ float getAllocatorFragmentation(size_t *out_frag_bytes) {
/* We may need to defrag other globals, one small allocation can hold a full allocator run.
* so although small, it is still important to defrag these */
-long defragOtherGlobals() {
- long defragged = 0;
+void defragOtherGlobals() {
/* there are many more pointers to defrag (e.g. client argv, output / aof buffers, etc.
* but we assume most of these are short lived, we only need to defrag allocations
* that remain static for a long time */
- defragged += activeDefragSdsDict(evalScriptsDict(), DEFRAG_SDS_DICT_VAL_LUA_SCRIPT);
- defragged += moduleDefragGlobals();
- return defragged;
+ activeDefragSdsDict(evalScriptsDict(), DEFRAG_SDS_DICT_VAL_LUA_SCRIPT);
+ moduleDefragGlobals();
}
/* returns 0 more work may or may not be needed (see non-zero cursor),
@@ -880,17 +834,17 @@ int defragLaterItem(dictEntry *de, unsigned long *cursor, long long endtime, int
if (de) {
robj *ob = dictGetVal(de);
if (ob->type == OBJ_LIST) {
- return scanLaterList(ob, cursor, endtime, &server.stat_active_defrag_hits);
+ return scanLaterList(ob, cursor, endtime);
} else if (ob->type == OBJ_SET) {
- server.stat_active_defrag_hits += scanLaterSet(ob, cursor);
+ scanLaterSet(ob, cursor);
} else if (ob->type == OBJ_ZSET) {
- server.stat_active_defrag_hits += scanLaterZset(ob, cursor);
+ scanLaterZset(ob, cursor);
} else if (ob->type == OBJ_HASH) {
- server.stat_active_defrag_hits += scanLaterHash(ob, cursor);
+ scanLaterHash(ob, cursor);
} else if (ob->type == OBJ_STREAM) {
- return scanLaterStreamListpacks(ob, cursor, endtime, &server.stat_active_defrag_hits);
+ return scanLaterStreamListpacks(ob, cursor, endtime);
} else if (ob->type == OBJ_MODULE) {
- return moduleLateDefrag(dictGetKey(de), ob, cursor, endtime, &server.stat_active_defrag_hits, dbid);
+ return moduleLateDefrag(dictGetKey(de), ob, cursor, endtime, dbid);
} else {
*cursor = 0; /* object type may have changed since we schedule it for later */
}
@@ -1061,7 +1015,7 @@ void activeDefragCycle(void) {
/* Move on to next database, and stop if we reached the last one. */
if (++current_db >= server.dbnum) {
/* defrag other items not part of the db / keys */
- server.stat_active_defrag_hits += defragOtherGlobals();
+ defragOtherGlobals();
long long now = ustime();
size_t frag_bytes;
@@ -1100,19 +1054,14 @@ void activeDefragCycle(void) {
/* Scan the keyspace dict unless we're scanning the expire dict. */
if (!expires_cursor)
- cursor = dictScanDefrag(db->dict,
- cursor,
- defragScanCallback,
- activeDefragAlloc,
- db);
+ cursor = dictScanDefrag(db->dict, cursor, defragScanCallback,
+ activeDefragAlloc, db);
/* When done scanning the keyspace dict, we scan the expire dict. */
if (!cursor)
- expires_cursor = dictScanDefrag(db->expires,
- expires_cursor,
+ expires_cursor = dictScanDefrag(db->expires, expires_cursor,
defragExpireScanCallback,
- activeDefragAlloc,
- NULL);
+ activeDefragAlloc, NULL);
/* Once in 16 scan iterations, 512 pointer reallocations. or 64 keys
* (if we have a lot of pointers in one hash bucket or rehashing),
@@ -1159,9 +1108,8 @@ void *activeDefragAlloc(void *ptr) {
return NULL;
}
-robj *activeDefragStringOb(robj *ob, long *defragged) {
+robj *activeDefragStringOb(robj *ob) {
UNUSED(ob);
- UNUSED(defragged);
return NULL;
}
diff --git a/src/module.c b/src/module.c
index b745e8ee4..481553f12 100644
--- a/src/module.c
+++ b/src/module.c
@@ -12562,7 +12562,6 @@ const char *RM_GetCurrentCommandName(RedisModuleCtx *ctx) {
* defrag callback.
*/
struct RedisModuleDefragCtx {
- long defragged;
long long int endtime;
unsigned long *cursor;
struct redisObject *key; /* Optional name of key processed, NULL when unknown. */
@@ -12651,11 +12650,8 @@ int RM_DefragCursorGet(RedisModuleDefragCtx *ctx, unsigned long *cursor) {
* be used again.
*/
void *RM_DefragAlloc(RedisModuleDefragCtx *ctx, void *ptr) {
- void *newptr = activeDefragAlloc(ptr);
- if (newptr)
- ctx->defragged++;
-
- return newptr;
+ UNUSED(ctx);
+ return activeDefragAlloc(ptr);
}
/* Defrag a RedisModuleString previously allocated by RM_Alloc, RM_Calloc, etc.
@@ -12669,7 +12665,8 @@ void *RM_DefragAlloc(RedisModuleDefragCtx *ctx, void *ptr) {
* on the Redis side is dropped as soon as the command callback returns).
*/
RedisModuleString *RM_DefragRedisModuleString(RedisModuleDefragCtx *ctx, RedisModuleString *str) {
- return activeDefragStringOb(str, &ctx->defragged);
+ UNUSED(ctx);
+ return activeDefragStringOb(str);
}
@@ -12678,11 +12675,11 @@ RedisModuleString *RM_DefragRedisModuleString(RedisModuleDefragCtx *ctx, RedisMo
* Returns a zero value (and initializes the cursor) if no more needs to be done,
* or a non-zero value otherwise.
*/
-int moduleLateDefrag(robj *key, robj *value, unsigned long *cursor, long long endtime, long long *defragged, int dbid) {
+int moduleLateDefrag(robj *key, robj *value, unsigned long *cursor, long long endtime, int dbid) {
moduleValue *mv = value->ptr;
moduleType *mt = mv->type;
- RedisModuleDefragCtx defrag_ctx = { 0, endtime, cursor, key, dbid};
+ RedisModuleDefragCtx defrag_ctx = { endtime, cursor, key, dbid};
/* Invoke callback. Note that the callback may be missing if the key has been
* replaced with a different type since our last visit.
@@ -12691,7 +12688,6 @@ int moduleLateDefrag(robj *key, robj *value, unsigned long *cursor, long long en
if (mt->defrag)
ret = mt->defrag(&defrag_ctx, key, &mv->value);
- *defragged += defrag_ctx.defragged;
if (!ret) {
*cursor = 0; /* No more work to do */
return 0;
@@ -12706,7 +12702,7 @@ int moduleLateDefrag(robj *key, robj *value, unsigned long *cursor, long long en
* Returns 1 if the operation has been completed or 0 if it needs to
* be scheduled for late defrag.
*/
-int moduleDefragValue(robj *key, robj *value, long *defragged, int dbid) {
+int moduleDefragValue(robj *key, robj *value, int dbid) {
moduleValue *mv = value->ptr;
moduleType *mt = mv->type;
@@ -12715,7 +12711,6 @@ int moduleDefragValue(robj *key, robj *value, long *defragged, int dbid) {
*/
moduleValue *newmv = activeDefragAlloc(mv);
if (newmv) {
- (*defragged)++;
value->ptr = mv = newmv;
}
@@ -12733,29 +12728,24 @@ int moduleDefragValue(robj *key, robj *value, long *defragged, int dbid) {
return 0; /* Defrag later */
}
- RedisModuleDefragCtx defrag_ctx = { 0, 0, NULL, key, dbid};
+ RedisModuleDefragCtx defrag_ctx = { 0, NULL, key, dbid };
mt->defrag(&defrag_ctx, key, &mv->value);
- (*defragged) += defrag_ctx.defragged;
return 1;
}
/* Call registered module API defrag functions */
-long moduleDefragGlobals(void) {
+void moduleDefragGlobals(void) {
dictIterator *di = dictGetIterator(modules);
dictEntry *de;
- long defragged = 0;
while ((de = dictNext(di)) != NULL) {
struct RedisModule *module = dictGetVal(de);
if (!module->defrag_cb)
continue;
- RedisModuleDefragCtx defrag_ctx = { 0, 0, NULL, NULL, -1};
+ RedisModuleDefragCtx defrag_ctx = { 0, NULL, NULL, -1};
module->defrag_cb(&defrag_ctx);
- defragged += defrag_ctx.defragged;
}
dictReleaseIterator(di);
-
- return defragged;
}
/* Returns the name of the key currently being processed.
diff --git a/src/server.h b/src/server.h
index 86611c321..bf0a15459 100644
--- a/src/server.h
+++ b/src/server.h
@@ -2442,9 +2442,9 @@ void moduleNotifyKeyUnlink(robj *key, robj *val, int dbid, int flags);
size_t moduleGetFreeEffort(robj *key, robj *val, int dbid);
size_t moduleGetMemUsage(robj *key, robj *val, size_t sample_size, int dbid);
robj *moduleTypeDupOrReply(client *c, robj *fromkey, robj *tokey, int todb, robj *value);
-int moduleDefragValue(robj *key, robj *obj, long *defragged, int dbid);
-int moduleLateDefrag(robj *key, robj *value, unsigned long *cursor, long long endtime, long long *defragged, int dbid);
-long moduleDefragGlobals(void);
+int moduleDefragValue(robj *key, robj *obj, int dbid);
+int moduleLateDefrag(robj *key, robj *value, unsigned long *cursor, long long endtime, int dbid);
+void moduleDefragGlobals(void);
void *moduleGetHandleByName(char *modulename);
int moduleIsModuleCommand(void *module_handle, struct redisCommand *cmd);
@@ -2988,7 +2988,7 @@ void checkChildrenDone(void);
int setOOMScoreAdj(int process_class);
void rejectCommandFormat(client *c, const char *fmt, ...);
void *activeDefragAlloc(void *ptr);
-robj *activeDefragStringOb(robj* ob, long *defragged);
+robj *activeDefragStringOb(robj* ob);
void dismissSds(sds s);
void dismissMemory(void* ptr, size_t size_hint);
void dismissMemoryInChild(void);