Modules: types doc updated to new API.

This commit is contained in:
antirez 2016-12-02 16:30:42 +01:00
parent 37b6e16ae1
commit 16cce320c4

View File

@ -47,23 +47,25 @@ be stored in the global variable.
#define MYTYPE_ENCODING_VERSION 0 #define MYTYPE_ENCODING_VERSION 0
int RedisModule_OnLoad(RedisModuleCtx *ctx) { int RedisModule_OnLoad(RedisModuleCtx *ctx) {
MyType = RedisModule_CreateDataType("MyType-AZ", MYTYPE_ENCODING_VERSION, RedisModuleTypeMethods tm = {
MyTypeRDBLoad, MyTypeRDBSave, MyTypeAOFRewrite, MyTypeDigest, .version = REDISMODULE_TYPE_METHOD_VERSION,
MyTypeFree); .rdb_load = MyTypeRDBLoad,
.rdb_save = MyTypeRDBSave,
.aof_rewrite = MyTypeAOFRewrite,
.free = MyTypeFree
};
MyType = RedisModule_CreateDataType("MyType-AZ",
MYTYPE_ENCODING_VERSION, &tm);
if (MyType == NULL) return REDISMODULE_ERR; if (MyType == NULL) return REDISMODULE_ERR;
} }
As you can see from the example above, a single API call is needed in order to As you can see from the example above, a single API call is needed in order to
register the new type. However a number of function pointers are passed as register the new type. However a number of function pointers are passed as
arguments. The prototype of `RedisModule_CreateDataType` is the following: arguments. Certain are optionals while some are mandatory. The above set
of methods *must* be passed, while `.digest` and `.mem_usage` are optional
moduleType *RedisModule_CreateDataType(RedisModuleCtx *ctx, and are currently not actually supported by the modules internals, so for
const char *name, int encver, now you can just ignore them.
moduleTypeLoadFunc rdb_load,
moduleTypeSaveFunc rdb_save,
moduleTypeRewriteFunc aof_rewrite,
moduleTypeDigestFunc digest,
moduleTypeFreeFunc free);
The `ctx` argument is the context that we receive in the `OnLoad` function. The `ctx` argument is the context that we receive in the `OnLoad` function.
The type `name` is a 9 character name in the character set that includes The type `name` is a 9 character name in the character set that includes
@ -74,6 +76,9 @@ ecosystem, so be creative, use both lower-case and upper case if it makes
sense, and try to use the convention of mixing the type name with the name sense, and try to use the convention of mixing the type name with the name
of the author of the module, to create a 9 character unique name. of the author of the module, to create a 9 character unique name.
**NOTE:** It is very important that the name is exactly 9 chars or the
registration of the type will fail. Read more to understand why.
For example if I'm building a *b-tree* data structure and my name is *antirez* For example if I'm building a *b-tree* data structure and my name is *antirez*
I'll call my type **btree1-az**. The name, converted to a 64 bit integer, I'll call my type **btree1-az**. The name, converted to a 64 bit integer,
is stored inside the RDB file when saving the type, and will be used when the is stored inside the RDB file when saving the type, and will be used when the
@ -95,12 +100,14 @@ there is data found for a different encoding version (and the encoding version
is passed as argument to `rdb_load`), so that the module can still load old is passed as argument to `rdb_load`), so that the module can still load old
RDB files. RDB files.
The remaining arguments `rdb_load`, `rdb_save`, `aof_rewrite`, `digest` and The last argument is a structure used in order to pass the type methods to the
`free` are all callbacks with the following prototypes and uses: registration function: `rdb_load`, `rdb_save`, `aof_rewrite`, `digest` and
`free` and `mem_usage` are all callbacks with the following prototypes and uses:
typedef void *(*RedisModuleTypeLoadFunc)(RedisModuleIO *rdb, int encver); typedef void *(*RedisModuleTypeLoadFunc)(RedisModuleIO *rdb, int encver);
typedef void (*RedisModuleTypeSaveFunc)(RedisModuleIO *rdb, void *value); typedef void (*RedisModuleTypeSaveFunc)(RedisModuleIO *rdb, void *value);
typedef void (*RedisModuleTypeRewriteFunc)(RedisModuleIO *aof, RedisModuleString *key, void *value); typedef void (*RedisModuleTypeRewriteFunc)(RedisModuleIO *aof, RedisModuleString *key, void *value);
typedef size_t (*RedisModuleTypeMemUsageFunc)(void *value);
typedef void (*RedisModuleTypeDigestFunc)(RedisModuleDigest *digest, void *value); typedef void (*RedisModuleTypeDigestFunc)(RedisModuleDigest *digest, void *value);
typedef void (*RedisModuleTypeFreeFunc)(void *value); typedef void (*RedisModuleTypeFreeFunc)(void *value);
@ -108,6 +115,7 @@ The remaining arguments `rdb_load`, `rdb_save`, `aof_rewrite`, `digest` and
* `rdb_save` is called when saving data to the RDB file. * `rdb_save` is called when saving data to the RDB file.
* `aof_rewrite` is called when the AOF is being rewritten, and the module needs to tell Redis what is the sequence of commands to recreate the content of a given key. * `aof_rewrite` is called when the AOF is being rewritten, and the module needs to tell Redis what is the sequence of commands to recreate the content of a given key.
* `digest` is called when `DEBUG DIGEST` is executed and a key holding this module type is found. Currently this is not yet implemented so the function ca be left empty. * `digest` is called when `DEBUG DIGEST` is executed and a key holding this module type is found. Currently this is not yet implemented so the function ca be left empty.
* `mem_usage` is called when the `MEMORY` command ask for the total memory consumed by a specific key, and is used in order to get the amount of bytes used by the module value.
* `free` is called when a key with the module native type is deleted via `DEL` or in any other mean, in order to let the module reclaim the memory associated with such a value. * `free` is called when a key with the module native type is deleted via `DEL` or in any other mean, in order to let the module reclaim the memory associated with such a value.
Ok, but *why* modules types require a 9 characters name? Ok, but *why* modules types require a 9 characters name?