summaryrefslogtreecommitdiff
path: root/src/modules/API.md
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/API.md')
-rw-r--r--src/modules/API.md1329
1 files changed, 1329 insertions, 0 deletions
diff --git a/src/modules/API.md b/src/modules/API.md
new file mode 100644
index 0000000..e90429e
--- /dev/null
+++ b/src/modules/API.md
@@ -0,0 +1,1329 @@
+# Modules API reference
+
+## `RM_Alloc`
+
+ void *RM_Alloc(size_t bytes);
+
+Use like malloc(). Memory allocated with this function is reported in
+Redis INFO memory, used for keys eviction according to maxmemory settings
+and in general is taken into account as memory allocated by Redis.
+You should avoid using malloc().
+
+## `RM_Calloc`
+
+ void *RM_Calloc(size_t nmemb, size_t size);
+
+Use like calloc(). Memory allocated with this function is reported in
+Redis INFO memory, used for keys eviction according to maxmemory settings
+and in general is taken into account as memory allocated by Redis.
+You should avoid using calloc() directly.
+
+## `RM_Realloc`
+
+ void* RM_Realloc(void *ptr, size_t bytes);
+
+Use like realloc() for memory obtained with `RedisModule_Alloc()`.
+
+## `RM_Free`
+
+ void RM_Free(void *ptr);
+
+Use like free() for memory obtained by `RedisModule_Alloc()` and
+`RedisModule_Realloc()`. However you should never try to free with
+`RedisModule_Free()` memory allocated with malloc() inside your module.
+
+## `RM_Strdup`
+
+ char *RM_Strdup(const char *str);
+
+Like strdup() but returns memory allocated with `RedisModule_Alloc()`.
+
+## `RM_PoolAlloc`
+
+ void *RM_PoolAlloc(RedisModuleCtx *ctx, size_t bytes);
+
+Return heap allocated memory that will be freed automatically when the
+module callback function returns. Mostly suitable for small allocations
+that are short living and must be released when the callback returns
+anyway. The returned memory is aligned to the architecture word size
+if at least word size bytes are requested, otherwise it is just
+aligned to the next power of two, so for example a 3 bytes request is
+4 bytes aligned while a 2 bytes request is 2 bytes aligned.
+
+There is no realloc style function since when this is needed to use the
+pool allocator is not a good idea.
+
+The function returns NULL if `bytes` is 0.
+
+## `RM_GetApi`
+
+ int RM_GetApi(const char *funcname, void **targetPtrPtr);
+
+Lookup the requested module API and store the function pointer into the
+target pointer. The function returns `REDISMODULE_ERR` if there is no such
+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.
+
+## `RM_IsKeysPositionRequest`
+
+ int RM_IsKeysPositionRequest(RedisModuleCtx *ctx);
+
+Return non-zero if a module command, that was declared with the
+flag "getkeys-api", is called in a special way to get the keys positions
+and not to get executed. Otherwise zero is returned.
+
+## `RM_KeyAtPos`
+
+ void RM_KeyAtPos(RedisModuleCtx *ctx, int pos);
+
+When a module command is called in order to obtain the position of
+keys, since it was flagged as "getkeys-api" during the registration,
+the command implementation checks for this special call using the
+`RedisModule_IsKeysPositionRequest()` API and uses this function in
+order to report keys, like in the following example:
+
+ if (`RedisModule_IsKeysPositionRequest(ctx))` {
+ `RedisModule_KeyAtPos(ctx`,1);
+ `RedisModule_KeyAtPos(ctx`,2);
+ }
+
+ Note: in the example below the get keys API would not be needed since
+ keys are at fixed positions. This interface is only used for commands
+ with a more complex structure.
+
+## `RM_CreateCommand`
+
+ int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc cmdfunc, const char *strflags, int firstkey, int lastkey, int keystep);
+
+Register a new command in the Redis server, that will be handled by
+calling the function pointer 'func' using the RedisModule calling
+convention. The function returns `REDISMODULE_ERR` if the specified command
+name is already busy or a set of invalid flags were passed, otherwise
+`REDISMODULE_OK` is returned and the new command is registered.
+
+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`.
+
+The set of flags 'strflags' specify the behavior of the command, and should
+be passed as a C string compoesd of space separated words, like for
+example "write deny-oom". The set of flags are:
+
+* **"write"**: The command may modify the data set (it may also read
+ from it).
+* **"readonly"**: The command returns data from keys but never writes.
+* **"admin"**: The command is an administrative command (may change
+ replication or perform similar tasks).
+* **"deny-oom"**: The command may use additional memory and should be
+ denied during out of memory conditions.
+* **"deny-script"**: Don't allow this command in Lua scripts.
+* **"allow-loading"**: Allow this command while the server is loading data.
+ Only commands not interacting with the data set
+ should be allowed to run in this mode. If not sure
+ don't use this flag.
+* **"pubsub"**: The command publishes things on Pub/Sub channels.
+* **"random"**: The command may have different outputs even starting
+ from the same input arguments and key values.
+* **"allow-stale"**: The command is allowed to run on slaves that don't
+ serve stale data. Don't use if you don't know what
+ this means.
+* **"no-monitor"**: Don't propoagate the command on monitor. Use this if
+ the command has sensible data among the arguments.
+* **"fast"**: The command time complexity is not greater
+ than O(log(N)) where N is the size of the collection or
+ anything else representing the normal scalability
+ issue with the command.
+* **"getkeys-api"**: The command implements the interface to return
+ the arguments that are keys. Used when start/stop/step
+ is not enough because of the command syntax.
+* **"no-cluster"**: The command should not register in Redis Cluster
+ since is not designed to work with it because, for
+ example, is unable to report the position of the
+ keys, programmatically creates key names, or any
+ other reason.
+
+## `RM_SetModuleAttribs`
+
+ void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int apiver);
+
+Called by `RM_Init()` to setup the `ctx->module` structure.
+
+This is an internal function, Redis modules developers don't need
+to use it.
+
+## `RM_Milliseconds`
+
+ long long RM_Milliseconds(void);
+
+Return the current UNIX time in milliseconds.
+
+## `RM_AutoMemory`
+
+ void RM_AutoMemory(RedisModuleCtx *ctx);
+
+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.
+
+## `RM_CreateString`
+
+ RedisModuleString *RM_CreateString(RedisModuleCtx *ctx, const char *ptr, size_t len);
+
+Create a new module string object. The returned string must be freed
+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.
+
+## `RM_CreateStringPrintf`
+
+ RedisModuleString *RM_CreateStringPrintf(RedisModuleCtx *ctx, const char *fmt, ...);
+
+Create a new module string object from a printf format and arguments.
+The returned string must be freed with `RedisModule_FreeString()`, unless
+automatic memory is enabled.
+
+The string is created using the sds formatter function sdscatvprintf().
+
+## `RM_CreateStringFromLongLong`
+
+ RedisModuleString *RM_CreateStringFromLongLong(RedisModuleCtx *ctx, long long ll);
+
+Like `RedisModule_CreatString()`, but creates a string starting from a long long
+integer instead of taking a buffer and its length.
+
+The returned string must be released with `RedisModule_FreeString()` or by
+enabling automatic memory management.
+
+## `RM_CreateStringFromString`
+
+ RedisModuleString *RM_CreateStringFromString(RedisModuleCtx *ctx, const RedisModuleString *str);
+
+Like `RedisModule_CreatString()`, but creates a string starting from another
+RedisModuleString.
+
+The returned string must be released with `RedisModule_FreeString()` or by
+enabling automatic memory management.
+
+## `RM_FreeString`
+
+ void RM_FreeString(RedisModuleCtx *ctx, RedisModuleString *str);
+
+Free a module string object obtained with one of the Redis modules API calls
+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.
+
+## `RM_RetainString`
+
+ void RM_RetainString(RedisModuleCtx *ctx, RedisModuleString *str);
+
+Every call to this function, will make the string 'str' requiring
+an additional call to `RedisModule_FreeString()` in order to really
+free the string. Note that the automatic freeing of the string obtained
+enabling modules automatic memory management counts for one
+`RedisModule_FreeString()` call (it is just executed automatically).
+
+Normally you want to call this function when, at the same time
+the following conditions are true:
+
+1) You have automatic memory management enabled.
+2) You want to create string objects.
+3) Those string objects you create need to live *after* the callback
+ function(for example a command implementation) creating them returns.
+
+Usually you want this in order to store the created string object
+into your own data structure, for example when implementing a new data
+type.
+
+Note that when memory management is turned off, you don't need
+any call to RetainString() since creating a string will always result
+into a string that lives after the callback function returns, if
+no FreeString() call is performed.
+
+## `RM_StringPtrLen`
+
+ const char *RM_StringPtrLen(const RedisModuleString *str, size_t *len);
+
+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.
+
+## `RM_StringToLongLong`
+
+ int RM_StringToLongLong(const RedisModuleString *str, long long *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
+as a valid, strict long long (no spaces before/after), `REDISMODULE_ERR`
+is returned.
+
+## `RM_StringToDouble`
+
+ int RM_StringToDouble(const RedisModuleString *str, double *d);
+
+Convert the string into a double, storing it at `*d`.
+Returns `REDISMODULE_OK` on success or `REDISMODULE_ERR` if the string is
+not a valid string representation of a double value.
+
+## `RM_StringCompare`
+
+ int RM_StringCompare(RedisModuleString *a, RedisModuleString *b);
+
+Compare two string objects, returning -1, 0 or 1 respectively if
+a < b, a == b, a > b. Strings are compared byte by byte as two
+binary blobs without any encoding care / collation attempt.
+
+## `RM_StringAppendBuffer`
+
+ int RM_StringAppendBuffer(RedisModuleCtx *ctx, RedisModuleString *str, const char *buf, size_t len);
+
+Append the specified buffere to the string 'str'. The string must be a
+string created by the user that is referenced only a single time, otherwise
+`REDISMODULE_ERR` is returend and the operation is not performed.
+
+## `RM_WrongArity`
+
+ int RM_WrongArity(RedisModuleCtx *ctx);
+
+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)`;
+
+## `RM_ReplyWithLongLong`
+
+ int RM_ReplyWithLongLong(RedisModuleCtx *ctx, long long ll);
+
+Send an integer reply to the client, with the specified long long value.
+The function always returns `REDISMODULE_OK`.
+
+## `RM_ReplyWithError`
+
+ int RM_ReplyWithError(RedisModuleCtx *ctx, const char *err);
+
+Reply with the error 'err'.
+
+Note that 'err' must contain all the error, including
+the initial error code. The function only provides the initial "-", so
+the usage is, for example:
+
+ `RM_ReplyWithError(ctx`,"ERR Wrong Type");
+
+and not just:
+
+ `RM_ReplyWithError(ctx`,"Wrong Type");
+
+The function always returns `REDISMODULE_OK`.
+
+## `RM_ReplyWithSimpleString`
+
+ int RM_ReplyWithSimpleString(RedisModuleCtx *ctx, const char *msg);
+
+Reply with a simple string (+... \r\n in RESP protocol). This replies
+are suitable only when sending a small non-binary string with small
+overhead, like "OK" or similar replies.
+
+The function always returns `REDISMODULE_OK`.
+
+## `RM_ReplyWithArray`
+
+ int RM_ReplyWithArray(RedisModuleCtx *ctx, long len);
+
+Reply with an array type of 'len' elements. However 'len' other calls
+to `ReplyWith*` style functions must follow in order to emit the elements
+of the array.
+
+When producing arrays with a number of element that is not known beforehand
+the function can be called with the special count
+`REDISMODULE_POSTPONED_ARRAY_LEN`, and the actual number of elements can be
+later set with `RedisModule_ReplySetArrayLength()` (which will set the
+latest "open" count if there are multiple ones).
+
+The function always returns `REDISMODULE_OK`.
+
+## `RM_ReplySetArrayLength`
+
+ void RM_ReplySetArrayLength(RedisModuleCtx *ctx, long len);
+
+When `RedisModule_ReplyWithArray()` is used with the argument
+`REDISMODULE_POSTPONED_ARRAY_LEN`, because we don't know beforehand the number
+of items we are going to output as elements of the array, this function
+will take care to set the array length.
+
+Since it is possible to have multiple array replies pending with unknown
+length, this function guarantees to always set the latest array length
+that was created in a postponed way.
+
+For example in order to output an array like [1,[10,20,30]] we
+could write:
+
+ `RedisModule_ReplyWithArray(ctx`,`REDISMODULE_POSTPONED_ARRAY_LEN`);
+ `RedisModule_ReplyWithLongLong(ctx`,1);
+ `RedisModule_ReplyWithArray(ctx`,`REDISMODULE_POSTPONED_ARRAY_LEN`);
+ `RedisModule_ReplyWithLongLong(ctx`,10);
+ `RedisModule_ReplyWithLongLong(ctx`,20);
+ `RedisModule_ReplyWithLongLong(ctx`,30);
+ `RedisModule_ReplySetArrayLength(ctx`,3); // Set len of 10,20,30 array.
+ `RedisModule_ReplySetArrayLength(ctx`,2); // Set len of top array
+
+Note that in the above example there is no reason to postpone the array
+length, since we produce a fixed number of elements, but in the practice
+the code may use an interator or other ways of creating the output so
+that is not easy to calculate in advance the number of elements.
+
+## `RM_ReplyWithStringBuffer`
+
+ int RM_ReplyWithStringBuffer(RedisModuleCtx *ctx, const char *buf, size_t len);
+
+Reply with a bulk string, taking in input a C buffer pointer and length.
+
+The function always returns `REDISMODULE_OK`.
+
+## `RM_ReplyWithString`
+
+ int RM_ReplyWithString(RedisModuleCtx *ctx, RedisModuleString *str);
+
+Reply with a bulk string, taking in input a RedisModuleString object.
+
+The function always returns `REDISMODULE_OK`.
+
+## `RM_ReplyWithNull`
+
+ int RM_ReplyWithNull(RedisModuleCtx *ctx);
+
+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`.
+
+## `RM_ReplyWithCallReply`
+
+ int RM_ReplyWithCallReply(RedisModuleCtx *ctx, RedisModuleCallReply *reply);
+
+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`.
+
+## `RM_ReplyWithDouble`
+
+ int RM_ReplyWithDouble(RedisModuleCtx *ctx, double d);
+
+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`.
+
+## `RM_Replicate`
+
+ int RM_Replicate(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...);
+
+Replicate the specified command and arguments to slaves and AOF, as effect
+of execution of the calling command implementation.
+
+The replicated commands are always wrapped into the MULTI/EXEC that
+contains all the commands replicated in a given module command
+execution. However the commands replicated with `RedisModule_Call()`
+are the first items, the ones replicated with `RedisModule_Replicate()`
+will all follow before the EXEC.
+
+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.
+
+## `RM_ReplicateVerbatim`
+
+ int RM_ReplicateVerbatim(RedisModuleCtx *ctx);
+
+This function will replicate the command exactly as it was invoked
+by the client. Note that this function will not wrap the command into
+a MULTI/EXEC stanza, so it should not be mixed with other replication
+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`.
+
+## `RM_GetClientId`
+
+ unsigned long long RM_GetClientId(RedisModuleCtx *ctx);
+
+Return the ID of the current client calling the currently active module
+command. The returned ID has a few guarantees:
+
+1. The ID is different for each different client, so if the same client
+ executes a module command multiple times, it can be recognized as
+ having the same ID, otherwise the ID will be different.
+2. The ID increases monotonically. Clients connecting to the server later
+ are guaranteed to get IDs greater than any past ID previously seen.
+
+Valid IDs are from 1 to 2^64-1. If 0 is returned it means there is no way
+to fetch the ID in the context the function was currently called.
+
+## `RM_GetSelectedDb`
+
+ int RM_GetSelectedDb(RedisModuleCtx *ctx);
+
+Return the currently selected DB.
+
+## `RM_SelectDb`
+
+ int RM_SelectDb(RedisModuleCtx *ctx, int newid);
+
+Change the currently selected DB. Returns an error if the id
+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.
+
+## `RM_OpenKey`
+
+ void *RM_OpenKey(RedisModuleCtx *ctx, robj *keyname, int mode);
+
+Return an handle representing a Redis key, so that it is possible
+to call other APIs with the key handle as argument to perform
+operations on the key.
+
+The return value is the handle repesenting the key, that must be
+closed with `RM_CloseKey()`.
+
+If the key does not exist and WRITE mode is requested, the handle
+is still returned, since it is possible to perform operations on
+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
+key does not exist, NULL is returned. However it is still safe to
+call `RedisModule_CloseKey()` and `RedisModule_KeyType()` on a NULL
+value.
+
+## `RM_CloseKey`
+
+ void RM_CloseKey(RedisModuleKey *key);
+
+Close a key handle.
+
+## `RM_KeyType`
+
+ int RM_KeyType(RedisModuleKey *key);
+
+Return the type of the key. If the key pointer is NULL then
+`REDISMODULE_KEYTYPE_EMPTY` is returned.
+
+## `RM_ValueLength`
+
+ size_t RM_ValueLength(RedisModuleKey *key);
+
+Return the length of the value associated with the key.
+For strings this is the length of the string. For all the other types
+is the number of elements (just counting keys for hashes).
+
+If the key pointer is NULL or the key is empty, zero is returned.
+
+## `RM_DeleteKey`
+
+ int RM_DeleteKey(RedisModuleKey *key);
+
+If the key is open for writing, remove it, and setup the key to
+accept new writes as an empty key (that will be created on demand).
+On success `REDISMODULE_OK` is returned. If the key is not open for
+writing `REDISMODULE_ERR` is returned.
+
+## `RM_GetExpire`
+
+ mstime_t RM_GetExpire(RedisModuleKey *key);
+
+Return the key expire value, as milliseconds of remaining TTL.
+If no TTL is associated with the key or if the key is empty,
+`REDISMODULE_NO_EXPIRE` is returned.
+
+## `RM_SetExpire`
+
+ int RM_SetExpire(RedisModuleKey *key, mstime_t expire);
+
+Set a new expire for the key. If the special expire
+`REDISMODULE_NO_EXPIRE` is set, the expire is cancelled if there was
+one (the same as the PERSIST command).
+
+Note that the expire must be provided as a positive integer representing
+the number of milliseconds of TTL the key should have.
+
+The function returns `REDISMODULE_OK` on success or `REDISMODULE_ERR` if
+the key was not open for writing or is an empty key.
+
+## `RM_StringSet`
+
+ int RM_StringSet(RedisModuleKey *key, RedisModuleString *str);
+
+If the key is open for writing, set the specified string 'str' as the
+value of the key, deleting the old value if any.
+On success `REDISMODULE_OK` is returned. If the key is not open for
+writing or there is an active iterator, `REDISMODULE_ERR` is returned.
+
+## `RM_StringDMA`
+
+ char *RM_StringDMA(RedisModuleKey *key, size_t *len, int mode);
+
+Prepare the key associated string value for DMA access, and returns
+a pointer and size (by reference), that the user can use to read or
+modify the string in-place accessing it directly via pointer.
+
+The 'mode' is composed by bitwise OR-ing the following flags:
+
+`REDISMODULE_READ` -- Read access
+`REDISMODULE_WRITE` -- Write access
+
+If the DMA is not requested for writing, the pointer returned should
+only be accessed in a read-only fashion.
+
+On error (wrong type) NULL is returned.
+
+DMA access rules:
+
+1. No other key writing function should be called since the moment
+the pointer is obtained, for all the time we want to use DMA access
+to read or modify the string.
+
+2. Each time `RM_StringTruncate()` is called, to continue with the DMA
+access, `RM_StringDMA()` should be called again to re-obtain
+a new pointer and length.
+
+3. If the returned pointer is not NULL, but the length is zero, no
+byte can be touched (the string is empty, or the key itself is empty)
+so a `RM_StringTruncate()` call should be used if there is to enlarge
+the string, and later call StringDMA() again to get the pointer.
+
+## `RM_StringTruncate`
+
+ int RM_StringTruncate(RedisModuleKey *key, size_t newlen);
+
+If the string is open for writing and is of string type, resize it, padding
+with zero bytes if the new length is greater than the old one.
+
+After this call, `RM_StringDMA()` must be called again to continue
+DMA access with the new pointer.
+
+The function returns `REDISMODULE_OK` on success, and `REDISMODULE_ERR` on
+error, that is, the key is not open for writing, is not a string
+or resizing for more than 512 MB is requested.
+
+If the key is empty, a string key is created with the new string value
+unless the new length value requested is zero.
+
+## `RM_ListPush`
+
+ int RM_ListPush(RedisModuleKey *key, int where, RedisModuleString *ele);
+
+Push an element into a list, on head or tail depending on 'where' argumnet.
+If the key pointer is about an empty key opened for writing, the key
+is created. On error (key opened for read-only operations or of the wrong
+type) `REDISMODULE_ERR` is returned, otherwise `REDISMODULE_OK` is returned.
+
+## `RM_ListPop`
+
+ RedisModuleString *RM_ListPop(RedisModuleKey *key, int where);
+
+Pop an element from the list, and returns it as a module string object
+that the user should be free with `RM_FreeString()` or by enabling
+automatic memory. 'where' specifies if the element should be popped from
+head or tail. The command returns NULL if:
+1) The list is empty.
+2) The key was not open for writing.
+3) The key is not a list.
+
+## `RM_ZsetAddFlagsToCoreFlags`
+
+ int RM_ZsetAddFlagsToCoreFlags(int flags);
+
+Conversion from/to public flags of the Modules API and our private flags,
+so that we have everything decoupled.
+
+## `RM_ZsetAddFlagsFromCoreFlags`
+
+ int RM_ZsetAddFlagsFromCoreFlags(int flags);
+
+See previous function comment.
+
+## `RM_ZsetAdd`
+
+ int RM_ZsetAdd(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr);
+
+Add a new element into a sorted set, with the specified 'score'.
+If the element already exists, the score is updated.
+
+A new sorted set is created at value if the key is an empty open key
+setup for writing.
+
+Additional flags can be passed to the function via a pointer, the flags
+are both used to receive input and to communicate state when the function
+returns. 'flagsptr' can be NULL if no special flags are used.
+
+The input flags are:
+
+`REDISMODULE_ZADD_XX`: Element must already exist. Do nothing otherwise.
+`REDISMODULE_ZADD_NX`: Element must not exist. Do nothing otherwise.
+
+The output flags are:
+
+`REDISMODULE_ZADD_ADDED`: The new element was added to the sorted set.
+`REDISMODULE_ZADD_UPDATED`: The score of the element was updated.
+`REDISMODULE_ZADD_NOP`: No operation was performed because XX or NX flags.
+
+On success the function returns `REDISMODULE_OK`. On the following errors
+`REDISMODULE_ERR` is returned:
+
+* The key was not opened for writing.
+* The key is of the wrong type.
+* 'score' double value is not a number (NaN).
+
+## `RM_ZsetIncrby`
+
+ int RM_ZsetIncrby(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr, double *newscore);
+
+This function works exactly like `RM_ZsetAdd()`, but instead of setting
+a new score, the score of the existing element is incremented, or if the
+element does not already exist, it is added assuming the old score was
+zero.
+
+The input and output flags, and the return value, have the same exact
+meaning, with the only difference that this function will return
+`REDISMODULE_ERR` even when 'score' is a valid double number, but adding it
+to the existing score resuts into a NaN (not a number) condition.
+
+This function has an additional field 'newscore', if not NULL is filled
+with the new score of the element after the increment, if no error
+is returned.
+
+## `RM_ZsetRem`
+
+ int RM_ZsetRem(RedisModuleKey *key, RedisModuleString *ele, int *deleted);
+
+Remove the specified element from the sorted set.
+The function returns `REDISMODULE_OK` on success, and `REDISMODULE_ERR`
+on one of the following conditions:
+
+* The key was not opened for writing.
+* The key is of the wrong type.
+
+The return value does NOT indicate the fact the element was really
+removed (since it existed) or not, just if the function was executed
+with success.
+
+In order to know if the element was removed, the additional argument
+'deleted' must be passed, that populates the integer by reference
+setting it to 1 or 0 depending on the outcome of the operation.
+The 'deleted' argument can be NULL if the caller is not interested
+to know if the element was really removed.
+
+Empty keys will be handled correctly by doing nothing.
+
+## `RM_ZsetScore`
+
+ int RM_ZsetScore(RedisModuleKey *key, RedisModuleString *ele, double *score);
+
+On success retrieve the double score associated at the sorted set element
+'ele' and returns `REDISMODULE_OK`. Otherwise `REDISMODULE_ERR` is returned
+to signal one of the following conditions:
+
+* There is no such element 'ele' in the sorted set.
+* The key is not a sorted set.
+* The key is an open empty key.
+
+## `RM_ZsetRangeStop`
+
+ void RM_ZsetRangeStop(RedisModuleKey *key);
+
+Stop a sorted set iteration.
+
+## `RM_ZsetRangeEndReached`
+
+ int RM_ZsetRangeEndReached(RedisModuleKey *key);
+
+Return the "End of range" flag value to signal the end of the iteration.
+
+## `RM_ZsetFirstInScoreRange`
+
+ int RM_ZsetFirstInScoreRange(RedisModuleKey *key, double min, double max, int minex, int maxex);
+
+Setup a sorted set iterator seeking the first element in the specified
+range. Returns `REDISMODULE_OK` if the iterator was correctly initialized
+otherwise `REDISMODULE_ERR` is returned in the following conditions:
+
+1. The value stored at key is not a sorted set or the key is empty.
+
+The range is specified according to the two double values 'min' and 'max'.
+Both can be infinite using the following two macros:
+
+`REDISMODULE_POSITIVE_INFINITE` for positive infinite value
+`REDISMODULE_NEGATIVE_INFINITE` for negative infinite value
+
+'minex' and 'maxex' parameters, if true, respectively setup a range
+where the min and max value are exclusive (not included) instead of
+inclusive.
+
+## `RM_ZsetLastInScoreRange`
+
+ int RM_ZsetLastInScoreRange(RedisModuleKey *key, double min, double max, int minex, int maxex);
+
+Exactly like `RedisModule_ZsetFirstInScoreRange()` but the last element of
+the range is selected for the start of the iteration instead.
+
+## `RM_ZsetFirstInLexRange`
+
+ int RM_ZsetFirstInLexRange(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max);
+
+Setup a sorted set iterator seeking the first element in the specified
+lexicographical range. Returns `REDISMODULE_OK` if the iterator was correctly
+initialized otherwise `REDISMODULE_ERR` is returned in the
+following conditions:
+
+1. The value stored at key is not a sorted set or the key is empty.
+2. The lexicographical range 'min' and 'max' format is invalid.
+
+'min' and 'max' should be provided as two RedisModuleString objects
+in the same format as the parameters passed to the ZRANGEBYLEX command.
+The function does not take ownership of the objects, so they can be released
+ASAP after the iterator is setup.
+
+## `RM_ZsetLastInLexRange`
+
+ int RM_ZsetLastInLexRange(RedisModuleKey *key, RedisModuleString *min, RedisModuleString *max);
+
+Exactly like `RedisModule_ZsetFirstInLexRange()` but the last element of
+the range is selected for the start of the iteration instead.
+
+## `RM_ZsetRangeCurrentElement`
+
+ RedisModuleString *RM_ZsetRangeCurrentElement(RedisModuleKey *key, double *score);
+
+Return the current sorted set element of an active sorted set iterator
+or NULL if the range specified in the iterator does not include any
+element.
+
+## `RM_ZsetRangeNext`
+
+ int RM_ZsetRangeNext(RedisModuleKey *key);
+
+Go to the next element of the sorted set iterator. Returns 1 if there was
+a next element, 0 if we are already at the latest element or the range
+does not include any item at all.
+
+## `RM_ZsetRangePrev`
+
+ int RM_ZsetRangePrev(RedisModuleKey *key);
+
+Go to the previous element of the sorted set iterator. Returns 1 if there was
+a previous element, 0 if we are already at the first element or the range
+does not include any item at all.
+
+## `RM_HashSet`
+
+ int RM_HashSet(RedisModuleKey *key, int flags, ...);
+
+Set the field of the specified hash field to the specified value.
+If the key is an empty key open for writing, it is created with an empty
+hash value, in order to set the specified field.
+
+The function is variadic and the user must specify pairs of field
+names and values, both as RedisModuleString pointers (unless the
+CFIELD option is set, see later).
+
+Example to set the hash argv[1] to the value argv[2]:
+
+ `RedisModule_HashSet(key`,`REDISMODULE_HASH_NONE`,argv[1],argv[2],NULL);
+
+The function can also be used in order to delete fields (if they exist)
+by setting them to the specified value of `REDISMODULE_HASH_DELETE`:
+
+ `RedisModule_HashSet(key`,`REDISMODULE_HASH_NONE`,argv[1],
+ `REDISMODULE_HASH_DELETE`,NULL);
+
+The behavior of the command changes with the specified flags, that can be
+set to `REDISMODULE_HASH_NONE` if no special behavior is needed.
+
+`REDISMODULE_HASH_NX`: The operation is performed only if the field was not
+ already existing in the hash.
+`REDISMODULE_HASH_XX`: The operation is performed only if the field was
+ already existing, so that a new value could be
+ associated to an existing filed, but no new fields
+ are created.
+`REDISMODULE_HASH_CFIELDS`: The field names passed are null terminated C
+ strings instead of RedisModuleString objects.
+
+Unless NX is specified, the command overwrites the old field value with
+the new one.
+
+When using `REDISMODULE_HASH_CFIELDS`, field names are reported using
+normal C strings, so for example to delete the field "foo" the following
+code can be used:
+
+ `RedisModule_HashSet(key`,`REDISMODULE_HASH_CFIELDS`,"foo",
+ `REDISMODULE_HASH_DELETE`,NULL);
+
+Return value:
+
+The number of fields updated (that may be less than the number of fields
+specified because of the XX or NX options).
+
+In the following case the return value is always zero:
+
+* The key was not open for writing.
+* The key was associated with a non Hash value.
+
+## `RM_HashGet`
+
+ int RM_HashGet(RedisModuleKey *key, int flags, ...);
+
+Get fields from an hash value. This function is called using a variable
+number of arguments, alternating a field name (as a StringRedisModule
+pointer) with a pointer to a StringRedisModule pointer, that is set to the
+value of the field if the field exist, or NULL if the field did not exist.
+At the end of the field/value-ptr pairs, NULL must be specified as last
+argument to signal the end of the arguments in the variadic function.
+
+This is an example usage:
+
+ RedisModuleString *first, *second;
+ `RedisModule_HashGet(mykey`,`REDISMODULE_HASH_NONE`,argv[1],&first,
+ argv[2],&second,NULL);
+
+As with `RedisModule_HashSet()` the behavior of the command can be specified
+passing flags different than `REDISMODULE_HASH_NONE`:
+
+`REDISMODULE_HASH_CFIELD`: field names as null terminated C strings.
+
+`REDISMODULE_HASH_EXISTS`: instead of setting the value of the field
+expecting a RedisModuleString pointer to pointer, the function just
+reports if the field esists or not and expects an integer pointer
+as the second element of each pair.
+
+Example of `REDISMODULE_HASH_CFIELD`:
+
+ RedisModuleString *username, *hashedpass;
+ `RedisModule_HashGet(mykey`,"username",&username,"hp",&hashedpass, NULL);
+
+Example of `REDISMODULE_HASH_EXISTS`:
+
+ int exists;
+ `RedisModule_HashGet(mykey`,argv[1],&exists,NULL);
+
+The function returns `REDISMODULE_OK` on success and `REDISMODULE_ERR` if
+the key is not an hash value.
+
+Memory management:
+
+The returned RedisModuleString objects should be released with
+`RedisModule_FreeString()`, or by enabling automatic memory management.
+
+## `RM_FreeCallReply_Rec`
+
+ void RM_FreeCallReply_Rec(RedisModuleCallReply *reply, int freenested);
+
+Free a Call reply and all the nested replies it contains if it's an
+array.
+
+## `RM_FreeCallReply`
+
+ void RM_FreeCallReply(RedisModuleCallReply *reply);
+
+Wrapper for the recursive free reply function. This is needed in order
+to have the first level function to return on nested replies, but only
+if called by the module API.
+
+## `RM_CallReplyType`
+
+ int RM_CallReplyType(RedisModuleCallReply *reply);
+
+Return the reply type.
+
+## `RM_CallReplyLength`
+
+ size_t RM_CallReplyLength(RedisModuleCallReply *reply);
+
+Return the reply type length, where applicable.
+
+## `RM_CallReplyArrayElement`
+
+ RedisModuleCallReply *RM_CallReplyArrayElement(RedisModuleCallReply *reply, size_t idx);
+
+Return the 'idx'-th nested call reply element of an array reply, or NULL
+if the reply type is wrong or the index is out of range.
+
+## `RM_CallReplyInteger`
+
+ long long RM_CallReplyInteger(RedisModuleCallReply *reply);
+
+Return the long long of an integer reply.
+
+## `RM_CallReplyStringPtr`
+
+ const char *RM_CallReplyStringPtr(RedisModuleCallReply *reply, size_t *len);
+
+Return the pointer and length of a string or error reply.
+
+## `RM_CreateStringFromCallReply`
+
+ RedisModuleString *RM_CreateStringFromCallReply(RedisModuleCallReply *reply);
+
+Return a new string object from a call reply of type string, error or
+integer. Otherwise (wrong reply type) return NULL.
+
+## `RM_Call`
+
+ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const char *fmt, ...);
+
+Exported API to call any Redis command from modules.
+On success a RedisModuleCallReply object is returned, otherwise
+NULL is returned and errno is set to the following values:
+
+EINVAL: command non existing, wrong arity, wrong format specifier.
+EPERM: operation in Cluster instance with key in non local slot.
+
+## `RM_CallReplyProto`
+
+ const char *RM_CallReplyProto(RedisModuleCallReply *reply, size_t *len);
+
+Return a pointer, and a length, to the protocol returned by the command
+that returned the reply object.
+
+## `RM_CreateDataType`
+
+ moduleType *RM_CreateDataType(RedisModuleCtx *ctx, const char *name, int encver, void *typemethods_ptr);
+
+Register a new data type exported by the module. The parameters are the
+following. Please for in depth documentation check the modules API
+documentation, especially the TYPES.md file.
+
+* **name**: A 9 characters data type name that MUST be unique in the Redis
+ Modules ecosystem. Be creative... and there will be no collisions. Use
+ the charset A-Z a-z 9-0, plus the two "-_" characters. A good
+ idea is to use, for example `<typename>-<vendor>`. For example
+ "tree-AntZ" may mean "Tree data structure by @antirez". To use both
+ lower case and upper case letters helps in order to prevent collisions.
+* **encver**: Encoding version, which is, the version of the serialization
+ that a module used in order to persist data. As long as the "name"
+ matches, the RDB loading will be dispatched to the type callbacks
+ whatever 'encver' is used, however the module can understand if
+ the encoding it must load are of an older version of the module.
+ For example the module "tree-AntZ" initially used encver=0. Later
+ after an upgrade, it started to serialize data in a different format
+ and to register the type with encver=1. However this module may
+ still load old data produced by an older version if the rdb_load
+ callback is able to check the encver value and act accordingly.
+ The encver must be a positive value between 0 and 1023.
+* **typemethods_ptr** is a pointer to a RedisModuleTypeMethods structure
+ that should be populated with the methods callbacks and structure
+ version, like in the following example:
+
+ RedisModuleTypeMethods tm = {
+ .version = `REDISMODULE_TYPE_METHOD_VERSION`,
+ .rdb_load = myType_RDBLoadCallBack,
+ .rdb_save = myType_RDBSaveCallBack,
+ .aof_rewrite = myType_AOFRewriteCallBack,
+ .free = myType_FreeCallBack,
+
+ // Optional fields
+ .digest = myType_DigestCallBack,
+ .mem_usage = myType_MemUsageCallBack,
+ }
+
+* **rdb_load**: A callback function pointer that loads data from RDB files.
+* **rdb_save**: A callback function pointer that saves data to RDB files.
+* **aof_rewrite**: A callback function pointer that rewrites data as commands.
+* **digest**: A callback function pointer that is used for `DEBUG DIGEST`.
+* **mem_usage**: A callback function pointer that is used for `MEMORY`.
+* **free**: A callback function pointer that can free a type value.
+
+The **digest* and **mem_usage** methods should currently be omitted since
+they are not yet implemented inside the Redis modules core.
+
+Note: the module name "AAAAAAAAA" is reserved and produces an error, it
+happens to be pretty lame as well.
+
+If there is already a module registering a type with the same name,
+and if the module name or encver is invalid, NULL is returned.
+Otherwise the new type is registered into Redis, and a reference of
+type RedisModuleType is returned: the caller of the function should store
+this reference into a gobal variable to make future use of it in the
+modules type API, since a single module may register multiple types.
+Example code fragment:
+
+ static RedisModuleType *BalancedTreeType;
+
+ int `RedisModule_OnLoad(RedisModuleCtx` *ctx) {
+ // some code here ...
+ BalancedTreeType = `RM_CreateDataType(`...);
+ }
+
+## `RM_ModuleTypeSetValue`
+
+ int RM_ModuleTypeSetValue(RedisModuleKey *key, moduleType *mt, void *value);
+
+If the key is open for writing, set the specified module type object
+as the value of the key, deleting the old value if any.
+On success `REDISMODULE_OK` is returned. If the key is not open for
+writing or there is an active iterator, `REDISMODULE_ERR` is returned.
+
+## `RM_ModuleTypeGetType`
+
+ moduleType *RM_ModuleTypeGetType(RedisModuleKey *key);
+
+Assuming `RedisModule_KeyType()` returned `REDISMODULE_KEYTYPE_MODULE` on
+the key, returns the moduel type pointer of the value stored at key.
+
+If the key is NULL, is not associated with a module type, or is empty,
+then NULL is returned instead.
+
+## `RM_ModuleTypeGetValue`
+
+ void *RM_ModuleTypeGetValue(RedisModuleKey *key);
+
+Assuming `RedisModule_KeyType()` returned `REDISMODULE_KEYTYPE_MODULE` on
+the key, returns the module type low-level value stored at key, as
+it was set by the user via `RedisModule_ModuleTypeSet()`.
+
+If the key is NULL, is not associated with a module type, or is empty,
+then NULL is returned instead.
+
+## `RM_SaveUnsigned`
+
+ void RM_SaveUnsigned(RedisModuleIO *io, uint64_t value);
+
+Save an unsigned 64 bit value into the RDB file. This function should only
+be called in the context of the rdb_save method of modules implementing new
+data types.
+
+## `RM_LoadUnsigned`
+
+ uint64_t RM_LoadUnsigned(RedisModuleIO *io);
+
+Load an unsigned 64 bit value from the RDB file. This function should only
+be called in the context of the rdb_load method of modules implementing
+new data types.
+
+## `RM_SaveSigned`
+
+ void RM_SaveSigned(RedisModuleIO *io, int64_t value);
+
+Like `RedisModule_SaveUnsigned()` but for signed 64 bit values.
+
+## `RM_LoadSigned`
+
+ int64_t RM_LoadSigned(RedisModuleIO *io);
+
+Like `RedisModule_LoadUnsigned()` but for signed 64 bit values.
+
+## `RM_SaveString`
+
+ void RM_SaveString(RedisModuleIO *io, RedisModuleString *s);
+
+In the context of the rdb_save method of a module type, saves a
+string into the RDB file taking as input a RedisModuleString.
+
+The string can be later loaded with `RedisModule_LoadString()` or
+other Load family functions expecting a serialized string inside
+the RDB file.
+
+## `RM_SaveStringBuffer`
+
+ void RM_SaveStringBuffer(RedisModuleIO *io, const char *str, size_t len);
+
+Like `RedisModule_SaveString()` but takes a raw C pointer and length
+as input.
+
+## `RM_LoadString`
+
+ RedisModuleString *RM_LoadString(RedisModuleIO *io);
+
+In the context of the rdb_load method of a module data type, loads a string
+from the RDB file, that was previously saved with `RedisModule_SaveString()`
+functions family.
+
+The returned string is a newly allocated RedisModuleString object, and
+the user should at some point free it with a call to `RedisModule_FreeString()`.
+
+If the data structure does not store strings as RedisModuleString objects,
+the similar function `RedisModule_LoadStringBuffer()` could be used instead.
+
+## `RM_LoadStringBuffer`
+
+ char *RM_LoadStringBuffer(RedisModuleIO *io, size_t *lenptr);
+
+Like `RedisModule_LoadString()` but returns an heap allocated string that
+was allocated with `RedisModule_Alloc()`, and can be resized or freed with
+`RedisModule_Realloc()` or `RedisModule_Free()`.
+
+The size of the string is stored at '*lenptr' if not NULL.
+The returned string is not automatically NULL termianted, it is loaded
+exactly as it was stored inisde the RDB file.
+
+## `RM_SaveDouble`
+
+ void RM_SaveDouble(RedisModuleIO *io, double value);
+
+In the context of the rdb_save method of a module data type, saves a double
+value to the RDB file. The double can be a valid number, a NaN or infinity.
+It is possible to load back the value with `RedisModule_LoadDouble()`.
+
+## `RM_LoadDouble`
+
+ double RM_LoadDouble(RedisModuleIO *io);
+
+In the context of the rdb_save method of a module data type, loads back the
+double value saved by `RedisModule_SaveDouble()`.
+
+## `RM_SaveFloat`
+
+ void RM_SaveFloat(RedisModuleIO *io, float value);
+
+In the context of the rdb_save method of a module data type, saves a float
+value to the RDB file. The float can be a valid number, a NaN or infinity.
+It is possible to load back the value with `RedisModule_LoadFloat()`.
+
+## `RM_LoadFloat`
+
+ float RM_LoadFloat(RedisModuleIO *io);
+
+In the context of the rdb_save method of a module data type, loads back the
+float value saved by `RedisModule_SaveFloat()`.
+
+## `RM_EmitAOF`
+
+ void RM_EmitAOF(RedisModuleIO *io, const char *cmdname, const char *fmt, ...);
+
+Emits a command into the AOF during the AOF rewriting process. This function
+is only called in the context of the aof_rewrite method of data types exported
+by a module. The command works exactly like `RedisModule_Call()` in the way
+the parameters are passed, but it does not return anything as the error
+handling is performed by Redis itself.
+
+## `RM_LogRaw`
+
+ void RM_LogRaw(RedisModule *module, const char *levelstr, const char *fmt, va_list ap);
+
+This is the low level function implementing both:
+
+ `RM_Log()`
+ `RM_LogIOError()`
+
+## `RM_Log`
+
+ void RM_Log(RedisModuleCtx *ctx, const char *levelstr, const char *fmt, ...);
+
+/*
+Produces a log message to the standard Redis log, the format accepts
+printf-alike specifiers, while level is a string describing the log
+level to use when emitting the log, and must be one of the following:
+
+* "debug"
+* "verbose"
+* "notice"
+* "warning"
+
+If the specified log level is invalid, verbose is used by default.
+There is a fixed limit to the length of the log line this function is able
+to emit, this limti is not specified but is guaranteed to be more than
+a few lines of text.
+
+## `RM_LogIOError`
+
+ void RM_LogIOError(RedisModuleIO *io, const char *levelstr, const char *fmt, ...);
+
+Log errors from RDB / AOF serialization callbacks.
+
+This function should be used when a callback is returning a critical
+error to the caller since cannot load or save the data for some
+critical reason.
+
+## `RM_BlockClient`
+
+ RedisModuleBlockedClient *RM_BlockClient(RedisModuleCtx *ctx, RedisModuleCmdFunc reply_callback, RedisModuleCmdFunc timeout_callback, void (*free_privdata)(void*), long long timeout_ms);
+
+Block a client in the context of a blocking command, returning an handle
+which will be used, later, in order to block the client with a call to
+`RedisModule_UnblockClient()`. The arguments specify callback functions
+and a timeout after which the client is unblocked.
+
+The callbacks are called in the following contexts:
+
+reply_callback: called after a successful `RedisModule_UnblockClient()` call
+ in order to reply to the client and unblock it.
+reply_timeout: called when the timeout is reached in order to send an
+ error to the client.
+free_privdata: called in order to free the privata data that is passed
+ by `RedisModule_UnblockClient()` call.
+
+## `RM_UnblockClient`
+
+ int RM_UnblockClient(RedisModuleBlockedClient *bc, void *privdata);
+
+Unblock a client blocked by ``RedisModule_BlockedClient``. This will trigger
+the reply callbacks to be called in order to reply to the client.
+The 'privdata' argument will be accessible by the reply callback, so
+the caller of this function can pass any value that is needed in order to
+actually reply to the client.
+
+A common usage for 'privdata' is a thread that computes something that
+needs to be passed to the client, included but not limited some slow
+to compute reply or some reply obtained via networking.
+
+Note: this function can be called from threads spawned by the module.
+
+## `RM_AbortBlock`
+
+ int RM_AbortBlock(RedisModuleBlockedClient *bc);
+
+Abort a blocked client blocking operation: the client will be unblocked
+without firing the reply callback.
+
+## `RM_IsBlockedReplyRequest`
+
+ int RM_IsBlockedReplyRequest(RedisModuleCtx *ctx);
+
+Return non-zero if a module command was called in order to fill the
+reply for a blocked client.
+
+## `RM_IsBlockedTimeoutRequest`
+
+ int RM_IsBlockedTimeoutRequest(RedisModuleCtx *ctx);
+
+Return non-zero if a module command was called in order to fill the
+reply for a blocked client that timed out.
+
+## `RM_GetBlockedClientPrivateData`
+
+ void *RM_GetBlockedClientPrivateData(RedisModuleCtx *ctx);
+
+Get the privata data set by `RedisModule_UnblockClient()`
+