From 58ac1f8bbe0f705e59b25b40fa00477dd79cc5e9 Mon Sep 17 00:00:00 2001 From: antirez Date: Tue, 25 Sep 2018 12:58:15 +0200 Subject: [PATCH] Modules: dictionary API WIP #7: don't store the context. Storing the context is useless, because we can't really reuse that later. For instance in the API RM_DictNext() that returns a RedisModuleString for the next key iterated, the user should pass the new context, because we may run the keys of the dictionary in a different context of the one where the dictionary was created. Also the dictionary may be created without a context, but we may still demand automatic memory management for the returned strings while iterating. --- src/module.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/module.c b/src/module.c index 332686ac..c1fbe122 100644 --- a/src/module.c +++ b/src/module.c @@ -250,8 +250,6 @@ static client *moduleFreeContextReusedClient; /* Data structures related to the exported dictionary data structure. */ typedef struct RedisModuleDict { - RedisModuleCtx *ctx; /* May be NULL for dictionaries created - out of a module context. */ rax *rax; /* The radix tree. */ } RedisModuleDict; @@ -271,7 +269,7 @@ robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int void moduleReplicateMultiIfNeeded(RedisModuleCtx *ctx); void RM_ZsetRangeStop(RedisModuleKey *kp); static void zsetKeyReset(RedisModuleKey *key); -void RM_FreeDict(RedisModuleDict *d); +void RM_FreeDict(RedisModuleCtx *ctx, RedisModuleDict *d); /* -------------------------------------------------------------------------- * Heap allocation raw functions @@ -793,7 +791,7 @@ void autoMemoryCollect(RedisModuleCtx *ctx) { case REDISMODULE_AM_STRING: decrRefCount(ptr); break; case REDISMODULE_AM_REPLY: RM_FreeCallReply(ptr); break; case REDISMODULE_AM_KEY: RM_CloseKey(ptr); break; - case REDISMODULE_AM_DICT: RM_FreeDict(ptr); break; + case REDISMODULE_AM_DICT: RM_FreeDict(NULL,ptr); break; } } ctx->flags |= REDISMODULE_CTX_AUTO_MEMORY; @@ -4368,15 +4366,16 @@ int RM_GetTimerInfo(RedisModuleCtx *ctx, RedisModuleTimerID id, uint64_t *remain */ RedisModuleDict *RM_CreateDict(RedisModuleCtx *ctx) { struct RedisModuleDict *d = zmalloc(sizeof(*d)); - d->ctx = ctx; d->rax = raxNew(); if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_DICT,d); return d; } -/* Free a dictionary created with RM_CreateDict(). */ -void RM_FreeDict(RedisModuleDict *d) { - if (d->ctx != NULL) autoMemoryFreed(d->ctx,REDISMODULE_AM_DICT,d); +/* Free a dictionary created with RM_CreateDict(). You need to pass the + * context pointer 'ctx' only if the dictionary was created using the + * context instead of passing NULL. */ +void RM_FreeDict(RedisModuleCtx *ctx, RedisModuleDict *d) { + if (ctx != NULL) autoMemoryFreed(ctx,REDISMODULE_AM_DICT,d); raxFree(d->rax); zfree(d); }