summaryrefslogtreecommitdiff
path: root/src/defrag.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/defrag.c')
-rw-r--r--src/defrag.c105
1 files changed, 34 insertions, 71 deletions
diff --git a/src/defrag.c b/src/defrag.c
index b813ab74f..5b7fdb775 100644
--- a/src/defrag.c
+++ b/src/defrag.c
@@ -238,46 +238,26 @@ void activeDefragZsetEntry(zset *zs, dictEntry *de) {
#define DEFRAG_SDS_DICT_VAL_VOID_PTR 3
#define DEFRAG_SDS_DICT_VAL_LUA_SCRIPT 4
-typedef struct {
- dict *dict;
- int val_type;
-} activeDefragSdsDictData;
-
-void activeDefragSdsDictCallback(void *privdata, const dictEntry *_de) {
- dictEntry *de = (dictEntry*)_de;
- activeDefragSdsDictData *data = privdata;
- dict *d = data->dict;
- int val_type = data->val_type;
- sds sdsele = dictGetKey(de), newsds;
- if ((newsds = activeDefragSds(sdsele)))
- 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);
- } else if (val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) {
- robj *newele, *ele = dictGetVal(de);
- 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);
- } else if (val_type == DEFRAG_SDS_DICT_VAL_LUA_SCRIPT) {
- void *newptr, *ptr = dictGetVal(de);
- if ((newptr = activeDefragLuaScript(ptr)))
- dictSetVal(d, de, newptr);
- }
+void activeDefragSdsDictCallback(void *privdata, const dictEntry *de) {
+ UNUSED(privdata);
+ UNUSED(de);
}
/* Defrag a dict with sds key and optional value (either ptr, sds or robj string) */
void activeDefragSdsDict(dict* d, int val_type) {
- activeDefragSdsDictData data = {d, val_type};
unsigned long cursor = 0;
+ dictDefragFunctions defragfns = {
+ .defragAlloc = activeDefragAlloc,
+ .defragKey = (dictDefragAllocFunction *)activeDefragSds,
+ .defragVal = (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS ? (dictDefragAllocFunction *)activeDefragSds :
+ val_type == DEFRAG_SDS_DICT_VAL_IS_STROB ? (dictDefragAllocFunction *)activeDefragStringOb :
+ val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR ? (dictDefragAllocFunction *)activeDefragAlloc :
+ val_type == DEFRAG_SDS_DICT_VAL_LUA_SCRIPT ? (dictDefragAllocFunction *)activeDefragLuaScript :
+ NULL)
+ };
do {
cursor = dictScanDefrag(d, cursor, activeDefragSdsDictCallback,
- activeDefragAlloc, &data);
+ &defragfns, NULL);
} while (cursor != 0);
}
@@ -407,19 +387,14 @@ void scanLaterZset(robj *ob, unsigned long *cursor) {
zset *zs = (zset*)ob->ptr;
dict *d = zs->dict;
scanLaterZsetData data = {zs};
- *cursor = dictScanDefrag(d, *cursor, scanLaterZsetCallback, activeDefragAlloc, &data);
+ dictDefragFunctions defragfns = {.defragAlloc = activeDefragAlloc};
+ *cursor = dictScanDefrag(d, *cursor, scanLaterZsetCallback, &defragfns, &data);
}
-typedef struct {
- dict *dict;
-} scanLaterDictData;
-
-void scanLaterSetCallback(void *privdata, const dictEntry *_de) {
- dictEntry *de = (dictEntry*)_de;
- scanLaterDictData *data = privdata;
- sds sdsele = dictGetKey(de), newsds;
- if ((newsds = activeDefragSds(sdsele)))
- dictSetKey(data->dict, de, newsds);
+/* Used as scan callback when all the work is done in the dictDefragFunctions. */
+void scanCallbackCountScanned(void *privdata, const dictEntry *de) {
+ UNUSED(privdata);
+ UNUSED(de);
server.stat_active_defrag_scanned++;
}
@@ -427,28 +402,23 @@ void scanLaterSet(robj *ob, unsigned long *cursor) {
if (ob->type != OBJ_SET || ob->encoding != OBJ_ENCODING_HT)
return;
dict *d = ob->ptr;
- scanLaterDictData data = {d};
- *cursor = dictScanDefrag(d, *cursor, scanLaterSetCallback, activeDefragAlloc, &data);
-}
-
-void scanLaterHashCallback(void *privdata, const dictEntry *_de) {
- dictEntry *de = (dictEntry*)_de;
- scanLaterDictData *data = privdata;
- sds sdsele = dictGetKey(de), newsds;
- if ((newsds = activeDefragSds(sdsele)))
- dictSetKey(data->dict, de, newsds);
- sdsele = dictGetVal(de);
- if ((newsds = activeDefragSds(sdsele)))
- dictSetVal(data->dict, de, newsds);
- server.stat_active_defrag_scanned++;
+ dictDefragFunctions defragfns = {
+ .defragAlloc = activeDefragAlloc,
+ .defragKey = (dictDefragAllocFunction *)activeDefragSds
+ };
+ *cursor = dictScanDefrag(d, *cursor, scanCallbackCountScanned, &defragfns, NULL);
}
void scanLaterHash(robj *ob, unsigned long *cursor) {
if (ob->type != OBJ_HASH || ob->encoding != OBJ_ENCODING_HT)
return;
dict *d = ob->ptr;
- scanLaterDictData data = {d};
- *cursor = dictScanDefrag(d, *cursor, scanLaterHashCallback, activeDefragAlloc, &data);
+ dictDefragFunctions defragfns = {
+ .defragAlloc = activeDefragAlloc,
+ .defragKey = (dictDefragAllocFunction *)activeDefragSds,
+ .defragVal = (dictDefragAllocFunction *)activeDefragSds
+ };
+ *cursor = dictScanDefrag(d, *cursor, scanCallbackCountScanned, &defragfns, NULL);
}
void defragQuicklist(redisDb *db, dictEntry *kde) {
@@ -788,14 +758,6 @@ void defragScanCallback(void *privdata, const dictEntry *de) {
server.stat_active_defrag_scanned++;
}
-/* Dummy scan callback used when defragging the expire dictionary. We only
- * defrag the entries, which is done per bucket. */
-void defragExpireScanCallback(void *privdata, const dictEntry *de) {
- UNUSED(privdata);
- UNUSED(de);
- server.stat_active_defrag_scanned++;
-}
-
/* Utility function to get the fragmentation ratio from jemalloc.
* It is critical to do that by comparing only heap maps that belong to
* jemalloc, and skip ones the jemalloc keeps as spare. Since we use this
@@ -1003,6 +965,7 @@ void activeDefragCycle(void) {
endtime = start + timelimit;
latencyStartMonitor(latency);
+ dictDefragFunctions defragfns = {.defragAlloc = activeDefragAlloc};
do {
/* if we're not continuing a scan from the last call or loop, start a new one */
if (!cursor && !expires_cursor) {
@@ -1055,13 +1018,13 @@ 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);
+ &defragfns, db);
/* When done scanning the keyspace dict, we scan the expire dict. */
if (!cursor)
expires_cursor = dictScanDefrag(db->expires, expires_cursor,
- defragExpireScanCallback,
- activeDefragAlloc, NULL);
+ scanCallbackCountScanned,
+ &defragfns, 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),