Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
0fd6d548
Commit
0fd6d548
authored
Apr 20, 2016
by
antirez
Browse files
Modules: fix top comments to be user-facing doc quality. About 33% done.
parent
f362f7a1
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/module.c
View file @
0fd6d548
...
@@ -116,7 +116,7 @@ typedef struct RedisModuleCallReply RedisModuleCallReply;
...
@@ -116,7 +116,7 @@ typedef struct RedisModuleCallReply RedisModuleCallReply;
void RM_FreeCallReply(RedisModuleCallReply *reply);
void RM_FreeCallReply(RedisModuleCallReply *reply);
void RM_CloseKey(RedisModuleKey *key);
void RM_CloseKey(RedisModuleKey *key);
void
RM_A
utoMemoryCollect
(
RedisModuleCtx
*
ctx
);
void
a
utoMemoryCollect(RedisModuleCtx *ctx);
robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int *argcp, int *flags, va_list ap);
robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int *argcp, int *flags, va_list ap);
void moduleReplicateMultiIfNeeded(RedisModuleCtx *ctx);
void moduleReplicateMultiIfNeeded(RedisModuleCtx *ctx);
void RM_ZsetRangeStop(RedisModuleKey *key);
void RM_ZsetRangeStop(RedisModuleKey *key);
...
@@ -204,7 +204,10 @@ int moduleDelKeyIfEmpty(RedisModuleKey *key) {
...
@@ -204,7 +204,10 @@ int moduleDelKeyIfEmpty(RedisModuleKey *key) {
/* Lookup the requested module API and store the function pointer into the
/* Lookup the requested module API and store the function pointer into the
* target pointer. The function returns REDISMODULE_ERR if there is no such
* target pointer. The function returns REDISMODULE_ERR if there is no such
* named API, otherwise REDISMODULE_OK. */
* named API, otherwise REDISMODULE_OK.
*
* This function is not meant to be used by modules developer, it is only
* used implicitly by including redismodule.h. */
int RM_GetApi(const char *funcname, void **targetPtrPtr) {
int RM_GetApi(const char *funcname, void **targetPtrPtr) {
dictEntry *he = dictFind(server.moduleapi, funcname);
dictEntry *he = dictFind(server.moduleapi, funcname);
if (!he) return REDISMODULE_ERR;
if (!he) return REDISMODULE_ERR;
...
@@ -221,7 +224,7 @@ void RedisModuleCommandDispatcher(client *c) {
...
@@ -221,7 +224,7 @@ void RedisModuleCommandDispatcher(client *c) {
ctx.module = cp->module;
ctx.module = cp->module;
ctx.client = c;
ctx.client = c;
cp->func(&ctx,(void**)c->argv,c->argc);
cp->func(&ctx,(void**)c->argv,c->argc);
RM_A
utoMemoryCollect
(
&
ctx
);
a
utoMemoryCollect(&ctx);
preventCommandPropagation(c);
preventCommandPropagation(c);
/* Handle the replication of the final EXEC, since whatever a command
/* Handle the replication of the final EXEC, since whatever a command
...
@@ -238,7 +241,18 @@ void RedisModuleCommandDispatcher(client *c) {
...
@@ -238,7 +241,18 @@ void RedisModuleCommandDispatcher(client *c) {
/* Register a new command in the Redis server, that will be handled by
/* Register a new command in the Redis server, that will be handled by
* calling the function pointer 'func' using the RedisModule calling
* calling the function pointer 'func' using the RedisModule calling
* convention. The function returns REDISMODULE_ERR if the specified command
* convention. The function returns REDISMODULE_ERR if the specified command
* name is already busy, otherwise REDISMODULE_OK. */
* name is already busy, otherwise REDISMODULE_OK is returned.
*
* This function must be called during the initialization of the module
* inside the RedisModule_OnLoad() function. Calling this function outside
* of the initialization function is not defined.
*
* The command function type is the following:
*
* int MyCommand_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc);
*
* And is supposed to always return REDISMODULE_OK.
*/
int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc) {
int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc) {
struct redisCommand *rediscmd;
struct redisCommand *rediscmd;
RedisModuleCommandProxy *cp;
RedisModuleCommandProxy *cp;
...
@@ -252,7 +266,7 @@ int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc c
...
@@ -252,7 +266,7 @@ int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc c
/* Create a command "proxy", which is a structure that is referenced
/* Create a command "proxy", which is a structure that is referenced
* in the command table, so that the generic command that works as
* in the command table, so that the generic command that works as
* bin
i
dng between modules and Redis, can know what function to call
* bind
i
ng between modules and Redis, can know what function to call
* and what the module is.
* and what the module is.
*
*
* Note that we use the Redis command table 'getkeys_proc' in order to
* Note that we use the Redis command table 'getkeys_proc' in order to
...
@@ -276,7 +290,10 @@ int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc c
...
@@ -276,7 +290,10 @@ int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc c
return REDISMODULE_OK;
return REDISMODULE_OK;
}
}
/* Called by RM_Init() to setup the ctx->module structure. */
/* Called by RM_Init() to setup the ctx->module structure.
*
* This is an internal function, Redis modules developers don't need
* to use it. */
void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int apiver){
void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int apiver){
RedisModule *module;
RedisModule *module;
...
@@ -292,13 +309,16 @@ void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int api
...
@@ -292,13 +309,16 @@ void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int api
* Automatic memory management for modules
* Automatic memory management for modules
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
/* Enable auto memory. */
/* Enable automatic memory management. See API.md for more information.
*
* The function must be called as the first function of a command implementation
* that wants to use automatic memory. */
void RM_AutoMemory(RedisModuleCtx *ctx) {
void RM_AutoMemory(RedisModuleCtx *ctx) {
ctx->flags |= REDISMODULE_CTX_AUTO_MEMORY;
ctx->flags |= REDISMODULE_CTX_AUTO_MEMORY;
}
}
/* Add a new object to release automatically when the callback returns. */
/* Add a new object to release automatically when the callback returns. */
void
RM_A
utoMemoryAdd
(
RedisModuleCtx
*
ctx
,
int
type
,
void
*
ptr
)
{
void
a
utoMemoryAdd(RedisModuleCtx *ctx, int type, void *ptr) {
if (!(ctx->flags & REDISMODULE_CTX_AUTO_MEMORY)) return;
if (!(ctx->flags & REDISMODULE_CTX_AUTO_MEMORY)) return;
if (ctx->amqueue_used == ctx->amqueue_len) {
if (ctx->amqueue_used == ctx->amqueue_len) {
ctx->amqueue_len *= 2;
ctx->amqueue_len *= 2;
...
@@ -312,7 +332,7 @@ void RM_AutoMemoryAdd(RedisModuleCtx *ctx, int type, void *ptr) {
...
@@ -312,7 +332,7 @@ void RM_AutoMemoryAdd(RedisModuleCtx *ctx, int type, void *ptr) {
/* Mark an object as freed in the auto release queue, so that users can still
/* Mark an object as freed in the auto release queue, so that users can still
* free things manually if they want. */
* free things manually if they want. */
void
RM_A
utoMemoryFreed
(
RedisModuleCtx
*
ctx
,
int
type
,
void
*
ptr
)
{
void
a
utoMemoryFreed(RedisModuleCtx *ctx, int type, void *ptr) {
if (!(ctx->flags & REDISMODULE_CTX_AUTO_MEMORY)) return;
if (!(ctx->flags & REDISMODULE_CTX_AUTO_MEMORY)) return;
int j;
int j;
...
@@ -329,7 +349,7 @@ void RM_AutoMemoryFreed(RedisModuleCtx *ctx, int type, void *ptr) {
...
@@ -329,7 +349,7 @@ void RM_AutoMemoryFreed(RedisModuleCtx *ctx, int type, void *ptr) {
}
}
/* Release all the objects in queue. */
/* Release all the objects in queue. */
void
RM_A
utoMemoryCollect
(
RedisModuleCtx
*
ctx
)
{
void
a
utoMemoryCollect(RedisModuleCtx *ctx) {
if (!(ctx->flags & REDISMODULE_CTX_AUTO_MEMORY)) return;
if (!(ctx->flags & REDISMODULE_CTX_AUTO_MEMORY)) return;
/* Clear the AUTO_MEMORY flag from the context, otherwise the functions
/* Clear the AUTO_MEMORY flag from the context, otherwise the functions
* we call to free the resources, will try to scan the auto release
* we call to free the resources, will try to scan the auto release
...
@@ -355,37 +375,49 @@ void RM_AutoMemoryCollect(RedisModuleCtx *ctx) {
...
@@ -355,37 +375,49 @@ void RM_AutoMemoryCollect(RedisModuleCtx *ctx) {
* String objects APIs
* String objects APIs
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
/* Create a new module string object. Must be freed with
/* Create a new module string object. The returned string must be freed
* RM_FreeString(), unless automatic memory is enabled. */
* with RedisModule_FreeString(), unless automatic memory is enabled.
*
* The string is created by copying the `len` bytes starting
* at `ptr`. No reference is retained to the passed buffer. */
RedisModuleString *RM_CreateString(RedisModuleCtx *ctx, const char *ptr, size_t len)
RedisModuleString *RM_CreateString(RedisModuleCtx *ctx, const char *ptr, size_t len)
{
{
RedisModuleString *o = createStringObject(ptr,len);
RedisModuleString *o = createStringObject(ptr,len);
RM_A
utoMemoryAdd
(
ctx
,
REDISMODULE_AM_STRING
,
o
);
a
utoMemoryAdd(ctx,REDISMODULE_AM_STRING,o);
return o;
return o;
}
}
/* Like RM_CreatString, but creates a string starting from a long long
/* Like RedisModule_CreatString(), but creates a string starting from a long long
* integer instea of taking a buffer and length. */
* integer instead of taking a buffer and its length.
*
* The returned string must be released with RedisModule_FreeString() or by
* enabling automatic memory management. */
RedisModuleString *RM_CreateStringFromLongLong(RedisModuleCtx *ctx, long long ll) {
RedisModuleString *RM_CreateStringFromLongLong(RedisModuleCtx *ctx, long long ll) {
char buf[LONG_STR_SIZE];
char buf[LONG_STR_SIZE];
size_t len = ll2string(buf,sizeof(buf),ll);
size_t len = ll2string(buf,sizeof(buf),ll);
return RM_CreateString(ctx,buf,len);
return RM_CreateString(ctx,buf,len);
}
}
/* Free a module string object obtained with one of the Redis API calls
/* Free a module string object obtained with one of the Redis modules API calls
* that return new string objects. */
* that return new string objects.
*
* It is possible to call this function even when automatic memory management
* is enabled. In that case the string will be released ASAP and removed
* from the pool of string to release at the end. */
void RM_FreeString(RedisModuleCtx *ctx, RedisModuleString *str) {
void RM_FreeString(RedisModuleCtx *ctx, RedisModuleString *str) {
decrRefCount(str);
decrRefCount(str);
RM_A
utoMemoryFreed
(
ctx
,
REDISMODULE_AM_STRING
,
str
);
a
utoMemoryFreed(ctx,REDISMODULE_AM_STRING,str);
}
}
/* Return the string pointer and length. */
/* Given a string module object, this function returns the string pointer
* and length of the string. The returned pointer and length should only
* be used for read only accesses and never modified. */
const char *RM_StringPtrLen(RedisModuleString *str, size_t *len) {
const char *RM_StringPtrLen(RedisModuleString *str, size_t *len) {
if (len) *len = sdslen(str->ptr);
if (len) *len = sdslen(str->ptr);
return str->ptr;
return str->ptr;
}
}
/*
Turn
the string into a long long, storing it at *ll.
/*
Convert
the string into a long long
integer
, storing it at *ll.
* Returns REDISMODULE_OK on success. If the string can't be parsed
* Returns REDISMODULE_OK on success. If the string can't be parsed
* as a valid, strict long long (no spaces before/after), REDISMODULE_ERR
* as a valid, strict long long (no spaces before/after), REDISMODULE_ERR
* is returned. */
* is returned. */
...
@@ -394,7 +426,7 @@ int RM_StringToLongLong(RedisModuleString *str, long long *ll) {
...
@@ -394,7 +426,7 @@ int RM_StringToLongLong(RedisModuleString *str, long long *ll) {
REDISMODULE_ERR;
REDISMODULE_ERR;
}
}
/*
Turn
the string into a double, storing it at *d.
/*
Convert
the string into a double, storing it at *d.
* Returns REDISMODULE_OK on success or REDISMODULE_ERR if the string is
* Returns REDISMODULE_OK on success or REDISMODULE_ERR if the string is
* not a valid string representation of a double value. */
* not a valid string representation of a double value. */
int RM_StringToDouble(RedisModuleString *str, double *d) {
int RM_StringToDouble(RedisModuleString *str, double *d) {
...
@@ -412,7 +444,13 @@ int RM_StringToDouble(RedisModuleString *str, double *d) {
...
@@ -412,7 +444,13 @@ int RM_StringToDouble(RedisModuleString *str, double *d) {
* return RM_ReplyWithLongLong(ctx,mycount);
* return RM_ReplyWithLongLong(ctx,mycount);
* -------------------------------------------------------------------------- */
* -------------------------------------------------------------------------- */
/* Send an error about the number of arguments given to the command. */
/* Send an error about the number of arguments given to the command,
* citing the command name in the error message.
*
* Example:
*
* if (argc != 3) return RedisModule_WrongArity(ctx);
*/
int RM_WrongArity(RedisModuleCtx *ctx) {
int RM_WrongArity(RedisModuleCtx *ctx) {
addReplyErrorFormat(ctx->client,
addReplyErrorFormat(ctx->client,
"wrong number of arguments for '%s' command",
"wrong number of arguments for '%s' command",
...
@@ -420,7 +458,7 @@ int RM_WrongArity(RedisModuleCtx *ctx) {
...
@@ -420,7 +458,7 @@ int RM_WrongArity(RedisModuleCtx *ctx) {
return REDISMODULE_OK;
return REDISMODULE_OK;
}
}
/* Send an integer reply with the specified long long value.
/* Send an integer reply
to the client,
with the specified long long value.
* The function always returns REDISMODULE_OK. */
* The function always returns REDISMODULE_OK. */
int RM_ReplyWithLongLong(RedisModuleCtx *ctx, long long ll) {
int RM_ReplyWithLongLong(RedisModuleCtx *ctx, long long ll) {
addReplyLongLong(ctx->client,ll);
addReplyLongLong(ctx->client,ll);
...
@@ -428,8 +466,9 @@ int RM_ReplyWithLongLong(RedisModuleCtx *ctx, long long ll) {
...
@@ -428,8 +466,9 @@ int RM_ReplyWithLongLong(RedisModuleCtx *ctx, long long ll) {
}
}
/* Reply with an error or simple string (status message). Used to implement
/* Reply with an error or simple string (status message). Used to implement
* ReplyWithSimpleString() and ReplyWithError(). */
* ReplyWithSimpleString() and ReplyWithError().
int
RM_ReplyWithStatus
(
RedisModuleCtx
*
ctx
,
const
char
*
msg
,
char
*
prefix
)
{
* The function always returns REDISMODULE_OK. */
int replyWithStatus(RedisModuleCtx *ctx, const char *msg, char *prefix) {
sds strmsg = sdsnewlen(prefix,1);
sds strmsg = sdsnewlen(prefix,1);
strmsg = sdscat(strmsg,msg);
strmsg = sdscat(strmsg,msg);
strmsg = sdscatlen(strmsg,"\r\n",2);
strmsg = sdscatlen(strmsg,"\r\n",2);
...
@@ -443,57 +482,80 @@ int RM_ReplyWithStatus(RedisModuleCtx *ctx, const char *msg, char *prefix) {
...
@@ -443,57 +482,80 @@ int RM_ReplyWithStatus(RedisModuleCtx *ctx, const char *msg, char *prefix) {
* the initial error code. The function only provides the initial "-", so
* the initial error code. The function only provides the initial "-", so
* the usage is, for example:
* the usage is, for example:
*
*
* RM_ReplyWithError(ctx,"ERR Wrong Type");
*
RM_ReplyWithError(ctx,"ERR Wrong Type");
*
*
* and not just:
* and not just:
*
*
* RM_ReplyWithError(ctx,"Wrong Type");
* RM_ReplyWithError(ctx,"Wrong Type");
*
* The function always returns REDISMODULE_OK.
*/
*/
int RM_ReplyWithError(RedisModuleCtx *ctx, const char *err) {
int RM_ReplyWithError(RedisModuleCtx *ctx, const char *err) {
return
RM_R
eplyWithStatus
(
ctx
,
err
,
"-"
);
return
r
eplyWithStatus(ctx,err,"-");
}
}
/* Reply with a simple string (+... \r\n in RESP protocol). This replies
/* Reply with a simple string (+... \r\n in RESP protocol). This replies
* are suitalbe only when sending a small non-binary string wiht small
* are suitable only when sending a small non-binary string with small
* overhead, like "OK" or similar replies. */
* overhead, like "OK" or similar replies.
*
* The function always returns REDISMODULE_OK. */
int RM_ReplyWithSimpleString(RedisModuleCtx *ctx, const char *msg) {
int RM_ReplyWithSimpleString(RedisModuleCtx *ctx, const char *msg) {
return
RM_R
eplyWithStatus
(
ctx
,
msg
,
"+"
);
return
r
eplyWithStatus(ctx,msg,"+");
}
}
/* Reply with an array type of 'len' elements. However 'len' other calls
/* Reply with an array type of 'len' elements. However 'len' other calls
* to ReplyWith* style functions must follow in order to emit the elements
* to ReplyWith* style functions must follow in order to emit the elements
* of the array. */
* of the array.
*
* The function always returns REDISMODULE_OK. */
int RM_ReplyWithArray(RedisModuleCtx *ctx, int len) {
int RM_ReplyWithArray(RedisModuleCtx *ctx, int len) {
addReplyMultiBulkLen(ctx->client,len);
addReplyMultiBulkLen(ctx->client,len);
return REDISMODULE_OK;
return REDISMODULE_OK;
}
}
/* Reply with a bulk string, taking in input a C buffer pointer and length. */
/* Reply with a bulk string, taking in input a C buffer pointer and length.
*
* The function always returns REDISMODULE_OK. */
int RM_ReplyWithStringBuffer(RedisModuleCtx *ctx, const char *buf, size_t len) {
int RM_ReplyWithStringBuffer(RedisModuleCtx *ctx, const char *buf, size_t len) {
addReplyBulkCBuffer(ctx->client,(char*)buf,len);
addReplyBulkCBuffer(ctx->client,(char*)buf,len);
return REDISMODULE_OK;
return REDISMODULE_OK;
}
}
/* Reply with a bulk string, taking in input a RedisModuleString object. */
/* Reply with a bulk string, taking in input a RedisModuleString object.
*
* The function always returns REDISMODULE_OK. */
int RM_ReplyWithString(RedisModuleCtx *ctx, RedisModuleString *str) {
int RM_ReplyWithString(RedisModuleCtx *ctx, RedisModuleString *str) {
addReplyBulk(ctx->client,str);
addReplyBulk(ctx->client,str);
return REDISMODULE_OK;
return REDISMODULE_OK;
}
}
/* Reply with NULL. */
/* Reply to the client with a NULL. In the RESP protocol a NULL is encoded
* as the string "$-1\r\n".
*
* The function always returns REDISMODULE_OK. */
int RM_ReplyWithNull(RedisModuleCtx *ctx) {
int RM_ReplyWithNull(RedisModuleCtx *ctx) {
addReply(ctx->client,shared.nullbulk);
addReply(ctx->client,shared.nullbulk);
return REDISMODULE_OK;
return REDISMODULE_OK;
}
}
/* Reply exactly what a Redis command returned us with RM_Call(). */
/* Reply exactly what a Redis command returned us with RedisModule_Call().
* This function is useful when we use RedisModule_Call() in order to
* execute some command, as we want to reply to the client exactly the
* same reply we obtained by the command.
*
* The function always returns REDISMODULE_OK. */
int RM_ReplyWithCallReply(RedisModuleCtx *ctx, RedisModuleCallReply *reply) {
int RM_ReplyWithCallReply(RedisModuleCtx *ctx, RedisModuleCallReply *reply) {
sds proto = sdsnewlen(reply->proto, reply->protolen);
sds proto = sdsnewlen(reply->proto, reply->protolen);
addReplySds(ctx->client,proto);
addReplySds(ctx->client,proto);
return REDISMODULE_OK;
return REDISMODULE_OK;
}
}
/* Send a string reply obtained converting the double 'd' into a string. */
/* Send a string reply obtained converting the double 'd' into a bulk string.
* This function is basically equivalent to converting a double into
* a string into a C buffer, and then calling the function
* RedisModule_ReplyWithStringBuffer() with the buffer and length.
*
* The function always returns REDISMODULE_OK. */
int RM_ReplyWithDouble(RedisModuleCtx *ctx, double d) {
int RM_ReplyWithDouble(RedisModuleCtx *ctx, double d) {
addReplyDouble(ctx->client,d);
addReplyDouble(ctx->client,d);
return REDISMODULE_OK;
return REDISMODULE_OK;
...
@@ -515,13 +577,22 @@ void moduleReplicateMultiIfNeeded(RedisModuleCtx *ctx) {
...
@@ -515,13 +577,22 @@ void moduleReplicateMultiIfNeeded(RedisModuleCtx *ctx) {
/* Replicate the specified command and arguments to slaves and AOF, as effect
/* Replicate the specified command and arguments to slaves and AOF, as effect
* of execution of the calling command implementation.
* of execution of the calling command implementation.
*
*
* The replicated commands are always wrap
e
pd into the MULTI/EXEC that
* The replicated commands are always wrapp
e
d into the MULTI/EXEC that
* contains all the commands replicated in a given module command
* contains all the commands replicated in a given module command
* execution. However the commands replicated with R
M
_Call()
* execution. However the commands replicated with R
edisModule
_Call()
* are the first items, the ones replicated with R
M
_Replicate()
* are the first items, the ones replicated with R
edisModule
_Replicate()
* will all follow before the EXEC.
* will all follow before the EXEC.
*
*
* Modules should try to use one interface or the other. */
* Modules should try to use one interface or the other.
*
* This command follows exactly the same interface of RedisModule_Call(),
* so a set of format specifiers must be passed, followed by arguments
* matching the provided format specifiers.
*
* Please refer to RedisModule_Call() for more information.
*
* The command returns REDISMODULE_ERR if the format specifiers are invalid
* or the command name does not belong to a known command. */
int RM_Replicate(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...) {
int RM_Replicate(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...) {
struct redisCommand *cmd;
struct redisCommand *cmd;
robj **argv = NULL;
robj **argv = NULL;
...
@@ -549,9 +620,16 @@ int RM_Replicate(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...)
...
@@ -549,9 +620,16 @@ int RM_Replicate(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...)
}
}
/* This function will replicate the command exactly as it was invoked
/* This function will replicate the command exactly as it was invoked
* by the client.
T
his function will not wrap the command into
* by the client.
Note that t
his function will not wrap the command into
* a MULTI/EXEC stanza, so it should not be mixed with other replication
* a MULTI/EXEC stanza, so it should not be mixed with other replication
* commands. */
* commands.
*
* Basically this form of replication is useful when you want to propagate
* the command to the slaves and AOF file exactly as it was called, since
* the command can just be re-executed to deterministically re-create the
* new state starting from the old one.
*
* The function always returns REDISMODULE_OK. */
int RM_ReplicateVerbatim(RedisModuleCtx *ctx) {
int RM_ReplicateVerbatim(RedisModuleCtx *ctx) {
alsoPropagate(ctx->client->cmd,ctx->client->db->id,
alsoPropagate(ctx->client->cmd,ctx->client->db->id,
ctx->client->argv,ctx->client->argc,
ctx->client->argv,ctx->client->argc,
...
@@ -569,7 +647,15 @@ int RM_GetSelectedDb(RedisModuleCtx *ctx) {
...
@@ -569,7 +647,15 @@ int RM_GetSelectedDb(RedisModuleCtx *ctx) {
}
}
/* Change the currently selected DB. Returns an error if the id
/* Change the currently selected DB. Returns an error if the id
* is out of range. */
* is out of range.
*
* Note that the client will retain the currently selected DB even after
* the Redis command implemented by the module calling this function
* returns.
*
* If the module command wishes to change something in a different DB and
* returns back to the original one, it should call RedisModule_GetSelectedDb()
* before in order to restore the old DB number before returning. */
int RM_SelectDb(RedisModuleCtx *ctx, int newid) {
int RM_SelectDb(RedisModuleCtx *ctx, int newid) {
int retval = selectDb(ctx->client,newid);
int retval = selectDb(ctx->client,newid);
return (retval == C_OK) ? REDISMODULE_OK : REDISMODULE_ERR;
return (retval == C_OK) ? REDISMODULE_OK : REDISMODULE_ERR;
...
@@ -587,7 +673,7 @@ int RM_SelectDb(RedisModuleCtx *ctx, int newid) {
...
@@ -587,7 +673,7 @@ int RM_SelectDb(RedisModuleCtx *ctx, int newid) {
* a yet not existing key (that will be created, for example, after
* a yet not existing key (that will be created, for example, after
* a list push operation). If the mode is just READ instead, and the
* a list push operation). If the mode is just READ instead, and the
* key does not exist, NULL is returned. However it is still safe to
* key does not exist, NULL is returned. However it is still safe to
* call R
M
_CloseKey() and R
M
_KeyType() on a NULL
* call R
edisModule
_CloseKey() and R
edisModule
_KeyType() on a NULL
* value. */
* value. */
void *RM_OpenKey(RedisModuleCtx *ctx, robj *keyname, int mode) {
void *RM_OpenKey(RedisModuleCtx *ctx, robj *keyname, int mode) {
RedisModuleKey *kp;
RedisModuleKey *kp;
...
@@ -612,7 +698,7 @@ void *RM_OpenKey(RedisModuleCtx *ctx, robj *keyname, int mode) {
...
@@ -612,7 +698,7 @@ void *RM_OpenKey(RedisModuleCtx *ctx, robj *keyname, int mode) {
kp->iter = NULL;
kp->iter = NULL;
kp->mode = mode;
kp->mode = mode;
RM_ZsetRangeStop(kp);
RM_ZsetRangeStop(kp);
RM_A
utoMemoryAdd
(
ctx
,
REDISMODULE_AM_KEY
,
kp
);
a
utoMemoryAdd(ctx,REDISMODULE_AM_KEY,kp);
return (void*)kp;
return (void*)kp;
}
}
...
@@ -622,7 +708,7 @@ void RM_CloseKey(RedisModuleKey *key) {
...
@@ -622,7 +708,7 @@ void RM_CloseKey(RedisModuleKey *key) {
if (key->mode & REDISMODULE_WRITE) signalModifiedKey(key->db,key->key);
if (key->mode & REDISMODULE_WRITE) signalModifiedKey(key->db,key->key);
/* TODO: if (key->iter) RM_KeyIteratorStop(kp); */
/* TODO: if (key->iter) RM_KeyIteratorStop(kp); */
decrRefCount(key->key);
decrRefCount(key->key);
RM_A
utoMemoryFreed
(
key
->
ctx
,
REDISMODULE_AM_KEY
,
key
);
a
utoMemoryFreed(key->ctx,REDISMODULE_AM_KEY,key);
zfree(key);
zfree(key);
}
}
...
@@ -847,7 +933,7 @@ RedisModuleString *RM_ListPop(RedisModuleKey *key, int where) {
...
@@ -847,7 +933,7 @@ RedisModuleString *RM_ListPop(RedisModuleKey *key, int where) {
robj *decoded = getDecodedObject(ele);
robj *decoded = getDecodedObject(ele);
decrRefCount(ele);
decrRefCount(ele);
moduleDelKeyIfEmpty(key);
moduleDelKeyIfEmpty(key);
RM_A
utoMemoryAdd
(
key
->
ctx
,
REDISMODULE_AM_STRING
,
decoded
);
a
utoMemoryAdd(key->ctx,REDISMODULE_AM_STRING,decoded);
return decoded;
return decoded;
}
}
...
@@ -1088,7 +1174,7 @@ RedisModuleString *RM_ZsetRangeCurrentElement(RedisModuleKey *key, double *score
...
@@ -1088,7 +1174,7 @@ RedisModuleString *RM_ZsetRangeCurrentElement(RedisModuleKey *key, double *score
} else {
} else {
serverPanic("Unsupported zset encoding");
serverPanic("Unsupported zset encoding");
}
}
RM_A
utoMemoryAdd
(
key
->
ctx
,
REDISMODULE_AM_STRING
,
str
);
a
utoMemoryAdd(key->ctx,REDISMODULE_AM_STRING,str);
return str;
return str;
}
}
...
@@ -1363,7 +1449,7 @@ void RM_FreeCallReply_Rec(RedisModuleCallReply *reply, int freenested){
...
@@ -1363,7 +1449,7 @@ void RM_FreeCallReply_Rec(RedisModuleCallReply *reply, int freenested){
* if called by the module API. */
* if called by the module API. */
void RM_FreeCallReply(RedisModuleCallReply *reply) {
void RM_FreeCallReply(RedisModuleCallReply *reply) {
RM_FreeCallReply_Rec(reply,0);
RM_FreeCallReply_Rec(reply,0);
RM_A
utoMemoryFreed
(
reply
->
ctx
,
REDISMODULE_AM_REPLY
,
reply
);
a
utoMemoryFreed(reply->ctx,REDISMODULE_AM_REPLY,reply);
}
}
/* Return the reply type. */
/* Return the reply type. */
...
@@ -1572,7 +1658,7 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch
...
@@ -1572,7 +1658,7 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch
listDelNode(c->reply,listFirst(c->reply));
listDelNode(c->reply,listFirst(c->reply));
}
}
reply = moduleCreateCallReplyFromProto(ctx,proto);
reply = moduleCreateCallReplyFromProto(ctx,proto);
RM_A
utoMemoryAdd
(
ctx
,
REDISMODULE_AM_REPLY
,
reply
);
a
utoMemoryAdd(ctx,REDISMODULE_AM_REPLY,reply);
cleanup:
cleanup:
freeClient(c);
freeClient(c);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment