incrRefCount(ele); /* added to hash */
zslInsert(zs->zsl,*score,ele);
incrRefCount(ele); /* added to skiplist */
+ touchWatchedKey(c->db,c->argv[1]);
server.dirty++;
if (doincrement)
addReplyDouble(c,*score);
incrRefCount(ele);
/* Update the score in the hash table */
dictReplace(zs->dict,ele,score);
+ touchWatchedKey(c->db,c->argv[1]);
server.dirty++;
} else {
zfree(score);
dictDelete(zs->dict,c->argv[2]);
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
if (dictSize(zs->dict) == 0) dbDelete(c->db,c->argv[1]);
+ touchWatchedKey(c->db,c->argv[1]);
server.dirty++;
addReply(c,shared.cone);
}
deleted = zslDeleteRangeByScore(zs->zsl,min,max,zs->dict);
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
if (dictSize(zs->dict) == 0) dbDelete(c->db,c->argv[1]);
+ if (deleted) touchWatchedKey(c->db,c->argv[1]);
server.dirty += deleted;
addReplyLongLong(c,deleted);
}
if (start < 0) start = llen+start;
if (end < 0) end = llen+end;
if (start < 0) start = 0;
- if (end < 0) end = 0;
- /* indexes sanity checks */
+ /* Invariant: start >= 0, so this test will be true when end < 0.
+ * The range is empty when start > end or start >= length. */
if (start > end || start >= llen) {
addReply(c,shared.czero);
return;
deleted = zslDeleteRangeByRank(zs->zsl,start+1,end+1,zs->dict);
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
if (dictSize(zs->dict) == 0) dbDelete(c->db,c->argv[1]);
+ if (deleted) touchWatchedKey(c->db,c->argv[1]);
server.dirty += deleted;
addReplyLongLong(c, deleted);
}
inline static void zunionInterAggregate(double *target, double val, int aggregate) {
if (aggregate == REDIS_AGGR_SUM) {
*target = *target + val;
+ /* The result of adding two doubles is NaN when one variable
+ * is +inf and the other is -inf. When these numbers are added,
+ * we maintain the convention of the result being 0.0. */
+ if (isnan(*target)) *target = 0.0;
} else if (aggregate == REDIS_AGGR_MIN) {
*target = val < *target ? val : *target;
} else if (aggregate == REDIS_AGGR_MAX) {
zset *dstzset;
dictIterator *di;
dictEntry *de;
+ int touched = 0;
/* expect setnum input keys to be given */
setnum = atoi(c->argv[2]->ptr);
redisAssert(op == REDIS_OP_INTER || op == REDIS_OP_UNION);
}
- dbDelete(c->db,dstkey);
+ if (dbDelete(c->db,dstkey)) {
+ touchWatchedKey(c->db,dstkey);
+ touched = 1;
+ server.dirty++;
+ }
if (dstzset->zsl->length) {
dbAdd(c->db,dstkey,dstobj);
addReplyLongLong(c, dstzset->zsl->length);
+ if (!touched) touchWatchedKey(c->db,dstkey);
server.dirty++;
} else {
decrRefCount(dstobj);
if (start < 0) start = llen+start;
if (end < 0) end = llen+end;
if (start < 0) start = 0;
- if (end < 0) end = 0;
- /* indexes sanity checks */
+ /* Invariant: start >= 0, so this test will be true when end < 0.
+ * The range is empty when start > end or start >= length. */
if (start > end || start >= llen) {
- /* Out of range start or start > end result in empty list */
addReply(c,shared.emptymultibulk);
return;
}