Add RedisModule_GetKeyNameFromIO().
This commit is contained in:
parent
74d6af8f80
commit
a88264d934
@ -1239,7 +1239,7 @@ int rewriteModuleObject(rio *r, robj *key, robj *o) {
|
|||||||
RedisModuleIO io;
|
RedisModuleIO io;
|
||||||
moduleValue *mv = o->ptr;
|
moduleValue *mv = o->ptr;
|
||||||
moduleType *mt = mv->type;
|
moduleType *mt = mv->type;
|
||||||
moduleInitIOContext(io,mt,r);
|
moduleInitIOContext(io,mt,r,key);
|
||||||
mt->aof_rewrite(&io,key,mv->value);
|
mt->aof_rewrite(&io,key,mv->value);
|
||||||
if (io.ctx) {
|
if (io.ctx) {
|
||||||
moduleFreeContext(io.ctx);
|
moduleFreeContext(io.ctx);
|
||||||
|
@ -4776,7 +4776,7 @@ NULL
|
|||||||
|
|
||||||
/* Generates a DUMP-format representation of the object 'o', adding it to the
|
/* Generates a DUMP-format representation of the object 'o', adding it to the
|
||||||
* io stream pointed by 'rio'. This function can't fail. */
|
* io stream pointed by 'rio'. This function can't fail. */
|
||||||
void createDumpPayload(rio *payload, robj *o) {
|
void createDumpPayload(rio *payload, robj *o, robj *key) {
|
||||||
unsigned char buf[2];
|
unsigned char buf[2];
|
||||||
uint64_t crc;
|
uint64_t crc;
|
||||||
|
|
||||||
@ -4784,7 +4784,7 @@ void createDumpPayload(rio *payload, robj *o) {
|
|||||||
* byte followed by the serialized object. This is understood by RESTORE. */
|
* byte followed by the serialized object. This is understood by RESTORE. */
|
||||||
rioInitWithBuffer(payload,sdsempty());
|
rioInitWithBuffer(payload,sdsempty());
|
||||||
serverAssert(rdbSaveObjectType(payload,o));
|
serverAssert(rdbSaveObjectType(payload,o));
|
||||||
serverAssert(rdbSaveObject(payload,o));
|
serverAssert(rdbSaveObject(payload,o,key));
|
||||||
|
|
||||||
/* Write the footer, this is how it looks like:
|
/* Write the footer, this is how it looks like:
|
||||||
* ----------------+---------------------+---------------+
|
* ----------------+---------------------+---------------+
|
||||||
@ -4842,7 +4842,7 @@ void dumpCommand(client *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create the DUMP encoded representation. */
|
/* Create the DUMP encoded representation. */
|
||||||
createDumpPayload(&payload,o);
|
createDumpPayload(&payload,o,c->argv[1]);
|
||||||
|
|
||||||
/* Transfer to the client */
|
/* Transfer to the client */
|
||||||
dumpobj = createObject(OBJ_STRING,payload.io.buffer.ptr);
|
dumpobj = createObject(OBJ_STRING,payload.io.buffer.ptr);
|
||||||
@ -4915,7 +4915,7 @@ void restoreCommand(client *c) {
|
|||||||
|
|
||||||
rioInitWithBuffer(&payload,c->argv[3]->ptr);
|
rioInitWithBuffer(&payload,c->argv[3]->ptr);
|
||||||
if (((type = rdbLoadObjectType(&payload)) == -1) ||
|
if (((type = rdbLoadObjectType(&payload)) == -1) ||
|
||||||
((obj = rdbLoadObject(type,&payload)) == NULL))
|
((obj = rdbLoadObject(type,&payload,c->argv[1])) == NULL))
|
||||||
{
|
{
|
||||||
addReplyError(c,"Bad data format");
|
addReplyError(c,"Bad data format");
|
||||||
return;
|
return;
|
||||||
@ -5203,7 +5203,7 @@ try_again:
|
|||||||
|
|
||||||
/* Emit the payload argument, that is the serialized object using
|
/* Emit the payload argument, that is the serialized object using
|
||||||
* the DUMP format. */
|
* the DUMP format. */
|
||||||
createDumpPayload(&payload,ov[j]);
|
createDumpPayload(&payload,ov[j],kv[j]);
|
||||||
serverAssertWithInfo(c,NULL,
|
serverAssertWithInfo(c,NULL,
|
||||||
rioWriteBulkString(&cmd,payload.io.buffer.ptr,
|
rioWriteBulkString(&cmd,payload.io.buffer.ptr,
|
||||||
sdslen(payload.io.buffer.ptr)));
|
sdslen(payload.io.buffer.ptr)));
|
||||||
|
@ -3438,6 +3438,14 @@ RedisModuleCtx *RM_GetContextFromIO(RedisModuleIO *io) {
|
|||||||
return io->ctx;
|
return io->ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns a RedisModuleString with the name of the key currently saving or
|
||||||
|
* loading, when an IO data type callback is called. There is no guarantee
|
||||||
|
* that the key name is always available, so this may return NULL.
|
||||||
|
*/
|
||||||
|
const RedisModuleString *RM_GetKeyNameFromIO(RedisModuleIO *io) {
|
||||||
|
return io->key;
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------
|
||||||
* Logging
|
* Logging
|
||||||
* -------------------------------------------------------------------------- */
|
* -------------------------------------------------------------------------- */
|
||||||
@ -5164,6 +5172,7 @@ void moduleRegisterCoreAPI(void) {
|
|||||||
REGISTER_API(RetainString);
|
REGISTER_API(RetainString);
|
||||||
REGISTER_API(StringCompare);
|
REGISTER_API(StringCompare);
|
||||||
REGISTER_API(GetContextFromIO);
|
REGISTER_API(GetContextFromIO);
|
||||||
|
REGISTER_API(GetKeyNameFromIO);
|
||||||
REGISTER_API(BlockClient);
|
REGISTER_API(BlockClient);
|
||||||
REGISTER_API(UnblockClient);
|
REGISTER_API(UnblockClient);
|
||||||
REGISTER_API(IsBlockedReplyRequest);
|
REGISTER_API(IsBlockedReplyRequest);
|
||||||
|
14
src/rdb.c
14
src/rdb.c
@ -751,7 +751,7 @@ size_t rdbSaveStreamConsumers(rio *rdb, streamCG *cg) {
|
|||||||
|
|
||||||
/* Save a Redis object.
|
/* Save a Redis object.
|
||||||
* Returns -1 on error, number of bytes written on success. */
|
* Returns -1 on error, number of bytes written on success. */
|
||||||
ssize_t rdbSaveObject(rio *rdb, robj *o) {
|
ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) {
|
||||||
ssize_t n = 0, nwritten = 0;
|
ssize_t n = 0, nwritten = 0;
|
||||||
|
|
||||||
if (o->type == OBJ_STRING) {
|
if (o->type == OBJ_STRING) {
|
||||||
@ -966,7 +966,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) {
|
|||||||
RedisModuleIO io;
|
RedisModuleIO io;
|
||||||
moduleValue *mv = o->ptr;
|
moduleValue *mv = o->ptr;
|
||||||
moduleType *mt = mv->type;
|
moduleType *mt = mv->type;
|
||||||
moduleInitIOContext(io,mt,rdb);
|
moduleInitIOContext(io,mt,rdb,key);
|
||||||
|
|
||||||
/* Write the "module" identifier as prefix, so that we'll be able
|
/* Write the "module" identifier as prefix, so that we'll be able
|
||||||
* to call the right module during loading. */
|
* to call the right module during loading. */
|
||||||
@ -996,7 +996,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) {
|
|||||||
* this length with very little changes to the code. In the future
|
* this length with very little changes to the code. In the future
|
||||||
* we could switch to a faster solution. */
|
* we could switch to a faster solution. */
|
||||||
size_t rdbSavedObjectLen(robj *o) {
|
size_t rdbSavedObjectLen(robj *o) {
|
||||||
ssize_t len = rdbSaveObject(NULL,o);
|
ssize_t len = rdbSaveObject(NULL,o,NULL);
|
||||||
serverAssertWithInfo(NULL,o,len != -1);
|
serverAssertWithInfo(NULL,o,len != -1);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@ -1038,7 +1038,7 @@ int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, long long expiretime) {
|
|||||||
/* Save type, key, value */
|
/* Save type, key, value */
|
||||||
if (rdbSaveObjectType(rdb,val) == -1) return -1;
|
if (rdbSaveObjectType(rdb,val) == -1) return -1;
|
||||||
if (rdbSaveStringObject(rdb,key) == -1) return -1;
|
if (rdbSaveStringObject(rdb,key) == -1) return -1;
|
||||||
if (rdbSaveObject(rdb,val) == -1) return -1;
|
if (rdbSaveObject(rdb,val,key) == -1) return -1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1380,7 +1380,7 @@ robj *rdbLoadCheckModuleValue(rio *rdb, char *modulename) {
|
|||||||
|
|
||||||
/* Load a Redis object of the specified type from the specified file.
|
/* Load a Redis object of the specified type from the specified file.
|
||||||
* On success a newly allocated object is returned, otherwise NULL. */
|
* On success a newly allocated object is returned, otherwise NULL. */
|
||||||
robj *rdbLoadObject(int rdbtype, rio *rdb) {
|
robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) {
|
||||||
robj *o = NULL, *ele, *dec;
|
robj *o = NULL, *ele, *dec;
|
||||||
uint64_t len;
|
uint64_t len;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -1767,7 +1767,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
RedisModuleIO io;
|
RedisModuleIO io;
|
||||||
moduleInitIOContext(io,mt,rdb);
|
moduleInitIOContext(io,mt,rdb,key);
|
||||||
io.ver = (rdbtype == RDB_TYPE_MODULE) ? 1 : 2;
|
io.ver = (rdbtype == RDB_TYPE_MODULE) ? 1 : 2;
|
||||||
/* Call the rdb_load method of the module providing the 10 bit
|
/* Call the rdb_load method of the module providing the 10 bit
|
||||||
* encoding version in the lower 10 bits of the module ID. */
|
* encoding version in the lower 10 bits of the module ID. */
|
||||||
@ -2023,7 +2023,7 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi, int loading_aof) {
|
|||||||
/* Read key */
|
/* Read key */
|
||||||
if ((key = rdbLoadStringObject(rdb)) == NULL) goto eoferr;
|
if ((key = rdbLoadStringObject(rdb)) == NULL) goto eoferr;
|
||||||
/* Read value */
|
/* Read value */
|
||||||
if ((val = rdbLoadObject(type,rdb)) == NULL) goto eoferr;
|
if ((val = rdbLoadObject(type,rdb,key)) == NULL) goto eoferr;
|
||||||
/* Check if the key already expired. This function is used when loading
|
/* Check if the key already expired. This function is used when loading
|
||||||
* an RDB file from disk, either at startup, or when an RDB was
|
* an RDB file from disk, either at startup, or when an RDB was
|
||||||
* received from the master. In the latter case, the master is
|
* received from the master. In the latter case, the master is
|
||||||
|
@ -140,9 +140,9 @@ int rdbSaveBackground(char *filename, rdbSaveInfo *rsi);
|
|||||||
int rdbSaveToSlavesSockets(rdbSaveInfo *rsi);
|
int rdbSaveToSlavesSockets(rdbSaveInfo *rsi);
|
||||||
void rdbRemoveTempFile(pid_t childpid);
|
void rdbRemoveTempFile(pid_t childpid);
|
||||||
int rdbSave(char *filename, rdbSaveInfo *rsi);
|
int rdbSave(char *filename, rdbSaveInfo *rsi);
|
||||||
ssize_t rdbSaveObject(rio *rdb, robj *o);
|
ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key);
|
||||||
size_t rdbSavedObjectLen(robj *o);
|
size_t rdbSavedObjectLen(robj *o);
|
||||||
robj *rdbLoadObject(int type, rio *rdb);
|
robj *rdbLoadObject(int type, rio *rdb, robj *key);
|
||||||
void backgroundSaveDoneHandler(int exitcode, int bysignal);
|
void backgroundSaveDoneHandler(int exitcode, int bysignal);
|
||||||
int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, long long expiretime);
|
int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, long long expiretime);
|
||||||
robj *rdbLoadStringObject(rio *rdb);
|
robj *rdbLoadStringObject(rio *rdb);
|
||||||
|
@ -285,7 +285,7 @@ int redis_check_rdb(char *rdbfilename, FILE *fp) {
|
|||||||
rdbstate.keys++;
|
rdbstate.keys++;
|
||||||
/* Read value */
|
/* Read value */
|
||||||
rdbstate.doing = RDB_CHECK_DOING_READ_OBJECT_VALUE;
|
rdbstate.doing = RDB_CHECK_DOING_READ_OBJECT_VALUE;
|
||||||
if ((val = rdbLoadObject(type,&rdb)) == NULL) goto eoferr;
|
if ((val = rdbLoadObject(type,&rdb,key)) == NULL) goto eoferr;
|
||||||
/* Check if the key already expired. */
|
/* Check if the key already expired. */
|
||||||
if (expiretime != -1 && expiretime < now)
|
if (expiretime != -1 && expiretime < now)
|
||||||
rdbstate.already_expired++;
|
rdbstate.already_expired++;
|
||||||
|
@ -278,6 +278,7 @@ int REDISMODULE_API_FUNC(RedisModule_StringAppendBuffer)(RedisModuleCtx *ctx, Re
|
|||||||
void REDISMODULE_API_FUNC(RedisModule_RetainString)(RedisModuleCtx *ctx, RedisModuleString *str);
|
void REDISMODULE_API_FUNC(RedisModule_RetainString)(RedisModuleCtx *ctx, RedisModuleString *str);
|
||||||
int REDISMODULE_API_FUNC(RedisModule_StringCompare)(RedisModuleString *a, RedisModuleString *b);
|
int REDISMODULE_API_FUNC(RedisModule_StringCompare)(RedisModuleString *a, RedisModuleString *b);
|
||||||
RedisModuleCtx *REDISMODULE_API_FUNC(RedisModule_GetContextFromIO)(RedisModuleIO *io);
|
RedisModuleCtx *REDISMODULE_API_FUNC(RedisModule_GetContextFromIO)(RedisModuleIO *io);
|
||||||
|
const RedisModuleString *REDISMODULE_API_FUNC(RedisModule_GetKeyNameFromIO)(RedisModuleIO *io);
|
||||||
long long REDISMODULE_API_FUNC(RedisModule_Milliseconds)(void);
|
long long REDISMODULE_API_FUNC(RedisModule_Milliseconds)(void);
|
||||||
void REDISMODULE_API_FUNC(RedisModule_DigestAddStringBuffer)(RedisModuleDigest *md, unsigned char *ele, size_t len);
|
void REDISMODULE_API_FUNC(RedisModule_DigestAddStringBuffer)(RedisModuleDigest *md, unsigned char *ele, size_t len);
|
||||||
void REDISMODULE_API_FUNC(RedisModule_DigestAddLongLong)(RedisModuleDigest *md, long long ele);
|
void REDISMODULE_API_FUNC(RedisModule_DigestAddLongLong)(RedisModuleDigest *md, long long ele);
|
||||||
@ -442,6 +443,7 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
|
|||||||
REDISMODULE_GET_API(RetainString);
|
REDISMODULE_GET_API(RetainString);
|
||||||
REDISMODULE_GET_API(StringCompare);
|
REDISMODULE_GET_API(StringCompare);
|
||||||
REDISMODULE_GET_API(GetContextFromIO);
|
REDISMODULE_GET_API(GetContextFromIO);
|
||||||
|
REDISMODULE_GET_API(GetKeyNameFromIO);
|
||||||
REDISMODULE_GET_API(Milliseconds);
|
REDISMODULE_GET_API(Milliseconds);
|
||||||
REDISMODULE_GET_API(DigestAddStringBuffer);
|
REDISMODULE_GET_API(DigestAddStringBuffer);
|
||||||
REDISMODULE_GET_API(DigestAddLongLong);
|
REDISMODULE_GET_API(DigestAddLongLong);
|
||||||
|
@ -578,16 +578,18 @@ typedef struct RedisModuleIO {
|
|||||||
int ver; /* Module serialization version: 1 (old),
|
int ver; /* Module serialization version: 1 (old),
|
||||||
* 2 (current version with opcodes annotation). */
|
* 2 (current version with opcodes annotation). */
|
||||||
struct RedisModuleCtx *ctx; /* Optional context, see RM_GetContextFromIO()*/
|
struct RedisModuleCtx *ctx; /* Optional context, see RM_GetContextFromIO()*/
|
||||||
|
struct redisObject *key; /* Optional name of key processed */
|
||||||
} RedisModuleIO;
|
} RedisModuleIO;
|
||||||
|
|
||||||
/* Macro to initialize an IO context. Note that the 'ver' field is populated
|
/* Macro to initialize an IO context. Note that the 'ver' field is populated
|
||||||
* inside rdb.c according to the version of the value to load. */
|
* inside rdb.c according to the version of the value to load. */
|
||||||
#define moduleInitIOContext(iovar,mtype,rioptr) do { \
|
#define moduleInitIOContext(iovar,mtype,rioptr,keyptr) do { \
|
||||||
iovar.rio = rioptr; \
|
iovar.rio = rioptr; \
|
||||||
iovar.type = mtype; \
|
iovar.type = mtype; \
|
||||||
iovar.bytes = 0; \
|
iovar.bytes = 0; \
|
||||||
iovar.error = 0; \
|
iovar.error = 0; \
|
||||||
iovar.ver = 0; \
|
iovar.ver = 0; \
|
||||||
|
iovar.key = keyptr; \
|
||||||
iovar.ctx = NULL; \
|
iovar.ctx = NULL; \
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user