Skip to content

Instantly share code, notes, and snippets.

@filipecosta90
Last active March 31, 2019 16:49
Show Gist options
  • Save filipecosta90/049c460d2cd2f7b242760b85f59725bc to your computer and use it in GitHub Desktop.
Save filipecosta90/049c460d2cd2f7b242760b85f59725bc to your computer and use it in GitHub Desktop.
list_extend.c -- step 3 :: ListExtendFilter_RedisCommand
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