]> git.saurik.com Git - redis.git/commitdiff
WATCH is now affected only when write commands actually modify the key content
authorantirez <antirez@gmail.com>
Mon, 12 Jul 2010 10:01:15 +0000 (12:01 +0200)
committerantirez <antirez@gmail.com>
Mon, 12 Jul 2010 10:01:15 +0000 (12:01 +0200)
TODO
src/db.c
src/sort.c
src/t_hash.c
src/t_list.c
src/t_set.c
src/t_string.c
src/t_zset.c

diff --git a/TODO b/TODO
index 5d9736a9b71c5978c737506917661dc10a011f88..dbde9bb59f1bf3c62c083db843492650e378901e 100644 (file)
--- a/TODO
+++ b/TODO
@@ -4,7 +4,9 @@ Redis TODO and Roadmap
 VERSION 2.2 TODO (Optimizations and latency)
 ============================================
 
+* SETNX when failing should not affect WATCH
 * Support for syslog(3).
+* Document ZCOUNT.
 * Change the implementation of ZCOUNT to use the augmented skiplist in order to be much faster.
 * Add an explicit test for MULTI/EXEC reloaded in the AOF.
 
index d5e0d1e8425f65855d3c74c675da671bcede9f24..958a9f6bc536937b3d31fdb86bf55b397df39cba 100644 (file)
--- a/src/db.c
+++ b/src/db.c
@@ -46,7 +46,6 @@ robj *lookupKeyRead(redisDb *db, robj *key) {
 
 robj *lookupKeyWrite(redisDb *db, robj *key) {
     deleteIfVolatile(db,key);
-    touchWatchedKey(db,key);
     return lookupKey(db,key);
 }
 
@@ -332,6 +331,7 @@ void renameGenericCommand(redisClient *c, int nx) {
         dbReplace(c->db,c->argv[2],o);
     }
     dbDelete(c->db,c->argv[1]);
+    touchWatchedKey(c->db,c->argv[1]);
     touchWatchedKey(c->db,c->argv[2]);
     server.dirty++;
     addReply(c,nx ? shared.cone : shared.ok);
@@ -506,5 +506,3 @@ void ttlCommand(redisClient *c) {
     }
     addReplySds(c,sdscatprintf(sdsempty(),":%d\r\n",ttl));
 }
-
-
index 0bc86b474246ea9aea38b219f935b7b5c5963e1a..4295a6ecca4da627725697700c1b79a93636db79 100644 (file)
@@ -364,6 +364,7 @@ void sortCommand(redisClient *c) {
          * SORT result is empty a new key is set and maybe the old content
          * replaced. */
         server.dirty += 1+outputlen;
+        touchWatchedKey(c->db,storekey);
         addReplySds(c,sdscatprintf(sdsempty(),":%d\r\n",outputlen));
     }
 
index 3f5fd6e16ef7f12817f423583075df528a6fbe7a..b6be284fa12d58bce12ccc8808c7a481f20453e2 100644 (file)
@@ -224,6 +224,7 @@ void hsetCommand(redisClient *c) {
     hashTypeTryObjectEncoding(o,&c->argv[2], &c->argv[3]);
     update = hashTypeSet(o,c->argv[2],c->argv[3]);
     addReply(c, update ? shared.czero : shared.cone);
+    touchWatchedKey(c->db,c->argv[1]);
     server.dirty++;
 }
 
@@ -238,6 +239,7 @@ void hsetnxCommand(redisClient *c) {
         hashTypeTryObjectEncoding(o,&c->argv[2], &c->argv[3]);
         hashTypeSet(o,c->argv[2],c->argv[3]);
         addReply(c, shared.cone);
+        touchWatchedKey(c->db,c->argv[1]);
         server.dirty++;
     }
 }
@@ -258,6 +260,7 @@ void hmsetCommand(redisClient *c) {
         hashTypeSet(o,c->argv[i],c->argv[i+1]);
     }
     addReply(c, shared.ok);
+    touchWatchedKey(c->db,c->argv[1]);
     server.dirty++;
 }
 
@@ -284,6 +287,7 @@ void hincrbyCommand(redisClient *c) {
     hashTypeSet(o,c->argv[2],new);
     decrRefCount(new);
     addReplyLongLong(c,value);
+    touchWatchedKey(c->db,c->argv[1]);
     server.dirty++;
 }
 
@@ -330,6 +334,7 @@ void hdelCommand(redisClient *c) {
     if (hashTypeDelete(o,c->argv[2])) {
         if (hashTypeLength(o) == 0) dbDelete(c->db,c->argv[1]);
         addReply(c,shared.cone);
+        touchWatchedKey(c->db,c->argv[1]);
         server.dirty++;
     } else {
         addReply(c,shared.czero);
index 0568fff119d47eba28b9896f31cdec9c1419eb49..2a98103333b71d9014983b78e0b05ea6fe8cccd9 100644 (file)
@@ -273,12 +273,14 @@ void pushGenericCommand(redisClient *c, int where) {
             return;
         }
         if (handleClientsWaitingListPush(c,c->argv[1],c->argv[2])) {
+            touchWatchedKey(c->db,c->argv[1]);
             addReply(c,shared.cone);
             return;
         }
     }
     listTypePush(lobj,c->argv[2],where);
     addReplyLongLong(c,listTypeLength(lobj));
+    touchWatchedKey(c->db,c->argv[1]);
     server.dirty++;
 }
 
