mirror of
https://github.com/fluencelabs/redis
synced 2025-03-17 08:00:49 +00:00
WATCH is now affected only when write commands actually modify the key content
This commit is contained in:
parent
e51a74aa40
commit
5b4bff9c17
2
TODO
2
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.
|
||||
|
||||
|
4
src/db.c
4
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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
10
src/t_list.c
10
src/t_list.c
@ -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++;
|
||||
}
|
||||
}
|
||||
|
11
src/t_set.c
11
src/t_set.c
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user