summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2013-01-24 16:20:53 +0100
committerantirez <antirez@gmail.com>2013-01-28 13:14:56 +0100
commitda04e6ed44bf80c5e2fe282522f924e8f55921cb (patch)
tree486d054f77c25e9d331b72c4eb2c6682dce2dc29
parent8766e81079dd4e26b0f5e1b04b8fc319b8d13eb7 (diff)
downloadredis-da04e6ed44bf80c5e2fe282522f924e8f55921cb.tar.gz
Keyspace events added for more commands.
-rw-r--r--src/bitops.c3
-rw-r--r--src/db.c2
-rw-r--r--src/sort.c4
-rw-r--r--src/t_hash.c10
-rw-r--r--src/t_list.c46
-rw-r--r--src/t_set.c31
-rw-r--r--src/t_string.c4
-rw-r--r--src/t_zset.c85
8 files changed, 134 insertions, 51 deletions
diff --git a/src/bitops.c b/src/bitops.c
index 75f3317a9..cda3adc7d 100644
--- a/src/bitops.c
+++ b/src/bitops.c
@@ -153,6 +153,7 @@ void setbitCommand(redisClient *c) {
byteval |= ((on & 0x1) << bit);
((uint8_t*)o->ptr)[byte] = byteval;
signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent("setbit",c->argv[1],c->db->id);
server.dirty++;
addReply(c, bitval ? shared.cone : shared.czero);
}
@@ -346,9 +347,11 @@ void bitopCommand(redisClient *c) {
if (maxlen) {
o = createObject(REDIS_STRING,res);
setKey(c->db,targetkey,o);
+ notifyKeyspaceEvent("set",targetkey,c->db->id);
decrRefCount(o);
} else if (dbDelete(c->db,targetkey)) {
signalModifiedKey(c->db,targetkey);
+ notifyKeyspaceEvent("del",targetkey,c->db->id);
}
server.dirty++;
addReplyLongLong(c,maxlen); /* Return the output string length in bytes. */
diff --git a/src/db.c b/src/db.c
index b45c73e5a..10e618246 100644
--- a/src/db.c
+++ b/src/db.c
@@ -587,12 +587,14 @@ void expireGenericCommand(redisClient *c, long long basetime, int unit) {
rewriteClientCommandVector(c,2,aux,key);
decrRefCount(aux);
signalModifiedKey(c->db,key);
+ notifyKeyspaceEvent("del",key,c->db->id);
addReply(c, shared.cone);
return;
} else {
setExpire(c->db,key,when);
addReply(c,shared.cone);
signalModifiedKey(c->db,key);
+ notifyKeyspaceEvent("expire",key,c->db->id);
server.dirty++;
return;
}
diff --git a/src/sort.c b/src/sort.c
index cd54072f3..a0971473d 100644
--- a/src/sort.c
+++ b/src/sort.c
@@ -504,9 +504,11 @@ void sortCommand(redisClient *c) {
}
if (outputlen) {
setKey(c->db,storekey,sobj);
+ notifyKeyspaceEvent("sortstore",storekey,c->db->id);
server.dirty += outputlen;
} else if (dbDelete(c->db,storekey)) {
signalModifiedKey(c->db,storekey);
+ notifyKeyspaceEvent("del",storekey,c->db->id);
server.dirty++;
}
decrRefCount(sobj);
@@ -525,5 +527,3 @@ void sortCommand(redisClient *c) {
}
zfree(vector);
}
-
-
diff --git a/src/t_hash.c b/src/t_hash.c
index 414fb1bf8..e395ee265 100644
--- a/src/t_hash.c
+++ b/src/t_hash.c
@@ -474,6 +474,7 @@ void hsetCommand(redisClient *c) {
update = hashTypeSet(o,c->argv[2],c->argv[3]);
addReply(c, update ? shared.czero : shared.cone);
signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent("hset",c->argv[1],c->db->id);
server.dirty++;
}
@@ -489,6 +490,7 @@ void hsetnxCommand(redisClient *c) {
hashTypeSet(o,c->argv[2],c->argv[3]);
addReply(c, shared.cone);
signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent("hset",c->argv[1],c->db->id);
server.dirty++;
}
}
@@ -510,6 +512,7 @@ void hmsetCommand(redisClient *c) {
}
addReply(c, shared.ok);
signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent("hset",c->argv[1],c->db->id);
server.dirty++;
}
@@ -543,6 +546,7 @@ void hincrbyCommand(redisClient *c) {
decrRefCount(new);
addReplyLongLong(c,value);
signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent("hincrby",c->argv[1],c->db->id);
server.dirty++;
}
@@ -569,6 +573,7 @@ void hincrbyfloatCommand(redisClient *c) {
hashTypeSet(o,c->argv[2],new);
addReplyBulk(c,new);
signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent("hincrbyfloat",c->argv[1],c->db->id);
server.dirty++;
/* Always replicate HINCRBYFLOAT as an HSET command with the final value
@@ -649,7 +654,7 @@ void hmgetCommand(redisClient *c) {
void hdelCommand(redisClient *c) {
robj *o;
- int j, deleted = 0;
+ int j, deleted = 0, keyremoved = 0;
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
checkType(c,o,REDIS_HASH)) return;
@@ -659,12 +664,15 @@ void hdelCommand(redisClient *c) {
deleted++;
if (hashTypeLength(o) == 0) {
dbDelete(c->db,c->argv[1]);
+ keyremoved = 1;
break;
}
}
}
if (deleted) {
signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent("hdel",c->argv[1],c->db->id);
+ if (keyremoved) notifyKeyspaceEvent("del",c->argv[1],c->db->id);
server.dirty += deleted;
}
addReplyLongLong(c,deleted);
diff --git a/src/t_list.c b/src/t_list.c
index d3d3f6c69..ea5f4718d 100644
--- a/src/t_list.c
+++ b/src/t_list.c
@@ -316,7 +316,12 @@ void pushGenericCommand(redisClient *c, int where) {
pushed++;
}
addReplyLongLong(c, waiting + (lobj ? listTypeLength(lobj) : 0));
- if (pushed) signalModifiedKey(c->db,c->argv[1]);
+ if (pushed) {
+ char *event = (where == REDIS_HEAD) ? "lpush" : "rpush";
+
+ signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent(event,c->argv[1],c->db->id);
+ }
server.dirty += pushed;
}
@@ -338,10 +343,6 @@ void pushxGenericCommand(redisClient *c, robj *refval, robj *val, int where) {
checkType(c,subject,REDIS_LIST)) return;
if (refval != NULL) {
- /* Note: we expect refval to be string-encoded because it is *not* the
- * last argument of the multi-bulk LINSERT. */
- redisAssertWithInfo(c,refval,refval->encoding == REDIS_ENCODING_RAW);
-
/* We're not sure if this value can be inserted yet, but we cannot
* convert the list inside the iterator. We don't want to loop over
* the list twice (once to see if the value can be inserted and once
@@ -366,6 +367,7 @@ void pushxGenericCommand(redisClient *c, robj *refval, robj *val, int where) {
ziplistLen(subject->ptr) > server.list_max_ziplist_entries)
listTypeConvert(subject,REDIS_ENCODING_LINKEDLIST);
signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent("linsert",c->argv[1],c->db->id);
server.dirty++;
} else {
/* Notify client of a failed insert */
@@ -373,8 +375,11 @@ void pushxGenericCommand(redisClient *c, robj *refval, robj *val, int where) {
return;
}
} else {
+ char *event = (where == REDIS_HEAD) ? "lpush" : "rpush";
+
listTypePush(subject,val,where);
signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent(event,c->argv[1],c->db->id);
server.dirty++;
}
@@ -469,6 +474,7 @@ void lsetCommand(redisClient *c) {
decrRefCount(value);
addReply(c,shared.ok);
signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent("lset",c->argv[1],c->db->id);
server.dirty++;
}
} else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
@@ -481,6 +487,7 @@ void lsetCommand(redisClient *c) {
incrRefCount(value);
addReply(c,shared.ok);
signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent("lset",c->argv[1],c->db->id);
server.dirty++;
}
} else {
@@ -496,9 +503,15 @@ void popGenericCommand(redisClient *c, int where) {
if (value == NULL) {
addReply(c,shared.nullbulk);
} else {
+ char *event = (where == REDIS_HEAD) ? "lpop" : "rpop";
+
addReplyBulk(c,value);
decrRefCount(value);
- if (listTypeLength(o) == 0) dbDelete(c->db,c->argv[1]);
+ notifyKeyspaceEvent(event,c->argv[1],c->db->id);
+ if (listTypeLength(o) == 0) {
+ notifyKeyspaceEvent("del",c->argv[1],c->db->id);
+ dbDelete(c->db,c->argv[1]);
+ }
signalModifiedKey(c->db,c->argv[1]);
server.dirty++;
}
@@ -618,7 +631,12 @@ void ltrimCommand(redisClient *c) {
} else {
redisPanic("Unknown list encoding");
}
- if (listTypeLength(o) == 0) dbDelete(c->db,c->argv[1]);
+
+ notifyKeyspaceEvent("ltrim",c->argv[1],c->db->id);
+ if (listTypeLength(o) == 0) {
+ dbDelete(c->db,c->argv[1]);
+ notifyKeyspaceEvent("del",c->argv[1],c->db->id);
+ }
signalModifiedKey(c->db,c->argv[1]);
server.dirty++;
addReply(c,shared.ok);
@@ -693,6 +711,7 @@ void rpoplpushHandlePush(redisClient *c, robj *dstkey, robj *dstobj, robj *value
}
signalModifiedKey(c->db,dstkey);
listTypePush(dstobj,value,REDIS_HEAD);
+ notifyKeyspaceEvent("lpush",dstkey,c->db->id);
/* Always send the pushed value to the client. */
addReplyBulk(c,value);
}
@@ -722,7 +741,11 @@ void rpoplpushCommand(redisClient *c) {
decrRefCount(value);
/* Delete the source list when it is empty */
- if (listTypeLength(sobj) == 0) dbDelete(c->db,touchedkey);
+ notifyKeyspaceEvent("rpop",touchedkey,c->db->id);
+ if (listTypeLength(sobj) == 0) {
+ dbDelete(c->db,touchedkey);
+ notifyKeyspaceEvent("del",touchedkey,c->db->id);
+ }
signalModifiedKey(c->db,touchedkey);
decrRefCount(touchedkey);
server.dirty++;
@@ -1046,6 +1069,7 @@ void blockingPopGenericCommand(redisClient *c, int where) {
} else {
if (listTypeLength(o) != 0) {
/* Non empty list, this is like a non normal [LR]POP. */
+ char *event = (where == REDIS_HEAD) ? "lpop" : "rpop";
robj *value = listTypePop(o,where);
redisAssert(value != NULL);
@@ -1053,7 +1077,11 @@ void blockingPopGenericCommand(redisClient *c, int where) {
addReplyBulk(c,c->argv[j]);
addReplyBulk(c,value);
decrRefCount(value);
- if (listTypeLength(o) == 0) dbDelete(c->db,c->argv[j]);
+ notifyKeyspaceEvent(event,c->argv[j],c->db->id);
+ if (listTypeLength(o) == 0) {
+ dbDelete(c->db,c->argv[j]);
+ notifyKeyspaceEvent("del",c->argv[j],c->db->id);
+ }
signalModifiedKey(c->db,c->argv[j]);
server.dirty++;
diff --git a/src/t_set.c b/src/t_set.c
index 0909d0301..70052a55e 100644
--- a/src/t_set.c
+++ b/src/t_set.c
@@ -266,14 +266,17 @@ void saddCommand(redisClient *c) {
c->argv[j] = tryObjectEncoding(c->argv[j]);
if (setTypeAdd(set,c->argv[j])) added++;
}
- if (added) signalModifiedKey(c->db,c->argv[1]);
+ if (added) {
+ signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent("sadd",c->argv[1],c->db->id);
+ }
server.dirty += added;
addReplyLongLong(c,added);
}
void sremCommand(redisClient *c) {
robj *set;
- int j, deleted = 0;
+ int j, deleted = 0, keyremoved = 0;
if ((set = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
checkType(c,set,REDIS_SET)) return;
@@ -283,12 +286,15 @@ void sremCommand(redisClient *c) {
deleted++;
if (setTypeSize(set) == 0) {
dbDelete(c->db,c->argv[1]);
+ keyremoved = 1;
break;
}
}
}
if (deleted) {
signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent("srem",c->argv[1],c->db->id);
+ if (keyremoved) notifyKeyspaceEvent("del",c->argv[1],c->db->id);
server.dirty += deleted;
}
addReplyLongLong(c,deleted);
@@ -322,9 +328,13 @@ void smoveCommand(redisClient *c) {
addReply(c,shared.czero);
return;
}
+ notifyKeyspaceEvent("srem",c->argv[1],c->db->id);
/* Remove the src set from the database when empty */
- if (setTypeSize(srcset) == 0) dbDelete(c->db,c->argv[1]);
+ if (setTypeSize(srcset) == 0) {
+ dbDelete(c->db,c->argv[1]);
+ notifyKeyspaceEvent("del",c->argv[1],c->db->id);
+ }
signalModifiedKey(c->db,c->argv[1]);
signalModifiedKey(c->db,c->argv[2]);
server.dirty++;
@@ -336,7 +346,10 @@ void smoveCommand(redisClient *c) {
}
/* An extra key has changed when ele was successfully added to dstset */
- if (setTypeAdd(dstset,ele)) server.dirty++;
+ if (setTypeAdd(dstset,ele)) {
+ server.dirty++;
+ notifyKeyspaceEvent("sadd",c->argv[2],c->db->id);
+ }
addReply(c,shared.cone);
}
@@ -378,6 +391,7 @@ void spopCommand(redisClient *c) {
incrRefCount(ele);
setTypeRemove(set,ele);
}
+ notifyKeyspaceEvent("spop",c->argv[1],c->db->id);
/* Replicate/AOF this command as an SREM operation */
aux = createStringObject("SREM",4);
@@ -386,7 +400,10 @@ void spopCommand(redisClient *c) {
decrRefCount(aux);
addReplyBulk(c,ele);
- if (setTypeSize(set) == 0) dbDelete(c->db,c->argv[1]);
+ if (setTypeSize(set) == 0) {
+ dbDelete(c->db,c->argv[1]);
+ notifyKeyspaceEvent("del",c->argv[1],c->db->id);
+ }
signalModifiedKey(c->db,c->argv[1]);
server.dirty++;
}
@@ -691,6 +708,7 @@ void sinterGenericCommand(redisClient *c, robj **setkeys, unsigned long setnum,
if (setTypeSize(dstset) > 0) {
dbAdd(c->db,dstkey,dstset);
addReplyLongLong(c,setTypeSize(dstset));
+ notifyKeyspaceEvent("sinterstore",dstkey,c->db->id);
} else {
decrRefCount(dstset);
addReply(c,shared.czero);
@@ -856,6 +874,9 @@ void sunionDiffGenericCommand(redisClient *c, robj **setkeys, int setnum, robj *
if (setTypeSize(dstset) > 0) {
dbAdd(c->db,dstkey,dstset);
addReplyLongLong(c,setTypeSize(dstset));
+ notifyKeyspaceEvent(
+ op == REDIS_OP_UNION ? "sunionstore" : "sdiffstore",
+ dstkey,c->db->id);
} else {
decrRefCount(dstset);
addReply(c,shared.czero);
diff --git a/src/t_string.c b/src/t_string.c
index a3e58e5b9..ed7840467 100644
--- a/src/t_string.c
+++ b/src/t_string.c
@@ -110,6 +110,7 @@ void getsetCommand(redisClient *c) {
if (getGenericCommand(c) == REDIS_ERR) return;
c->argv[2] = tryObjectEncoding(c->argv[2]);
setKey(c->db,c->argv[1],c->argv[2]);
+ notifyKeyspaceEvent("set",c->argv[1],c->db->id);
server.dirty++;
}
@@ -171,6 +172,7 @@ void setrangeCommand(redisClient *c) {
o->ptr = sdsgrowzero(o->ptr,offset+sdslen(value));
memcpy((char*)o->ptr+offset,value,sdslen(value));
signalModifiedKey(c->db,c->argv[1]);
+ notifyKeyspaceEvent("setrange",c->argv[1],c->db->id);
server.dirty++;
}
addReplyLongLong(c,sdslen(o->ptr));
@@ -255,7 +257,7 @@ void msetGenericCommand(redisClient *c, int nx) {
for (j = 1; j < c->argc; j += 2) {
c->argv[j+1] = tryObjectEncoding(c->argv[j+1]);
setKey(c->db,c->argv[j],c->argv[j+1]);
- notifyKeyspaceEvent("set",c->argv[j+1],c->db->id);
+ notifyKeyspaceEvent("set",c->argv[j],c->db->id);
}
server.dirty += (c->argc-1)/2;
addReply(c, nx ? shared.cone : shared.ok);
diff --git a/src/t_zset.c b/src/t_zset.c
index 0d92f681f..4a9383c12 100644
--- a/src/t_zset.c
+++ b/src/t_zset.c
@@ -844,9 +844,9 @@ void zaddGenericCommand(redisClient *c, int incr) {
robj *ele;
robj *zobj;
robj *curobj;
- double score = 0, *scores, curscore = 0.0;
+ double score = 0, *scores = NULL, curscore = 0.0;
int j, elements = (c->argc-2)/2;
- int added = 0;
+ int added = 0, updated = 0;
if (c->argc % 2) {
addReply(c,shared.syntaxerr);
@@ -859,11 +859,7 @@ void zaddGenericCommand(redisClient *c, int incr) {
scores = zmalloc(sizeof(double)*elements);
for (j = 0; j < elements; j++) {
if (getDoubleFromObjectOrReply(c,c->argv[2+j*2],&scores[j],NULL)
- != REDIS_OK)
- {
- zfree(scores);
- return;
- }
+ != REDIS_OK) goto cleanup;
}
/* Lookup the key and create the sorted set if does not exist. */
@@ -880,8 +876,7 @@ void zaddGenericCommand(redisClient *c, int incr) {
} else {
if (zobj->type != REDIS_ZSET) {
addReply(c,shared.wrongtypeerr);
- zfree(scores);
- return;
+ goto cleanup;
}
}
@@ -898,10 +893,7 @@ void zaddGenericCommand(redisClient *c, int incr) {
score += curscore;
if (isnan(score)) {
addReplyError(c,nanerr);
- /* Don't need to check if the sorted set is empty
- * because we know it has at least one element. */
- zfree(scores);
- return;
+ goto cleanup;
}
}
@@ -909,9 +901,8 @@ void zaddGenericCommand(redisClient *c, int incr) {
if (score != curscore) {
zobj->ptr = zzlDelete(zobj->ptr,eptr);
zobj->ptr = zzlInsert(zobj->ptr,ele,score);
-
- signalModifiedKey(c->db,key);
server.dirty++;
+ updated++;
}
} else {
/* Optimize: check if the element is too large or the list
@@ -921,10 +912,8 @@ void zaddGenericCommand(redisClient *c, int incr) {
zsetConvert(zobj,REDIS_ENCODING_SKIPLIST);
if (sdslen(ele->ptr) > server.zset_max_ziplist_value)
zsetConvert(zobj,REDIS_ENCODING_SKIPLIST);
-
- signalModifiedKey(c->db,key);
server.dirty++;
- if (!incr) added++;
+ added++;
}
} else if (zobj->encoding == REDIS_ENCODING_SKIPLIST) {
zset *zs = zobj->ptr;
@@ -943,8 +932,7 @@ void zaddGenericCommand(redisClient *c, int incr) {
addReplyError(c,nanerr);
/* Don't need to check if the sorted set is empty
* because we know it has at least one element. */
- zfree(scores);
- return;
+ goto cleanup;
}
}
@@ -956,29 +944,32 @@ void zaddGenericCommand(redisClient *c, int incr) {
znode = zslInsert(zs->zsl,score,curobj);
incrRefCount(curobj); /* Re-inserted in skiplist. */
dictGetVal(de) = &znode->score; /* Update score ptr. */
-
- signalModifiedKey(c->db,key);
server.dirty++;
+ updated++;
}
} else {
znode = zslInsert(zs->zsl,score,ele);
incrRefCount(ele); /* Inserted in skiplist. */
redisAssertWithInfo(c,NULL,dictAdd(zs->dict,ele,&znode->score) == DICT_OK);
incrRefCount(ele); /* Added to dictionary. */
-
- signalModifiedKey(c->db,key);
server.dirty++;
- if (!incr) added++;
+ added++;
}
} else {
redisPanic("Unknown sorted set encoding");
}
}
- zfree(scores);
if (incr) /* ZINCRBY */
addReplyDouble(c,score);
else /* ZADD */
addReplyLongLong(c,added);
+
+cleanup:
+ zfree(scores);
+ if (added || updated) {
+ signalModifiedKey(c->db,key);
+ notifyKeyspaceEvent(incr ? "zincr" : "zadd", key, c->db->id);
+ }
}
void zaddCommand(redisClient *c) {
@@ -992,7 +983,7 @@ void zincrbyCommand(redisClient *c) {
void zremCommand(redisClient *c) {
robj *key = c->argv[1];
robj *zobj;
- int deleted = 0, j;
+ int deleted = 0, keyremoved = 0, j;
if ((zobj = lookupKeyWriteOrReply(c,key,shared.czero)) == NULL ||
checkType(c,zobj,REDIS_ZSET)) return;
@@ -1038,6 +1029,8 @@ void zremCommand(redisClient *c) {
}
if (deleted) {
+ notifyKeyspaceEvent("zrem",key,c->db->id);
+ if (keyremoved) notifyKeyspaceEvent("del",key,c->db->id);
signalModifiedKey(c->db,key);
server.dirty += deleted;
}
@@ -1048,6 +1041,7 @@ void zremrangebyscoreCommand(redisClient *c) {
robj *key = c->argv[1];
robj *zobj;
zrangespec range;
+ int keyremoved = 0;
unsigned long deleted;
/* Parse the range arguments. */
@@ -1061,17 +1055,27 @@ void zremrangebyscoreCommand(redisClient *c) {
if (zobj->encoding == REDIS_ENCODING_ZIPLIST) {
zobj->ptr = zzlDeleteRangeByScore(zobj->ptr,range,&deleted);
- if (zzlLength(zobj->ptr) == 0) dbDelete(c->db,key);
+ if (zzlLength(zobj->ptr) == 0) {
+ dbDelete(c->db,key);
+ keyremoved = 1;
+ }
} else if (zobj->encoding == REDIS_ENCODING_SKIPLIST) {
zset *zs = zobj->ptr;
deleted = zslDeleteRangeByScore(zs->zsl,range,zs->dict);
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
- if (dictSize(zs->dict) == 0) dbDelete(c->db,key);
+ if (dictSize(zs->dict) == 0) {
+ dbDelete(c->db,key);
+ keyremoved = 1;
+ }
} else {
redisPanic("Unknown sorted set encoding");
}
- if (deleted) signalModifiedKey(c->db,key);
+ if (deleted) {
+ signalModifiedKey(c->db,key);
+ notifyKeyspaceEvent("zrembyscore",key,c->db->id);
+ if (keyremoved) notifyKeyspaceEvent("del",key,c->db->id);
+ }
server.dirty += deleted;
addReplyLongLong(c,deleted);
}
@@ -1083,6 +1087,7 @@ void zremrangebyrankCommand(redisClient *c) {
long end;
int llen;
unsigned long deleted;
+ int keyremoved = 0;
if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != REDIS_OK) ||
(getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != REDIS_OK)) return;
@@ -1107,19 +1112,29 @@ void zremrangebyrankCommand(redisClient *c) {
if (zobj->encoding == REDIS_ENCODING_ZIPLIST) {
/* Correct for 1-based rank. */
zobj->ptr = zzlDeleteRangeByRank(zobj->ptr,start+1,end+1,&deleted);
- if (zzlLength(zobj->ptr) == 0) dbDelete(c->db,key);
+ if (zzlLength(zobj->ptr) == 0) {
+ dbDelete(c->db,key);
+ keyremoved = 1;
+ }
} else if (zobj->encoding == REDIS_ENCODING_SKIPLIST) {
zset *zs = zobj->ptr;
/* Correct for 1-based rank. */
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,key);
+ if (dictSize(zs->dict) == 0) {
+ dbDelete(c->db,key);
+ keyremoved = 1;
+ }
} else {
redisPanic("Unknown sorted set encoding");
}
- if (deleted) signalModifiedKey(c->db,key);
+ if (deleted) {
+ signalModifiedKey(c->db,key);
+ notifyKeyspaceEvent("zrembyrank",key,c->db->id);
+ if (keyremoved) notifyKeyspaceEvent("del",key,c->db->id);
+ }
server.dirty += deleted;
addReplyLongLong(c,deleted);
}
@@ -1661,6 +1676,7 @@ void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) {
if (dbDelete(c->db,dstkey)) {
signalModifiedKey(c->db,dstkey);
+ notifyKeyspaceEvent("del",dstkey,c->db->id);
touched = 1;
server.dirty++;
}
@@ -1673,6 +1689,9 @@ void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) {
dbAdd(c->db,dstkey,dstobj);
addReplyLongLong(c,zsetLength(dstobj));
if (!touched) signalModifiedKey(c->db,dstkey);
+ notifyKeyspaceEvent(
+ (op == REDIS_OP_UNION) ? "zunionstore" : "zinterstore",
+ dstkey,c->db->id);
server.dirty++;
} else {
decrRefCount(dstobj);