@@ -327,6 +329,7 @@ void pushxGenericCommand(redisClient *c, robj *refval, robj *val, int where) {
             if (subject->encoding == REDIS_ENCODING_ZIPLIST &&
                 ziplistLen(subject->ptr) > server.list_max_ziplist_entries)
                     listTypeConvert(subject,REDIS_ENCODING_LINKEDLIST);
+            touchWatchedKey(c->db,c->argv[1]);
             server.dirty++;
         } else {
             /* Notify client of a failed insert */
@@ -335,6 +338,7 @@ void pushxGenericCommand(redisClient *c, robj *refval, robj *val, int where) {
         }
     } else {
         listTypePush(subject,val,where);
+        touchWatchedKey(c->db,c->argv[1]);
         server.dirty++;
     }
 
@@ -419,6 +423,7 @@ void lsetCommand(redisClient *c) {
             o->ptr = ziplistInsert(o->ptr,p,value->ptr,sdslen(value->ptr));
             decrRefCount(value);
             addReply(c,shared.ok);
+            touchWatchedKey(c->db,c->argv[1]);
             server.dirty++;
         }
     } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
@@ -430,6 +435,7 @@ void lsetCommand(redisClient *c) {
             listNodeValue(ln) = value;
             incrRefCount(value);
             addReply(c,shared.ok);
+            touchWatchedKey(c->db,c->argv[1]);
             server.dirty++;
         }
     } else {
@@ -448,6 +454,7 @@ void popGenericCommand(redisClient *c, int where) {
         addReplyBulk(c,value);
         decrRefCount(value);
         if (listTypeLength(o) == 0) dbDelete(c->db,c->argv[1]);
+        touchWatchedKey(c->db,c->argv[1]);
         server.dirty++;
     }
 }
@@ -546,6 +553,7 @@ void ltrimCommand(redisClient *c) {
         redisPanic("Unknown list encoding");
     }
     if (listTypeLength(o) == 0) dbDelete(c->db,c->argv[1]);
+    touchWatchedKey(c->db,c->argv[1]);
     server.dirty++;
     addReply(c,shared.ok);
 }
@@ -587,6 +595,7 @@ void lremCommand(redisClient *c) {
 
     if (listTypeLength(subject) == 0) dbDelete(c->db,c->argv[1]);
     addReplySds(c,sdscatprintf(sdsempty(),":%d\r\n",removed));
+    if (removed) touchWatchedKey(c->db,c->argv[1]);
 }
 
 /* This is the semantic of this command:
@@ -635,6 +644,7 @@ void rpoplpushcommand(redisClient *c) {
 
         /* Delete the source list when it is empty */
         if (listTypeLength(sobj) == 0) dbDelete(c->db,c->argv[1]);
+        touchWatchedKey(c->db,c->argv[1]);
         server.dirty++;
     }
 }
index 808ef268ebccd610bf263aaab2c4e61f247406c0..94b97633e83f0e1cfaeac0cb39d27beaba6ed270 100644 (file)
@@ -19,6 +19,7 @@ void saddCommand(redisClient *c) {
     }
     if (dictAdd(set->ptr,c->argv[2],NULL) == DICT_OK) {
         incrRefCount(c->argv[2]);
+        touchWatchedKey(c->db,c->argv[1]);
         server.dirty++;
         addReply(c,shared.cone);
     } else {
@@ -34,6 +35,7 @@ void sremCommand(redisClient *c) {
 
     if (dictDelete(set->ptr,c->argv[2]) == DICT_OK) {
         server.dirty++;
+        touchWatchedKey(c->db,c->argv[1]);
         if (htNeedsResize(set->ptr)) dictResize(set->ptr);
         if (dictSize((dict*)set->ptr) == 0) dbDelete(c->db,c->argv[1]);
         addReply(c,shared.cone);
@@ -67,6 +69,8 @@ void smoveCommand(redisClient *c) {
     }
     if (dictSize((dict*)srcset->ptr) == 0 && srcset != dstset)
         dbDelete(c->db,c->argv[1]);
+    touchWatchedKey(c->db,c->argv[1]);
+    touchWatchedKey(c->db,c->argv[2]);
     server.dirty++;
     /* Add the element to the destination set */
     if (!dstset) {
@@ -118,6 +122,7 @@ void spopCommand(redisClient *c) {
         dictDelete(set->ptr,ele);
         if (htNeedsResize(set->ptr)) dictResize(set->ptr);
         if (dictSize((dict*)set->ptr) == 0) dbDelete(c->db,c->argv[1]);
+        touchWatchedKey(c->db,c->argv[1]);
         server.dirty++;
     }
 }
@@ -161,8 +166,10 @@ void sinterGenericCommand(redisClient *c, robj **setskeys, unsigned long setsnum
         if (!setobj) {
             zfree(dv);
             if (dstkey) {
-                if (dbDelete(c->db,dstkey))
+                if (dbDelete(c->db,dstkey)) {
+                    touchWatchedKey(c->db,dstkey);
                     server.dirty++;
+                }
                 addReply(c,shared.czero);
             } else {
                 addReply(c,shared.emptymultibulk);
@@ -229,6 +236,7 @@ void sinterGenericCommand(redisClient *c, robj **setskeys, unsigned long setsnum
             decrRefCount(dstset);
             addReply(c,shared.czero);
         }
+        touchWatchedKey(c->db,dstkey);
         server.dirty++;
     } else {
         lenobj->ptr = sdscatprintf(sdsempty(),"*%lu\r\n",cardinality);
@@ -327,6 +335,7 @@ void sunionDiffGenericCommand(redisClient *c, robj **setskeys, int setsnum, robj
             decrRefCount(dstset);
             addReply(c,shared.czero);
         }
+        touchWatchedKey(c->db,dstkey);
         server.dirty++;
     }
     zfree(dv);
index eaaec05bebf0e9c75dd0c4299e1d7666599e2a35..281bd6be942372ed74fae41ba01816b12533ab4a 100644 (file)
@@ -17,7 +17,6 @@ void setGenericCommand(redisClient *c, int nx, robj *key, robj *val, robj *expir
         }
     }
 
-    touchWatchedKey(c->db,key);
     if (nx) deleteIfVolatile(c->db,key);
     retval = dbAdd(c->db,key,val);
     if (retval == REDIS_ERR) {
@@ -31,6 +30,7 @@ void setGenericCommand(redisClient *c, int nx, robj *key, robj *val, robj *expir
     } else {
         incrRefCount(val);
     }
+    touchWatchedKey(c->db,key);
     server.dirty++;
     removeExpire(c->db,key);
     if (expire) setExpire(c->db,key,time(NULL)+seconds);
@@ -72,6 +72,7 @@ void getsetCommand(redisClient *c) {
     if (getGenericCommand(c) == REDIS_ERR) return;
     dbReplace(c->db,c->argv[1],c->argv[2]);
     incrRefCount(c->argv[2]);
+    touchWatchedKey(c->db,c->argv[1]);
     server.dirty++;
     removeExpire(c->db,c->argv[1]);
 }
@@ -120,6 +121,7 @@ void msetGenericCommand(redisClient *c, int nx) {
         dbReplace(c->db,c->argv[j],c->argv[j+1]);
         incrRefCount(c->argv[j+1]);
         removeExpire(c->db,c->argv[j]);
+        touchWatchedKey(c->db,c->argv[j]);
     }
     server.dirty += (c->argc-1)/2;
     addReply(c, nx ? shared.cone : shared.ok);
@@ -144,6 +146,7 @@ void incrDecrCommand(redisClient *c, long long incr) {
     value += incr;
     o = createStringObjectFromLongLong(value);
     dbReplace(c->db,c->argv[1],o);
+    touchWatchedKey(c->db,c->argv[1]);
     server.dirty++;
     addReply(c,shared.colon);
     addReply(c,o);
@@ -207,6 +210,7 @@ void appendCommand(redisClient *c) {
         }
         totlen = sdslen(o->ptr);
     }
+    touchWatchedKey(c->db,c->argv[1]);
     server.dirty++;
     addReplySds(c,sdscatprintf(sdsempty(),":%lu\r\n",(unsigned long)totlen));
 }
index 26a80e994f793e7cb64e92901895229380e0e15a..0fcd6ea362c79c59febfe6850e1ecaf709787fb7 100644 (file)
@@ -379,6 +379,7 @@ void zaddGenericCommand(redisClient *c, robj *key, robj *ele, double scoreval, i
         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);
@@ -402,6 +403,7 @@ void zaddGenericCommand(redisClient *c, robj *key, robj *ele, double scoreval, i
             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);
@@ -452,6 +454,7 @@ void zremCommand(redisClient *c) {
     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);
 }
@@ -473,6 +476,7 @@ void zremrangebyscoreCommand(redisClient *c) {
     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);
 }
@@ -511,6 +515,7 @@ void zremrangebyrankCommand(redisClient *c) {
     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);
 }
@@ -702,6 +707,7 @@ void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) {
     if (dstzset->zsl->length) {
         dbAdd(c->db,dstkey,dstobj);
         addReplyLongLong(c, dstzset->zsl->length);
+        touchWatchedKey(c->db,dstkey);
         server.dirty++;
     } else {
         decrRefCount(dstobj);