Skip to content

Commit 951cefa

Browse files
committed
Simplify RedisModule DefragRedisModuleDict API
1 parent 4ebdf9b commit 951cefa

File tree

3 files changed

+60
-13
lines changed

3 files changed

+60
-13
lines changed

src/module.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13930,8 +13930,8 @@ int moduleDefragRaxNode(raxNode **noderef) {
1393013930
}
1393113931

1393213932
/* Defrag a RedisModuleDict previously allocated by RM_CreateDict. */
13933-
typedef void *(*RedisModuleDefragDictFunc)(RedisModuleDefragCtx *ctx, RedisModuleDict *dict, void *data, void *privdata);
13934-
RedisModuleDict *RM_DefragRedisModuleDict(RedisModuleDefragCtx *ctx, RedisModuleDict *dict, RedisModuleDefragDictFunc callback, void *privdata) {
13933+
RedisModuleDict *RM_DefragRedisModuleDict(RedisModuleDefragCtx *ctx, RedisModuleDict *dict) {
13934+
UNUSED(ctx);
1393513935
RedisModuleDict *newdict = NULL;
1393613936
rax* newrax;
1393713937
raxIterator ri;
@@ -13944,13 +13944,7 @@ RedisModuleDict *RM_DefragRedisModuleDict(RedisModuleDefragCtx *ctx, RedisModule
1394413944
ri.node_cb = moduleDefragRaxNode;
1394513945
moduleDefragRaxNode(&dict->rax->head);
1394613946
raxSeek(&ri,"^",NULL,0);
13947-
while (raxNext(&ri)) {
13948-
void *newdata = NULL;
13949-
if (callback)
13950-
newdata = callback(ctx, dict, ri.data, privdata);
13951-
if (newdata)
13952-
raxSetData(ri.node, ri.data=newdata);
13953-
}
13947+
while (raxNext(&ri)) {}
1395413948
raxStop(&ri);
1395513949
return dict;
1395613950
}

src/redismodule.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,6 @@ typedef int (*RedisModuleConfigSetEnumFunc)(const char *name, int val, void *pri
927927
typedef int (*RedisModuleConfigApplyFunc)(RedisModuleCtx *ctx, void *privdata, RedisModuleString **err);
928928
typedef void (*RedisModuleOnUnblocked)(RedisModuleCtx *ctx, RedisModuleCallReply *reply, void *private_data);
929929
typedef int (*RedisModuleAuthCallback)(RedisModuleCtx *ctx, RedisModuleString *username, RedisModuleString *password, RedisModuleString **err);
930-
typedef void (*RedisModuleDefragDictFunc)(RedisModuleDefragCtx *ctx, RedisModuleDict *dict, void *data, void *privdata);
931930

932931
typedef struct RedisModuleTypeMethods {
933932
uint64_t version;
@@ -1311,7 +1310,7 @@ REDISMODULE_API void *(*RedisModule_DefragAlloc)(RedisModuleDefragCtx *ctx, void
13111310
REDISMODULE_API void *(*RedisModule_DefragAllocRaw)(RedisModuleDefragCtx *ctx, size_t size) REDISMODULE_ATTR;
13121311
REDISMODULE_API void (*RedisModule_DefragFreeRaw)(RedisModuleDefragCtx *ctx, void *ptr) REDISMODULE_ATTR;
13131312
REDISMODULE_API RedisModuleString *(*RedisModule_DefragRedisModuleString)(RedisModuleDefragCtx *ctx, RedisModuleString *str) REDISMODULE_ATTR;
1314-
REDISMODULE_API RedisModuleDict *(*RedisModule_DefragRedisModuleDict)(RedisModuleDefragCtx *ctx, RedisModuleDict *dict, RedisModuleDefragDictFunc *callback, void *privdata) REDISMODULE_ATTR;
1313+
REDISMODULE_API RedisModuleDict *(*RedisModule_DefragRedisModuleDict)(RedisModuleDefragCtx *ctx, RedisModuleDict *dict) REDISMODULE_ATTR;
13151314
REDISMODULE_API int (*RedisModule_DefragShouldStop)(RedisModuleDefragCtx *ctx) REDISMODULE_ATTR;
13161315
REDISMODULE_API int (*RedisModule_DefragCursorSet)(RedisModuleDefragCtx *ctx, unsigned long cursor) REDISMODULE_ATTR;
13171316
REDISMODULE_API int (*RedisModule_DefragCursorGet)(RedisModuleDefragCtx *ctx, unsigned long *cursor) REDISMODULE_ATTR;

tests/modules/defragtest.c

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ unsigned long int global_defragged = 0;
2929
unsigned long global_strings_len = 0;
3030
RedisModuleString **global_strings = NULL;
3131

32+
unsigned long global_dicts_len = 0;
33+
RedisModuleDict **global_dicts = NULL;
34+
3235
static void createGlobalStrings(RedisModuleCtx *ctx, unsigned long count)
3336
{
3437
global_strings_len = count;
@@ -39,7 +42,7 @@ static void createGlobalStrings(RedisModuleCtx *ctx, unsigned long count)
3942
}
4043
}
4144

42-
static void defragGlobalStrings(RedisModuleDefragCtx *ctx)
45+
static int defragGlobalStrings(RedisModuleDefragCtx *ctx)
4346
{
4447
unsigned long cursor = 0;
4548
RedisModule_DefragCursorGet(ctx, &cursor);
@@ -54,6 +57,56 @@ static void defragGlobalStrings(RedisModuleDefragCtx *ctx)
5457

5558
cursor++;
5659
RedisModule_DefragCursorSet(ctx, cursor == global_strings_len ? 0 : cursor);
60+
return cursor;
61+
}
62+
63+
static void createGlobalDicts(RedisModuleCtx *ctx, unsigned long count) {
64+
global_dicts_len = count;
65+
global_dicts = RedisModule_Alloc(sizeof(RedisModuleDict *) * count);
66+
67+
for (unsigned long i = 0; i < count; i++) {
68+
RedisModuleDict *dict = RedisModule_CreateDict(ctx);
69+
for (unsigned long j = 0; j < 100; j ++) {
70+
RedisModuleString *str = RedisModule_CreateStringFromULongLong(ctx, j);
71+
RedisModule_DictSet(dict, str, str);
72+
}
73+
global_dicts[i] = dict;
74+
}
75+
}
76+
77+
static int defragGlobalDicts(RedisModuleDefragCtx *ctx) {
78+
unsigned long cursor = 0;
79+
RedisModule_DefragCursorGet(ctx, &cursor);
80+
81+
RedisModule_Assert(cursor < global_dicts_len);
82+
RedisModuleDict *new = RedisModule_DefragRedisModuleDict(ctx, global_dicts[cursor]);
83+
global_attempts++;
84+
if (new != NULL) {
85+
global_dicts[cursor] = new;
86+
global_defragged++;
87+
}
88+
89+
cursor++;
90+
RedisModule_DefragCursorSet(ctx, cursor == global_dicts_len ? 0 : cursor);
91+
return cursor;
92+
}
93+
94+
typedef enum { DEFRAG_NOT_START, DEFRAG_STRING, DEFRAG_DICT } defrag_module_stage;
95+
static void defragGlobal(RedisModuleDefragCtx *ctx) {
96+
static defrag_module_stage stage = DEFRAG_NOT_START;
97+
if (stage == DEFRAG_NOT_START) {
98+
stage = DEFRAG_STRING; /* Start a new global defrag. */
99+
}
100+
101+
if (stage == DEFRAG_STRING) {
102+
if (defragGlobalStrings(ctx) == 0) {
103+
stage = DEFRAG_DICT;
104+
}
105+
} else {
106+
if (defragGlobalDicts(ctx) == 0) {
107+
stage = DEFRAG_NOT_START;
108+
}
109+
}
57110
}
58111

59112
static void defragStart(RedisModuleDefragCtx *ctx) {
@@ -243,6 +296,7 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
243296
}
244297

245298
createGlobalStrings(ctx, glen);
299+
createGlobalDicts(ctx, glen);
246300

247301
RedisModuleTypeMethods tm = {
248302
.version = REDISMODULE_TYPE_METHOD_VERSION,
@@ -263,7 +317,7 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
263317
return REDISMODULE_ERR;
264318

265319
RedisModule_RegisterInfoFunc(ctx, FragInfo);
266-
RedisModule_RegisterDefragFunc(ctx, defragGlobalStrings);
320+
RedisModule_RegisterDefragFunc(ctx, defragGlobal);
267321
RedisModule_RegisterDefragCallbacks(ctx, defragStart, defragEnd);
268322

269323
return REDISMODULE_OK;

0 commit comments

Comments
 (0)