@@ -29,6 +29,9 @@ unsigned long int global_defragged = 0;
2929unsigned long global_strings_len = 0 ;
3030RedisModuleString * * global_strings = NULL ;
3131
32+ unsigned long global_dicts_len = 0 ;
33+ RedisModuleDict * * global_dicts = NULL ;
34+
3235static 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
59112static 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