mirror of
https://github.com/fluencelabs/redis
synced 2025-06-23 14:01:34 +00:00
Modules: support for modules native data types.
This commit is contained in:
88
src/server.h
88
src/server.h
@ -33,6 +33,7 @@
|
||||
#include "fmacros.h"
|
||||
#include "config.h"
|
||||
#include "solarisfixes.h"
|
||||
#include "rio.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -421,6 +422,90 @@ typedef long long mstime_t; /* millisecond time type. */
|
||||
#define OBJ_ZSET 3
|
||||
#define OBJ_HASH 4
|
||||
|
||||
/* The "module" object type is a special one that signals that the object
|
||||
* is one directly managed by a Redis module. In this case the value points
|
||||
* to a moduleValue struct, which contains the object value (which is only
|
||||
* handled by the module itself) and the RedisModuleType struct which lists
|
||||
* function pointers in order to serialize, deserialize, AOF-rewrite and
|
||||
* free the object.
|
||||
*
|
||||
* Inside the RDB file, module types are encoded as OBJ_MODULE followed
|
||||
* by a 64 bit module type ID, which has a 54 bits module-specific signature
|
||||
* in order to dispatch the loading to the right module, plus a 10 bits
|
||||
* encoding version. */
|
||||
#define OBJ_MODULE 5
|
||||
|
||||
/* Extract encver / signature from a module type ID. */
|
||||
#define REDISMODULE_TYPE_ENCVER_BITS 10
|
||||
#define REDISMODULE_TYPE_ENCVER_MASK ((1<<REDISMODULE_TYPE_ENCVER_BITS)-1)
|
||||
#define REDISMODULE_TYPE_ENCVER(id) (id & REDISMODULE_TYPE_ENCVER_MASK)
|
||||
#define REDISMODULE_TYPE_SIGN(id) ((id & ~((uint64_t)REDISMODULE_TYPE_ENCVER_MASK)) >>REDISMODULE_TYPE_ENCVER_BITS)
|
||||
|
||||
struct RedisModule;
|
||||
struct RedisModuleIO;
|
||||
struct RedisModuleDigest;
|
||||
struct redisObject;
|
||||
|
||||
/* Each module type implementation should export a set of methods in order
|
||||
* to serialize and deserialize the value in the RDB file, rewrite the AOF
|
||||
* log, create the digest for "DEBUG DIGEST", and free the value when a key
|
||||
* is deleted. */
|
||||
typedef void *(*moduleTypeLoadFunc)(struct RedisModuleIO *io, int encver);
|
||||
typedef void (*moduleTypeSaveFunc)(struct RedisModuleIO *io, void *value);
|
||||
typedef void (*moduleTypeRewriteFunc)(struct RedisModuleIO *io, struct redisObject *key, void *value);
|
||||
typedef void (*moduleTypeDigestFunc)(struct RedisModuleDigest *digest, void *value);
|
||||
typedef void (*moduleTypeFreeFunc)(void *value);
|
||||
|
||||
/* The module type, which is referenced in each value of a given type, defines
|
||||
* the methods and links to the module exporting the type. */
|
||||
typedef struct RedisModuleType {
|
||||
uint64_t id; /* Higher 54 bits of type ID + 10 lower bits of encoding ver. */
|
||||
struct RedisModule *module;
|
||||
moduleTypeLoadFunc rdb_load;
|
||||
moduleTypeSaveFunc rdb_save;
|
||||
moduleTypeRewriteFunc aof_rewrite;
|
||||
moduleTypeDigestFunc digest;
|
||||
moduleTypeFreeFunc free;
|
||||
char name[10]; /* 9 bytes name + null term. Charset: A-Z a-z 0-9 _- */
|
||||
} moduleType;
|
||||
|
||||
/* In Redis objects 'robj' structures of type OBJ_MODULE, the value pointer
|
||||
* is set to the following structure, referencing the moduleType structure
|
||||
* in order to work with the value, and at the same time providing a raw
|
||||
* pointer to the value, as created by the module commands operating with
|
||||
* the module type.
|
||||
*
|
||||
* So for example in order to free such a value, it is possible to use
|
||||
* the following code:
|
||||
*
|
||||
* if (robj->type == OBJ_MODULE) {
|
||||
* moduleValue *mt = robj->ptr;
|
||||
* mt->type->free(mt->value);
|
||||
* zfree(mt); // We need to release this in-the-middle struct as well.
|
||||
* }
|
||||
*/
|
||||
typedef struct moduleValue {
|
||||
moduleType *type;
|
||||
void *value;
|
||||
} moduleValue;
|
||||
|
||||
/* This is a wrapper for the 'rio' streams used inside rdb.c in Redis, so that
|
||||
* the user does not have to take the total count of the written bytes nor
|
||||
* to care about error conditions. */
|
||||
typedef struct RedisModuleIO {
|
||||
size_t bytes; /* Bytes read / written so far. */
|
||||
rio *rio; /* Rio stream. */
|
||||
moduleType *type; /* Module type doing the operation. */
|
||||
int error; /* True if error condition happened. */
|
||||
} RedisModuleIO;
|
||||
|
||||
#define moduleInitIOContext(iovar,mtype,rioptr) do { \
|
||||
iovar.rio = rioptr; \
|
||||
iovar.type = mtype; \
|
||||
iovar.bytes = 0; \
|
||||
iovar.error = 0; \
|
||||
} while(0);
|
||||
|
||||
/* Objects encoding. Some kind of objects like Strings and Hashes can be
|
||||
* internally represented in multiple ways. The 'encoding' field of the object
|
||||
* is set to one of this fields for this object. */
|
||||
@ -1074,6 +1159,8 @@ void moduleInitModulesSystem(void);
|
||||
int moduleLoad(const char *path);
|
||||
void moduleLoadFromQueue(void);
|
||||
int *moduleGetCommandKeysViaAPI(struct redisCommand *cmd, robj **argv, int argc, int *numkeys);
|
||||
moduleType *moduleTypeLookupModuleByID(uint64_t id);
|
||||
void moduleTypeNameByID(char *name, uint64_t moduleid);
|
||||
|
||||
/* Utils */
|
||||
long long ustime(void);
|
||||
@ -1207,6 +1294,7 @@ robj *createIntsetObject(void);
|
||||
robj *createHashObject(void);
|
||||
robj *createZsetObject(void);
|
||||
robj *createZsetZiplistObject(void);
|
||||
robj *createModuleObject(moduleType *mt, void *value);
|
||||
int getLongFromObjectOrReply(client *c, robj *o, long *target, const char *msg);
|
||||
int checkType(client *c, robj *o, int type);
|
||||
int getLongLongFromObjectOrReply(client *c, robj *o, long long *target, const char *msg);
|
||||
|
Reference in New Issue
Block a user