/* HELLO.LEXRANGE key min_lex max_lex min_age max_age * This command expects a sorted set stored at key in the following form: * - All the elements have score 0. * - Elements are pairs of "<name>:<age>", for example "Anna:52". * The command will return all the sorted set items that are lexicographically * between the specified range (using the same format as ZRANGEBYLEX) * and having an age between min_age and max_age. */ int HelloLexRange_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { RedisModule_AutoMemory(ctx); /* Use automatic memory management. */ if (argc != 6) return RedisModule_WrongArity(ctx); RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1], REDISMODULE_READ|REDISMODULE_WRITE); if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_ZSET) { return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); } if (RedisModule_ZsetFirstInLexRange(key,argv[2],argv[3]) != REDISMODULE_OK) { return RedisModule_ReplyWithError(ctx,"invalid range"); } int arraylen = 0; RedisModule_ReplyWithArray(ctx,REDISMODULE_POSTPONED_ARRAY_LEN); while(!RedisModule_ZsetRangeEndReached(key)) { double score; RedisModuleString *ele = RedisModule_ZsetRangeCurrentElement(key,&score); RedisModule_ReplyWithString(ctx,ele); RedisModule_FreeString(ctx,ele); RedisModule_ZsetRangeNext(key); arraylen++; } RedisModule_ZsetRangeStop(key); RedisModule_ReplySetArrayLength(ctx,arraylen); RedisModule_CloseKey(key); return REDISMODULE_OK; }
/* HELLO.ZSUMRANGE key startscore endscore * Return the sum of all the scores elements between startscore and endscore. * * The computation is performed two times, one time from start to end and * another time backward. The two scores, returned as a two element array, * should match.*/ int HelloZsumRange_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { double score_start, score_end; if (argc != 4) return RedisModule_WrongArity(ctx); if (RedisModule_StringToDouble(argv[2],&score_start) != REDISMODULE_OK || RedisModule_StringToDouble(argv[3],&score_end) != REDISMODULE_OK) { return RedisModule_ReplyWithError(ctx,"ERR invalid range"); } RedisModuleKey *key = RedisModule_OpenKey(ctx,argv[1], REDISMODULE_READ|REDISMODULE_WRITE); if (RedisModule_KeyType(key) != REDISMODULE_KEYTYPE_ZSET) { return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); } double scoresum_a = 0; double scoresum_b = 0; RedisModule_ZsetFirstInScoreRange(key,score_start,score_end,0,0); while(!RedisModule_ZsetRangeEndReached(key)) { double score; RedisModuleString *ele = RedisModule_ZsetRangeCurrentElement(key,&score); RedisModule_FreeString(ctx,ele); scoresum_a += score; RedisModule_ZsetRangeNext(key); } RedisModule_ZsetRangeStop(key); RedisModule_ZsetLastInScoreRange(key,score_start,score_end,0,0); while(!RedisModule_ZsetRangeEndReached(key)) { double score; RedisModuleString *ele = RedisModule_ZsetRangeCurrentElement(key,&score); RedisModule_FreeString(ctx,ele); scoresum_b += score; RedisModule_ZsetRangePrev(key); } RedisModule_ZsetRangeStop(key); RedisModule_CloseKey(key); RedisModule_ReplyWithArray(ctx,2); RedisModule_ReplyWithDouble(ctx,scoresum_a); RedisModule_ReplyWithDouble(ctx,scoresum_b); return REDISMODULE_OK; }
RedisModuleKey* Index_LookupKey(RedisModuleCtx *ctx, const char *graph, const char *label, const char *property) { char *strKey; asprintf(&strKey, "%s_%s_%s_%s", INDEX_PREFIX, graph, label, property); RedisModuleString *rmIndexId = RedisModule_CreateString(ctx, strKey, strlen(strKey)); free(strKey); RedisModuleKey *key = RedisModule_OpenKey(ctx, rmIndexId, REDISMODULE_WRITE); RedisModule_FreeString(ctx, rmIndexId); return key; }
/* HELLO.LIST.SPLICE srclist dstlist count * Moves 'count' elements from the tail of 'srclist' to the head of * 'dstlist'. If less than count elements are available, it moves as much * elements as possible. */ int HelloListSplice_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { if (argc != 4) return RedisModule_WrongArity(ctx); RedisModuleKey *srckey = RedisModule_OpenKey(ctx,argv[1], REDISMODULE_READ|REDISMODULE_WRITE); RedisModuleKey *dstkey = RedisModule_OpenKey(ctx,argv[2], REDISMODULE_READ|REDISMODULE_WRITE); /* Src and dst key must be empty or lists. */ if ((RedisModule_KeyType(srckey) != REDISMODULE_KEYTYPE_LIST && RedisModule_KeyType(srckey) != REDISMODULE_KEYTYPE_EMPTY) || (RedisModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_LIST && RedisModule_KeyType(dstkey) != REDISMODULE_KEYTYPE_EMPTY)) { RedisModule_CloseKey(srckey); RedisModule_CloseKey(dstkey); return RedisModule_ReplyWithError(ctx,REDISMODULE_ERRORMSG_WRONGTYPE); } long long count; if ((RedisModule_StringToLongLong(argv[3],&count) != REDISMODULE_OK) || (count < 0)) { RedisModule_CloseKey(srckey); RedisModule_CloseKey(dstkey); return RedisModule_ReplyWithError(ctx,"ERR invalid count"); } while(count-- > 0) { RedisModuleString *ele; ele = RedisModule_ListPop(srckey,REDISMODULE_LIST_TAIL); if (ele == NULL) break; RedisModule_ListPush(dstkey,REDISMODULE_LIST_HEAD,ele); RedisModule_FreeString(ctx,ele); } size_t len = RedisModule_ValueLength(srckey); RedisModule_CloseKey(srckey); RedisModule_CloseKey(dstkey); RedisModule_ReplyWithLongLong(ctx,len); return REDISMODULE_OK; }