Last active
March 31, 2019 16:49
-
-
Save filipecosta90/049c460d2cd2f7b242760b85f59725bc to your computer and use it in GitHub Desktop.
list_extend.c -- step 3 :: ListExtendFilter_RedisCommand
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int ListExtendFilter_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, | |
int argc) { | |
// LIST_EXTEND.FILTER source_list destination_list low_value high_value | |
if (argc != 5) { | |
return RedisModule_WrongArity(ctx); | |
} | |
RedisModule_AutoMemory(ctx); | |
// Open field/value list keys | |
RedisModuleKey *sourceListKey = | |
RedisModule_OpenKey(ctx, argv[1], REDISMODULE_READ | REDISMODULE_WRITE); | |
int sourceListKeyType = RedisModule_KeyType(sourceListKey); | |
if (sourceListKeyType != REDISMODULE_KEYTYPE_LIST && | |
sourceListKeyType != REDISMODULE_KEYTYPE_EMPTY) { | |
RedisModule_CloseKey(sourceListKey); | |
return RedisModule_ReplyWithError(ctx, REDISMODULE_ERRORMSG_WRONGTYPE); | |
} | |
// Open destination key | |
RedisModuleKey *destinationListKey = | |
RedisModule_OpenKey(ctx, argv[2], REDISMODULE_WRITE); | |
RedisModule_DeleteKey(destinationListKey); | |
// Get length of list | |
size_t sourceListLength = RedisModule_ValueLength(sourceListKey); | |
if (sourceListLength == 0) { | |
RedisModule_ReplyWithLongLong(ctx, 0L); | |
return REDISMODULE_OK; | |
} | |
char strLowerLimit[] = "-inf"; | |
char strUpperLimit[] = "+inf"; | |
RedisModuleString *expectedMinusInf, *expectedPlusInf; | |
long long lowerLimit; | |
long long upperLimit; | |
int lowerLimitOk = 0; | |
int upperLimitOk = 0; | |
expectedMinusInf = RedisModule_CreateString(ctx, strLowerLimit, 4); | |
expectedPlusInf = RedisModule_CreateString(ctx, strUpperLimit, 4); | |
// check if argv[3] is -inf | |
if (RedisModule_StringCompare(argv[3], expectedMinusInf) == 0) { | |
lowerLimit = LONG_MIN; | |
lowerLimitOk = 1; | |
} else { | |
if (RedisModule_StringToLongLong(argv[3], &lowerLimit) == REDISMODULE_OK) | |
lowerLimitOk = 1; | |
} | |
// check if argv[4] is +inf | |
if (RedisModule_StringCompare(argv[4], expectedPlusInf) == 0) { | |
upperLimit = LONG_MAX; | |
upperLimitOk = 1; | |
} else { | |
if (RedisModule_StringToLongLong(argv[4], &upperLimit) == REDISMODULE_OK) | |
upperLimitOk = 1; | |
} | |
// the number of added elements to the destination_list | |
size_t added = 0; | |
// loop trough source_list | |
for (size_t pos = 0; pos < sourceListLength; pos++) { | |
RedisModuleString *ele = | |
RedisModule_ListPop(sourceListKey, REDISMODULE_LIST_TAIL); | |
RedisModule_ListPush(sourceListKey, REDISMODULE_LIST_HEAD, ele); | |
long long val; | |
// convert string to long long | |
if ((RedisModule_StringToLongLong(ele, &val) == REDISMODULE_OK) && | |
lowerLimitOk == 1 && upperLimitOk == 1) { | |
if (val >= lowerLimit && val <= upperLimit) { | |
// RedisModule_Log(ctx, "notice", "element within range %d %d %d", | |
// lowerLimit, val, upperLimit ); | |
RedisModuleString *newele = | |
RedisModule_CreateStringFromLongLong(ctx, val); | |
// push to destination_list | |
if (RedisModule_ListPush(destinationListKey, REDISMODULE_LIST_HEAD, | |
newele) == REDISMODULE_ERR) { | |
return REDISMODULE_ERR; | |
} | |
added++; | |
} | |
} | |
} | |
RedisModule_ReplyWithLongLong(ctx, added); | |
// propagate the command to the slaves and AOF file exactly as it was called | |
RedisModule_ReplicateVerbatim(ctx); | |
return REDISMODULE_OK; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment