mirror of https://github.com/redis/redis.git
				
				
				
			Added RM_UnlinkKey - a low level analog to UNLINK command
This commit is contained in:
		
							parent
							
								
									e509fbb8d9
								
							
						
					
					
						commit
						e76dfc90a7
					
				
							
								
								
									
										15
									
								
								src/module.c
								
								
								
								
							
							
						
						
									
										15
									
								
								src/module.c
								
								
								
								
							|  | @ -1456,6 +1456,20 @@ int RM_DeleteKey(RedisModuleKey *key) { | |||
|     return REDISMODULE_OK; | ||||
| } | ||||
| 
 | ||||
| /* If the key is open for writing, unlink it (that is delete it in a 
 | ||||
|  * non-blocking way, not reclaiming memory immediately) 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. */ | ||||
| int RM_UnlinkKey(RedisModuleKey *key) { | ||||
|     if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR; | ||||
|     if (key->value) { | ||||
|         dbAsyncDelete(key->db,key->key); | ||||
|         key->value = NULL; | ||||
|     } | ||||
|     return REDISMODULE_OK; | ||||
| } | ||||
| 
 | ||||
| /* 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. */ | ||||
|  | @ -3960,6 +3974,7 @@ void moduleRegisterCoreAPI(void) { | |||
|     REGISTER_API(Replicate); | ||||
|     REGISTER_API(ReplicateVerbatim); | ||||
|     REGISTER_API(DeleteKey); | ||||
|     REGISTER_API(UnlinkKey); | ||||
|     REGISTER_API(StringSet); | ||||
|     REGISTER_API(StringDMA); | ||||
|     REGISTER_API(StringTruncate); | ||||
|  |  | |||
|  | @ -120,6 +120,38 @@ int TestStringPrintf(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { | |||
|     return REDISMODULE_OK; | ||||
| } | ||||
| 
 | ||||
| int failTest(RedisModuleCtx *ctx, const char *msg) { | ||||
|     RedisModule_ReplyWithError(ctx, msg); | ||||
|     return REDISMODULE_ERR; | ||||
| } | ||||
| int TestUnlink(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { | ||||
|     RedisModule_AutoMemory(ctx); | ||||
|     REDISMODULE_NOT_USED(argv); | ||||
|     REDISMODULE_NOT_USED(argc); | ||||
| 
 | ||||
|     RedisModuleKey *k = RedisModule_OpenKey(ctx, RedisModule_CreateStringPrintf(ctx, "unlinked"), REDISMODULE_WRITE | REDISMODULE_READ); | ||||
|     if (!k) return failTest(ctx, "Could not create key"); | ||||
|      | ||||
|     if (REDISMODULE_ERR == RedisModule_StringSet(k, RedisModule_CreateStringPrintf(ctx, "Foobar"))) { | ||||
|         return failTest(ctx, "Could not set string value"); | ||||
|     } | ||||
| 
 | ||||
|     RedisModuleCallReply *rep = RedisModule_Call(ctx, "EXISTS", "c", "unlinked"); | ||||
|     if (!rep || RedisModule_CallReplyInteger(rep) != 1) { | ||||
|         return failTest(ctx, "Key does not exist before unlink"); | ||||
|     } | ||||
| 
 | ||||
|     if (REDISMODULE_ERR == RedisModule_UnlinkKey(k)) { | ||||
|         return failTest(ctx, "Could not unlink key"); | ||||
|     } | ||||
| 
 | ||||
|     rep = RedisModule_Call(ctx, "EXISTS", "c", "unlinked"); | ||||
|     if (!rep || RedisModule_CallReplyInteger(rep) != 0) { | ||||
|         return failTest(ctx, "Could not verify key to be unlinked"); | ||||
|     } | ||||
|     return RedisModule_ReplyWithSimpleString(ctx, "OK"); | ||||
|      | ||||
| } | ||||
| 
 | ||||
| /* TEST.CTXFLAGS -- Test GetContextFlags. */ | ||||
| int TestCtxFlags(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { | ||||
|  | @ -269,6 +301,9 @@ int TestIt(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { | |||
|     T("test.string.append",""); | ||||
|     if (!TestAssertStringReply(ctx,reply,"foobar",6)) goto fail; | ||||
| 
 | ||||
|     T("test.unlink",""); | ||||
|     if (!TestAssertStringReply(ctx,reply,"OK",2)) goto fail; | ||||
| 
 | ||||
|     T("test.string.append.am",""); | ||||
|     if (!TestAssertStringReply(ctx,reply,"foobar",6)) goto fail; | ||||
| 
 | ||||
|  | @ -311,6 +346,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) | |||
|         TestCtxFlags,"readonly",1,1,1) == REDISMODULE_ERR) | ||||
|         return REDISMODULE_ERR; | ||||
|      | ||||
|     if (RedisModule_CreateCommand(ctx,"test.unlink", | ||||
|         TestUnlink,"write deny-oom",1,1,1) == REDISMODULE_ERR) | ||||
|         return REDISMODULE_ERR; | ||||
| 
 | ||||
|     if (RedisModule_CreateCommand(ctx,"test.it", | ||||
|         TestIt,"readonly",1,1,1) == REDISMODULE_ERR) | ||||
|         return REDISMODULE_ERR; | ||||
|  |  | |||
|  | @ -185,6 +185,7 @@ int REDISMODULE_API_FUNC(RedisModule_ReplicateVerbatim)(RedisModuleCtx *ctx); | |||
| const char *REDISMODULE_API_FUNC(RedisModule_CallReplyStringPtr)(RedisModuleCallReply *reply, size_t *len); | ||||
| RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringFromCallReply)(RedisModuleCallReply *reply); | ||||
| int REDISMODULE_API_FUNC(RedisModule_DeleteKey)(RedisModuleKey *key); | ||||
| int REDISMODULE_API_FUNC(RedisModule_UnlinkKey)(RedisModuleKey *key); | ||||
| int REDISMODULE_API_FUNC(RedisModule_StringSet)(RedisModuleKey *key, RedisModuleString *str); | ||||
| char *REDISMODULE_API_FUNC(RedisModule_StringDMA)(RedisModuleKey *key, size_t *len, int mode); | ||||
| int REDISMODULE_API_FUNC(RedisModule_StringTruncate)(RedisModuleKey *key, size_t newlen); | ||||
|  | @ -306,6 +307,7 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int | |||
|     REDISMODULE_GET_API(Replicate); | ||||
|     REDISMODULE_GET_API(ReplicateVerbatim); | ||||
|     REDISMODULE_GET_API(DeleteKey); | ||||
|     REDISMODULE_GET_API(UnlinkKey); | ||||
|     REDISMODULE_GET_API(StringSet); | ||||
|     REDISMODULE_GET_API(StringDMA); | ||||
|     REDISMODULE_GET_API(StringTruncate); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue