diff --git a/src/module.c b/src/module.c index b4fc3e856..8d04215d6 100644 --- a/src/module.c +++ b/src/module.c @@ -2516,19 +2516,19 @@ RedisModuleString *RM_ListPop(RedisModuleKey *key, int where) { * so that we have everything decoupled. */ int moduleZsetAddFlagsToCoreFlags(int flags) { int retflags = 0; - if (flags & REDISMODULE_ZADD_XX) retflags |= ZADD_XX; - if (flags & REDISMODULE_ZADD_NX) retflags |= ZADD_NX; - if (flags & REDISMODULE_ZADD_GT) retflags |= ZADD_GT; - if (flags & REDISMODULE_ZADD_LT) retflags |= ZADD_LT; + if (flags & REDISMODULE_ZADD_XX) retflags |= ZADD_IN_XX; + if (flags & REDISMODULE_ZADD_NX) retflags |= ZADD_IN_NX; + if (flags & REDISMODULE_ZADD_GT) retflags |= ZADD_IN_GT; + if (flags & REDISMODULE_ZADD_LT) retflags |= ZADD_IN_LT; return retflags; } /* See previous function comment. */ int moduleZsetAddFlagsFromCoreFlags(int flags) { int retflags = 0; - if (flags & ZADD_ADDED) retflags |= REDISMODULE_ZADD_ADDED; - if (flags & ZADD_UPDATED) retflags |= REDISMODULE_ZADD_UPDATED; - if (flags & ZADD_NOP) retflags |= REDISMODULE_ZADD_NOP; + if (flags & ZADD_OUT_ADDED) retflags |= REDISMODULE_ZADD_ADDED; + if (flags & ZADD_OUT_UPDATED) retflags |= REDISMODULE_ZADD_UPDATED; + if (flags & ZADD_OUT_NOP) retflags |= REDISMODULE_ZADD_NOP; return retflags; } @@ -2565,16 +2565,16 @@ int moduleZsetAddFlagsFromCoreFlags(int flags) { * * 'score' double value is not a number (NaN). */ int RM_ZsetAdd(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr) { - int flags = 0; + int in_flags = 0, out_flags = 0; if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR; if (key->value && key->value->type != OBJ_ZSET) return REDISMODULE_ERR; if (key->value == NULL) moduleCreateEmptyKey(key,REDISMODULE_KEYTYPE_ZSET); - if (flagsptr) flags = moduleZsetAddFlagsToCoreFlags(*flagsptr); - if (zsetAdd(key->value,score,ele->ptr,&flags,NULL) == 0) { + if (flagsptr) in_flags = moduleZsetAddFlagsToCoreFlags(*flagsptr); + if (zsetAdd(key->value,score,ele->ptr,in_flags,&out_flags,NULL) == 0) { if (flagsptr) *flagsptr = 0; return REDISMODULE_ERR; } - if (flagsptr) *flagsptr = moduleZsetAddFlagsFromCoreFlags(flags); + if (flagsptr) *flagsptr = moduleZsetAddFlagsFromCoreFlags(out_flags); return REDISMODULE_OK; } @@ -2592,22 +2592,17 @@ int RM_ZsetAdd(RedisModuleKey *key, double score, RedisModuleString *ele, int *f * with the new score of the element after the increment, if no error * is returned. */ int RM_ZsetIncrby(RedisModuleKey *key, double score, RedisModuleString *ele, int *flagsptr, double *newscore) { - int flags = 0; + int in_flags = 0, out_flags = 0; if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR; if (key->value && key->value->type != OBJ_ZSET) return REDISMODULE_ERR; if (key->value == NULL) moduleCreateEmptyKey(key,REDISMODULE_KEYTYPE_ZSET); - if (flagsptr) flags = moduleZsetAddFlagsToCoreFlags(*flagsptr); - flags |= ZADD_INCR; - if (zsetAdd(key->value,score,ele->ptr,&flags,newscore) == 0) { + if (flagsptr) in_flags = moduleZsetAddFlagsToCoreFlags(*flagsptr); + in_flags |= ZADD_IN_INCR; + if (zsetAdd(key->value,score,ele->ptr,in_flags,&out_flags,newscore) == 0) { if (flagsptr) *flagsptr = 0; return REDISMODULE_ERR; } - /* zsetAdd() may signal back that the resulting score is not a number. */ - if (flagsptr && (*flagsptr & ZADD_NAN)) { - *flagsptr = 0; - return REDISMODULE_ERR; - } - if (flagsptr) *flagsptr = moduleZsetAddFlagsFromCoreFlags(flags); + if (flagsptr) *flagsptr = moduleZsetAddFlagsFromCoreFlags(out_flags); return REDISMODULE_OK; } diff --git a/src/server.h b/src/server.h index ef1ac1e48..11fe55397 100644 --- a/src/server.h +++ b/src/server.h @@ -2111,21 +2111,18 @@ void ACLUpdateDefaultUserPassword(sds password); /* Sorted sets data type */ /* Input flags. */ -#define ZADD_NONE 0 -#define ZADD_INCR (1<<0) /* Increment the score instead of setting it. */ -#define ZADD_NX (1<<1) /* Don't touch elements not already existing. */ -#define ZADD_XX (1<<2) /* Only touch elements already existing. */ -#define ZADD_GT (1<<7) /* Only update existing when new scores are higher. */ -#define ZADD_LT (1<<8) /* Only update existing when new scores are lower. */ +#define ZADD_IN_NONE 0 +#define ZADD_IN_INCR (1<<0) /* Increment the score instead of setting it. */ +#define ZADD_IN_NX (1<<1) /* Don't touch elements not already existing. */ +#define ZADD_IN_XX (1<<2) /* Only touch elements already existing. */ +#define ZADD_IN_GT (1<<3) /* Only update existing when new scores are higher. */ +#define ZADD_IN_LT (1<<4) /* Only update existing when new scores are lower. */ /* Output flags. */ -#define ZADD_NOP (1<<3) /* Operation not performed because of conditionals.*/ -#define ZADD_NAN (1<<4) /* Only touch elements already existing. */ -#define ZADD_ADDED (1<<5) /* The element was new and was added. */ -#define ZADD_UPDATED (1<<6) /* The element already existed, score updated. */ - -/* Flags only used by the ZADD command but not by zsetAdd() API: */ -#define ZADD_CH (1<<16) /* Return num of elements added or updated. */ +#define ZADD_OUT_NOP (1<<0) /* Operation not performed because of conditionals.*/ +#define ZADD_OUT_NAN (1<<1) /* Only touch elements already existing. */ +#define ZADD_OUT_ADDED (1<<2) /* The element was new and was added. */ +#define ZADD_OUT_UPDATED (1<<3) /* The element already existed, score updated. */ /* Struct to hold an inclusive/exclusive range spec by score comparison. */ typedef struct { @@ -2156,7 +2153,7 @@ void zsetConvert(robj *zobj, int encoding); void zsetConvertToZiplistIfNeeded(robj *zobj, size_t maxelelen); int zsetScore(robj *zobj, sds member, double *score); unsigned long zslGetRank(zskiplist *zsl, double score, sds o); -int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore); +int zsetAdd(robj *zobj, double score, sds ele, int in_flags, int *out_flags, double *newscore); long zsetRank(robj *zobj, sds ele, int reverse); int zsetDel(robj *zobj, sds ele); robj *zsetDup(robj *o); diff --git a/src/t_zset.c b/src/t_zset.c index 6df21e300..dd65d3c67 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -1279,9 +1279,7 @@ int zsetScore(robj *zobj, sds member, double *score) { /* Add a new element or update the score of an existing element in a sorted * set, regardless of its encoding. * - * The set of flags change the command behavior. They are passed with an integer - * pointer since the function will clear the flags and populate them with - * other flags to indicate different conditions. + * The set of flags change the command behavior. * * The input flags are the following: * @@ -1323,19 +1321,19 @@ int zsetScore(robj *zobj, sds member, double *score) { * * The function does not take ownership of the 'ele' SDS string, but copies * it if needed. */ -int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) { +int zsetAdd(robj *zobj, double score, sds ele, int in_flags, int *out_flags, double *newscore) { /* Turn options into simple to check vars. */ - int incr = (*flags & ZADD_INCR) != 0; - int nx = (*flags & ZADD_NX) != 0; - int xx = (*flags & ZADD_XX) != 0; - int gt = (*flags & ZADD_GT) != 0; - int lt = (*flags & ZADD_LT) != 0; - *flags = 0; /* We'll return our response flags. */ + int incr = (in_flags & ZADD_IN_INCR) != 0; + int nx = (in_flags & ZADD_IN_NX) != 0; + int xx = (in_flags & ZADD_IN_XX) != 0; + int gt = (in_flags & ZADD_IN_GT) != 0; + int lt = (in_flags & ZADD_IN_LT) != 0; + *out_flags = 0; /* We'll return our response flags. */ double curscore; /* NaN as input is an error regardless of all the other parameters. */ if (isnan(score)) { - *flags = ZADD_NAN; + *out_flags = ZADD_OUT_NAN; return 0; } @@ -1346,7 +1344,7 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) { if ((eptr = zzlFind(zobj->ptr,ele,&curscore)) != NULL) { /* NX? Return, same element already exists. */ if (nx) { - *flags |= ZADD_NOP; + *out_flags |= ZADD_OUT_NOP; return 1; } @@ -1354,7 +1352,7 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) { if (incr) { score += curscore; if (isnan(score)) { - *flags |= ZADD_NAN; + *out_flags |= ZADD_OUT_NAN; return 0; } if (newscore) *newscore = score; @@ -1369,7 +1367,7 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) { { zobj->ptr = zzlDelete(zobj->ptr,eptr); zobj->ptr = zzlInsert(zobj->ptr,ele,score); - *flags |= ZADD_UPDATED; + *out_flags |= ZADD_OUT_UPDATED; } return 1; } else if (!xx) { @@ -1380,10 +1378,10 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) { sdslen(ele) > server.zset_max_ziplist_value) zsetConvert(zobj,OBJ_ENCODING_SKIPLIST); if (newscore) *newscore = score; - *flags |= ZADD_ADDED; + *out_flags |= ZADD_OUT_ADDED; return 1; } else { - *flags |= ZADD_NOP; + *out_flags |= ZADD_OUT_NOP; return 1; } } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { @@ -1395,7 +1393,7 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) { if (de != NULL) { /* NX? Return, same element already exists. */ if (nx) { - *flags |= ZADD_NOP; + *out_flags |= ZADD_OUT_NOP; return 1; } curscore = *(double*)dictGetVal(de); @@ -1404,7 +1402,7 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) { if (incr) { score += curscore; if (isnan(score)) { - *flags |= ZADD_NAN; + *out_flags |= ZADD_OUT_NAN; return 0; } if (newscore) *newscore = score; @@ -1422,18 +1420,18 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) { * the hash table representing the sorted set, so we just * update the score. */ dictGetVal(de) = &znode->score; /* Update score ptr. */ - *flags |= ZADD_UPDATED; + *out_flags |= ZADD_OUT_UPDATED; } return 1; } else if (!xx) { ele = sdsdup(ele); znode = zslInsert(zs->zsl,score,ele); serverAssert(dictAdd(zs->dict,ele,&znode->score) == DICT_OK); - *flags |= ZADD_ADDED; + *out_flags |= ZADD_OUT_ADDED; if (newscore) *newscore = score; return 1; } else { - *flags |= ZADD_NOP; + *out_flags |= ZADD_OUT_NOP; return 1; } } else { @@ -1712,7 +1710,7 @@ void zaddGenericCommand(client *c, int flags) { robj *zobj; sds ele; double score = 0, *scores = NULL; - int j, elements; + int j, elements, ch = 0; int scoreidx = 0; /* The following vars are used in order to track what the command actually * did during the execution, to reply to the client and to trigger the @@ -1727,23 +1725,22 @@ void zaddGenericCommand(client *c, int flags) { scoreidx = 2; while(scoreidx < c->argc) { char *opt = c->argv[scoreidx]->ptr; - if (!strcasecmp(opt,"nx")) flags |= ZADD_NX; - else if (!strcasecmp(opt,"xx")) flags |= ZADD_XX; - else if (!strcasecmp(opt,"ch")) flags |= ZADD_CH; - else if (!strcasecmp(opt,"incr")) flags |= ZADD_INCR; - else if (!strcasecmp(opt,"gt")) flags |= ZADD_GT; - else if (!strcasecmp(opt,"lt")) flags |= ZADD_LT; + if (!strcasecmp(opt,"nx")) flags |= ZADD_IN_NX; + else if (!strcasecmp(opt,"xx")) flags |= ZADD_IN_XX; + else if (!strcasecmp(opt,"ch")) ch = 1; /* Return num of elements added or updated. */ + else if (!strcasecmp(opt,"incr")) flags |= ZADD_IN_INCR; + else if (!strcasecmp(opt,"gt")) flags |= ZADD_IN_GT; + else if (!strcasecmp(opt,"lt")) flags |= ZADD_IN_LT; else break; scoreidx++; } /* Turn options into simple to check vars. */ - int incr = (flags & ZADD_INCR) != 0; - int nx = (flags & ZADD_NX) != 0; - int xx = (flags & ZADD_XX) != 0; - int ch = (flags & ZADD_CH) != 0; - int gt = (flags & ZADD_GT) != 0; - int lt = (flags & ZADD_LT) != 0; + int incr = (flags & ZADD_IN_INCR) != 0; + int nx = (flags & ZADD_IN_NX) != 0; + int xx = (flags & ZADD_IN_XX) != 0; + int gt = (flags & ZADD_IN_GT) != 0; + int lt = (flags & ZADD_IN_LT) != 0; /* After the options, we expect to have an even number of args, since * we expect any number of score-element pairs. */ @@ -1801,17 +1798,17 @@ void zaddGenericCommand(client *c, int flags) { for (j = 0; j < elements; j++) { double newscore; score = scores[j]; - int retflags = flags; + int retflags = 0; ele = c->argv[scoreidx+1+j*2]->ptr; - int retval = zsetAdd(zobj, score, ele, &retflags, &newscore); + int retval = zsetAdd(zobj, score, ele, flags, &retflags, &newscore); if (retval == 0) { addReplyError(c,nanerr); goto cleanup; } - if (retflags & ZADD_ADDED) added++; - if (retflags & ZADD_UPDATED) updated++; - if (!(retflags & ZADD_NOP)) processed++; + if (retflags & ZADD_OUT_ADDED) added++; + if (retflags & ZADD_OUT_UPDATED) updated++; + if (!(retflags & ZADD_OUT_NOP)) processed++; score = newscore; } server.dirty += (added+updated); @@ -1836,11 +1833,11 @@ cleanup: } void zaddCommand(client *c) { - zaddGenericCommand(c,ZADD_NONE); + zaddGenericCommand(c,ZADD_IN_NONE); } void zincrbyCommand(client *c) { - zaddGenericCommand(c,ZADD_INCR); + zaddGenericCommand(c,ZADD_IN_INCR); } void zremCommand(client *c) { @@ -2941,7 +2938,7 @@ static void zrangeResultEmitCBufferForStore(zrange_result_handler *handler, double newscore; int retflags = 0; sds ele = sdsnewlen(value, value_length_in_bytes); - int retval = zsetAdd(handler->dstobj, score, ele, &retflags, &newscore); + int retval = zsetAdd(handler->dstobj, score, ele, ZADD_IN_NONE, &retflags, &newscore); sdsfree(ele); serverAssert(retval); } @@ -2952,7 +2949,7 @@ static void zrangeResultEmitLongLongForStore(zrange_result_handler *handler, double newscore; int retflags = 0; sds ele = sdsfromlonglong(value); - int retval = zsetAdd(handler->dstobj, score, ele, &retflags, &newscore); + int retval = zsetAdd(handler->dstobj, score, ele, ZADD_IN_NONE, &retflags, &newscore); sdsfree(ele); serverAssert(retval); }