diff options
Diffstat (limited to 'src/t_zset.c')
-rw-r--r-- | src/t_zset.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/src/t_zset.c b/src/t_zset.c index 4b28c24ef..2ef02ac8a 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -1283,6 +1283,10 @@ int zsetScore(robj *zobj, sds member, double *score) { * assume 0 as previous score. * ZADD_NX: Perform the operation only if the element does not exist. * ZADD_XX: Perform the operation only if the element already exist. + * ZADD_GT: Perform the operation on existing elements only if the new score is + * greater than the current score. + * ZADD_LT: Perform the operation on existing elements only if the new score is + * less than the current score. * * When ZADD_INCR is used, the new score of the element is stored in * '*newscore' if 'newscore' is not NULL. @@ -1317,6 +1321,8 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) { 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. */ double curscore; @@ -1348,7 +1354,12 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) { } /* Remove and re-insert when score changed. */ - if (score != curscore) { + if (score != curscore && + /* LT? Only update if score is less than current. */ + (!lt || score < curscore) && + /* GT? Only update if score is greater than current. */ + (!gt || score > curscore)) + { zobj->ptr = zzlDelete(zobj->ptr,eptr); zobj->ptr = zzlInsert(zobj->ptr,ele,score); *flags |= ZADD_UPDATED; @@ -1393,7 +1404,12 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore) { } /* Remove and re-insert when score changes. */ - if (score != curscore) { + if (score != curscore && + /* LT? Only update if score is less than current. */ + (!lt || score < curscore) && + /* GT? Only update if score is greater than current. */ + (!gt || score > curscore)) + { znode = zslUpdateScore(zs->zsl,curscore,ele,score); /* Note that we did not removed the original element from * the hash table representing the sorted set, so we just @@ -1555,6 +1571,8 @@ void zaddGenericCommand(client *c, int flags) { 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; else break; scoreidx++; } @@ -1564,6 +1582,8 @@ void zaddGenericCommand(client *c, int flags) { 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; /* After the options, we expect to have an even number of args, since * we expect any number of score-element pairs. */ @@ -1580,6 +1600,13 @@ void zaddGenericCommand(client *c, int flags) { "XX and NX options at the same time are not compatible"); return; } + + if ((gt && nx) || (lt && nx) || (gt && lt)) { + addReplyError(c, + "GT, LT, and/or NX options at the same time are not compatible"); + return; + } + /* Note that XX is compatible with either GT or LT */ if (incr && elements > 1) { addReplyError(c, |