touched key for WATCH refactored into a more general thing that can be used also for the cache system. Some more changes towards diskstore working.
This commit is contained in:
parent
d021221086
commit
cea8c5cd75
35
src/db.c
35
src/db.c
@ -152,20 +152,41 @@ int selectDb(redisClient *c, int id) {
|
|||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
* Hooks for key space changes.
|
||||||
|
*
|
||||||
|
* Every time a key in the database is modified the function
|
||||||
|
* signalModifiedKey() is called.
|
||||||
|
*
|
||||||
|
* Every time a DB is flushed the function signalFlushDb() is called.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void signalModifiedKey(redisDb *db, robj *key) {
|
||||||
|
touchWatchedKey(db,key);
|
||||||
|
if (server.ds_enabled)
|
||||||
|
cacheScheduleForFlush(db,key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void signalFlushedDb(int dbid) {
|
||||||
|
touchWatchedKeysOnFlush(dbid);
|
||||||
|
if (server.ds_enabled)
|
||||||
|
dsFlushDb(dbid);
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
* Type agnostic commands operating on the key space
|
* Type agnostic commands operating on the key space
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void flushdbCommand(redisClient *c) {
|
void flushdbCommand(redisClient *c) {
|
||||||
server.dirty += dictSize(c->db->dict);
|
server.dirty += dictSize(c->db->dict);
|
||||||
touchWatchedKeysOnFlush(c->db->id);
|
signalFlushedDb(c->db->id);
|
||||||
dictEmpty(c->db->dict);
|
dictEmpty(c->db->dict);
|
||||||
dictEmpty(c->db->expires);
|
dictEmpty(c->db->expires);
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flushallCommand(redisClient *c) {
|
void flushallCommand(redisClient *c) {
|
||||||
touchWatchedKeysOnFlush(-1);
|
signalFlushedDb(-1);
|
||||||
server.dirty += emptyDb();
|
server.dirty += emptyDb();
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
if (server.bgsavechildpid != -1) {
|
if (server.bgsavechildpid != -1) {
|
||||||
@ -181,7 +202,7 @@ void delCommand(redisClient *c) {
|
|||||||
|
|
||||||
for (j = 1; j < c->argc; j++) {
|
for (j = 1; j < c->argc; j++) {
|
||||||
if (dbDelete(c->db,c->argv[j])) {
|
if (dbDelete(c->db,c->argv[j])) {
|
||||||
touchWatchedKey(c->db,c->argv[j]);
|
signalModifiedKey(c->db,c->argv[j]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
deleted++;
|
deleted++;
|
||||||
}
|
}
|
||||||
@ -327,8 +348,8 @@ void renameGenericCommand(redisClient *c, int nx) {
|
|||||||
dbReplace(c->db,c->argv[2],o);
|
dbReplace(c->db,c->argv[2],o);
|
||||||
}
|
}
|
||||||
dbDelete(c->db,c->argv[1]);
|
dbDelete(c->db,c->argv[1]);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
touchWatchedKey(c->db,c->argv[2]);
|
signalModifiedKey(c->db,c->argv[2]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReply(c,nx ? shared.cone : shared.ok);
|
addReply(c,nx ? shared.cone : shared.ok);
|
||||||
}
|
}
|
||||||
@ -487,13 +508,13 @@ void expireGenericCommand(redisClient *c, robj *key, robj *param, long offset) {
|
|||||||
if (seconds <= 0) {
|
if (seconds <= 0) {
|
||||||
if (dbDelete(c->db,key)) server.dirty++;
|
if (dbDelete(c->db,key)) server.dirty++;
|
||||||
addReply(c, shared.cone);
|
addReply(c, shared.cone);
|
||||||
touchWatchedKey(c->db,key);
|
signalModifiedKey(c->db,key);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
time_t when = time(NULL)+seconds;
|
time_t when = time(NULL)+seconds;
|
||||||
setExpire(c->db,key,when);
|
setExpire(c->db,key,when);
|
||||||
addReply(c,shared.cone);
|
addReply(c,shared.cone);
|
||||||
touchWatchedKey(c->db,key);
|
signalModifiedKey(c->db,key);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -120,3 +120,6 @@ int dsDel(redisDb *db, robj *key) {
|
|||||||
|
|
||||||
int dsExists(redisDb *db, robj *key) {
|
int dsExists(redisDb *db, robj *key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dsFlushDb(int dbid) {
|
||||||
|
}
|
||||||
|
14
src/object.c
14
src/object.c
@ -208,16 +208,16 @@ robj *tryObjectEncoding(robj *o) {
|
|||||||
/* Ok, this object can be encoded...
|
/* Ok, this object can be encoded...
|
||||||
*
|
*
|
||||||
* Can I use a shared object? Only if the object is inside a given
|
* Can I use a shared object? Only if the object is inside a given
|
||||||
* range and if this is the main thread, since when VM is enabled we
|
* range and if the back end in use is in-memory. For disk store every
|
||||||
* have the constraint that I/O thread should only handle non-shared
|
* object in memory used as value should be independent.
|
||||||
* objects, in order to avoid race conditions (we don't have per-object
|
|
||||||
* locking).
|
|
||||||
*
|
*
|
||||||
* Note that we also avoid using shared integers when maxmemory is used
|
* Note that we also avoid using shared integers when maxmemory is used
|
||||||
* because very object needs to have a private LRU field for the LRU
|
* because every object needs to have a private LRU field for the LRU
|
||||||
* algorithm to work well. */
|
* algorithm to work well. */
|
||||||
if (server.maxmemory == 0 && value >= 0 && value < REDIS_SHARED_INTEGERS &&
|
if (server.ds_enabled == 0 &&
|
||||||
pthread_equal(pthread_self(),server.mainthread)) {
|
server.maxmemory == 0 && value >= 0 && value < REDIS_SHARED_INTEGERS &&
|
||||||
|
pthread_equal(pthread_self(),server.mainthread))
|
||||||
|
{
|
||||||
decrRefCount(o);
|
decrRefCount(o);
|
||||||
incrRefCount(shared.integers[value]);
|
incrRefCount(shared.integers[value]);
|
||||||
return shared.integers[value];
|
return shared.integers[value];
|
||||||
|
23
src/rdb.c
23
src/rdb.c
@ -848,7 +848,6 @@ int rdbLoad(char *filename) {
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
uint32_t dbid;
|
uint32_t dbid;
|
||||||
int type, retval, rdbver;
|
int type, retval, rdbver;
|
||||||
int swap_all_values = 0;
|
|
||||||
redisDb *db = server.db+0;
|
redisDb *db = server.db+0;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
time_t expiretime, now = time(NULL);
|
time_t expiretime, now = time(NULL);
|
||||||
@ -919,28 +918,6 @@ int rdbLoad(char *filename) {
|
|||||||
/* Set the expire time if needed */
|
/* Set the expire time if needed */
|
||||||
if (expiretime != -1) setExpire(db,key,expiretime);
|
if (expiretime != -1) setExpire(db,key,expiretime);
|
||||||
|
|
||||||
/* Handle swapping while loading big datasets when VM is on */
|
|
||||||
|
|
||||||
/* If we detecter we are hopeless about fitting something in memory
|
|
||||||
* we just swap every new key on disk. Directly...
|
|
||||||
* Note that's important to check for this condition before resorting
|
|
||||||
* to random sampling, otherwise we may try to swap already
|
|
||||||
* swapped keys. */
|
|
||||||
if (swap_all_values) {
|
|
||||||
dictEntry *de = dictFind(db->dict,key->ptr);
|
|
||||||
|
|
||||||
/* de may be NULL since the key already expired */
|
|
||||||
if (de) {
|
|
||||||
vmpointer *vp;
|
|
||||||
val = dictGetEntryVal(de);
|
|
||||||
|
|
||||||
if (val->refcount == 1 &&
|
|
||||||
(vp = vmSwapObjectBlocking(val)) != NULL)
|
|
||||||
dictGetEntryVal(de) = vp;
|
|
||||||
}
|
|
||||||
decrRefCount(key);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
decrRefCount(key);
|
decrRefCount(key);
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@ -830,6 +830,9 @@ void initServer() {
|
|||||||
server.slaves = listCreate();
|
server.slaves = listCreate();
|
||||||
server.monitors = listCreate();
|
server.monitors = listCreate();
|
||||||
server.unblocked_clients = listCreate();
|
server.unblocked_clients = listCreate();
|
||||||
|
server.cache_flush_queue = listCreate();
|
||||||
|
server.cache_flush_delay = 0;
|
||||||
|
|
||||||
createSharedObjects();
|
createSharedObjects();
|
||||||
server.el = aeCreateEventLoop();
|
server.el = aeCreateEventLoop();
|
||||||
server.db = zmalloc(sizeof(redisDb)*server.dbnum);
|
server.db = zmalloc(sizeof(redisDb)*server.dbnum);
|
||||||
|
31
src/redis.h
31
src/redis.h
@ -431,7 +431,9 @@ struct redisServer {
|
|||||||
/* Blocked clients */
|
/* Blocked clients */
|
||||||
unsigned int bpop_blocked_clients;
|
unsigned int bpop_blocked_clients;
|
||||||
unsigned int cache_blocked_clients;
|
unsigned int cache_blocked_clients;
|
||||||
list *unblocked_clients;
|
list *unblocked_clients; /* list of clients to unblock before next loop */
|
||||||
|
list *cache_flush_queue; /* keys to flush on disk */
|
||||||
|
int cache_flush_delay; /* seconds to wait before flushing keys */
|
||||||
/* Sort parameters - qsort_r() is only available under BSD so we
|
/* Sort parameters - qsort_r() is only available under BSD so we
|
||||||
* have to take this state global, in order to pass it to sortCompare() */
|
* have to take this state global, in order to pass it to sortCompare() */
|
||||||
int sort_desc;
|
int sort_desc;
|
||||||
@ -554,6 +556,14 @@ typedef struct iojob {
|
|||||||
* field is populated by the I/O thread for REDIS_IOJOB_LOAD. */
|
* field is populated by the I/O thread for REDIS_IOJOB_LOAD. */
|
||||||
} iojob;
|
} iojob;
|
||||||
|
|
||||||
|
/* When diskstore is enabled and a flush operation is requested we push
|
||||||
|
* one of this structures into server.cache_flush_queue. */
|
||||||
|
typedef struct dirtykey {
|
||||||
|
redisDb *db;
|
||||||
|
robj *key;
|
||||||
|
time_t ctime; /* This is the creation time of the entry. */
|
||||||
|
} dirtykey;
|
||||||
|
|
||||||
/* Structure to hold list iteration abstraction. */
|
/* Structure to hold list iteration abstraction. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
robj *subject;
|
robj *subject;
|
||||||
@ -774,33 +784,22 @@ int dsSet(redisDb *db, robj *key, robj *val);
|
|||||||
robj *dsGet(redisDb *db, robj *key);
|
robj *dsGet(redisDb *db, robj *key);
|
||||||
int dsDel(redisDb *db, robj *key);
|
int dsDel(redisDb *db, robj *key);
|
||||||
int dsExists(redisDb *db, robj *key);
|
int dsExists(redisDb *db, robj *key);
|
||||||
|
int dsFlushDb(int dbid);
|
||||||
|
|
||||||
/* Disk Store Cache */
|
/* Disk Store Cache */
|
||||||
void vmInit(void);
|
void dsInit(void);
|
||||||
void vmMarkPagesFree(off_t page, off_t count);
|
|
||||||
robj *vmLoadObject(robj *o);
|
|
||||||
robj *vmPreviewObject(robj *o);
|
|
||||||
int vmSwapOneObjectBlocking(void);
|
|
||||||
int vmSwapOneObjectThreaded(void);
|
|
||||||
int vmCanSwapOut(void);
|
|
||||||
void vmThreadedIOCompletedJob(aeEventLoop *el, int fd, void *privdata, int mask);
|
void vmThreadedIOCompletedJob(aeEventLoop *el, int fd, void *privdata, int mask);
|
||||||
void vmCancelThreadedIOJob(robj *o);
|
|
||||||
void lockThreadedIO(void);
|
void lockThreadedIO(void);
|
||||||
void unlockThreadedIO(void);
|
void unlockThreadedIO(void);
|
||||||
int vmSwapObjectThreaded(robj *key, robj *val, redisDb *db);
|
|
||||||
void freeIOJob(iojob *j);
|
void freeIOJob(iojob *j);
|
||||||
void queueIOJob(iojob *j);
|
void queueIOJob(iojob *j);
|
||||||
int vmWriteObjectOnSwap(robj *o, off_t page);
|
|
||||||
robj *vmReadObjectFromSwap(off_t page, int type);
|
|
||||||
void waitEmptyIOJobsQueue(void);
|
void waitEmptyIOJobsQueue(void);
|
||||||
void vmReopenSwapFile(void);
|
|
||||||
int vmFreePage(off_t page);
|
|
||||||
void zunionInterBlockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd, int argc, robj **argv);
|
void zunionInterBlockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd, int argc, robj **argv);
|
||||||
void execBlockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd, int argc, robj **argv);
|
void execBlockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd, int argc, robj **argv);
|
||||||
int blockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd);
|
int blockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd);
|
||||||
int dontWaitForSwappedKey(redisClient *c, robj *key);
|
int dontWaitForSwappedKey(redisClient *c, robj *key);
|
||||||
void handleClientsBlockedOnSwappedKey(redisDb *db, robj *key);
|
void handleClientsBlockedOnSwappedKey(redisDb *db, robj *key);
|
||||||
vmpointer *vmSwapObjectBlocking(robj *val);
|
int cacheFreeOneEntry(void);
|
||||||
|
|
||||||
/* Set data type */
|
/* Set data type */
|
||||||
robj *setTypeCreate(robj *value);
|
robj *setTypeCreate(robj *value);
|
||||||
@ -871,6 +870,8 @@ robj *dbRandomKey(redisDb *db);
|
|||||||
int dbDelete(redisDb *db, robj *key);
|
int dbDelete(redisDb *db, robj *key);
|
||||||
long long emptyDb();
|
long long emptyDb();
|
||||||
int selectDb(redisClient *c, int id);
|
int selectDb(redisClient *c, int id);
|
||||||
|
void signalModifiedKey(redisDb *db, robj *key);
|
||||||
|
void signalFlushedDb(int dbid);
|
||||||
|
|
||||||
/* Git SHA1 */
|
/* Git SHA1 */
|
||||||
char *redisGitSHA1(void);
|
char *redisGitSHA1(void);
|
||||||
|
@ -368,7 +368,7 @@ void sortCommand(redisClient *c) {
|
|||||||
* SORT result is empty a new key is set and maybe the old content
|
* SORT result is empty a new key is set and maybe the old content
|
||||||
* replaced. */
|
* replaced. */
|
||||||
server.dirty += 1+outputlen;
|
server.dirty += 1+outputlen;
|
||||||
touchWatchedKey(c->db,storekey);
|
signalModifiedKey(c->db,storekey);
|
||||||
addReplyLongLong(c,outputlen);
|
addReplyLongLong(c,outputlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/t_hash.c
10
src/t_hash.c
@ -279,7 +279,7 @@ void hsetCommand(redisClient *c) {
|
|||||||
hashTypeTryObjectEncoding(o,&c->argv[2], &c->argv[3]);
|
hashTypeTryObjectEncoding(o,&c->argv[2], &c->argv[3]);
|
||||||
update = hashTypeSet(o,c->argv[2],c->argv[3]);
|
update = hashTypeSet(o,c->argv[2],c->argv[3]);
|
||||||
addReply(c, update ? shared.czero : shared.cone);
|
addReply(c, update ? shared.czero : shared.cone);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +294,7 @@ void hsetnxCommand(redisClient *c) {
|
|||||||
hashTypeTryObjectEncoding(o,&c->argv[2], &c->argv[3]);
|
hashTypeTryObjectEncoding(o,&c->argv[2], &c->argv[3]);
|
||||||
hashTypeSet(o,c->argv[2],c->argv[3]);
|
hashTypeSet(o,c->argv[2],c->argv[3]);
|
||||||
addReply(c, shared.cone);
|
addReply(c, shared.cone);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -315,7 +315,7 @@ void hmsetCommand(redisClient *c) {
|
|||||||
hashTypeSet(o,c->argv[i],c->argv[i+1]);
|
hashTypeSet(o,c->argv[i],c->argv[i+1]);
|
||||||
}
|
}
|
||||||
addReply(c, shared.ok);
|
addReply(c, shared.ok);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,7 +342,7 @@ void hincrbyCommand(redisClient *c) {
|
|||||||
hashTypeSet(o,c->argv[2],new);
|
hashTypeSet(o,c->argv[2],new);
|
||||||
decrRefCount(new);
|
decrRefCount(new);
|
||||||
addReplyLongLong(c,value);
|
addReplyLongLong(c,value);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,7 +402,7 @@ void hdelCommand(redisClient *c) {
|
|||||||
if (hashTypeDelete(o,c->argv[2])) {
|
if (hashTypeDelete(o,c->argv[2])) {
|
||||||
if (hashTypeLength(o) == 0) dbDelete(c->db,c->argv[1]);
|
if (hashTypeLength(o) == 0) dbDelete(c->db,c->argv[1]);
|
||||||
addReply(c,shared.cone);
|
addReply(c,shared.cone);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
} else {
|
} else {
|
||||||
addReply(c,shared.czero);
|
addReply(c,shared.czero);
|
||||||
|
22
src/t_list.c
22
src/t_list.c
@ -274,14 +274,14 @@ void pushGenericCommand(redisClient *c, int where) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (handleClientsWaitingListPush(c,c->argv[1],c->argv[2])) {
|
if (handleClientsWaitingListPush(c,c->argv[1],c->argv[2])) {
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
addReply(c,shared.cone);
|
addReply(c,shared.cone);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
listTypePush(lobj,c->argv[2],where);
|
listTypePush(lobj,c->argv[2],where);
|
||||||
addReplyLongLong(c,listTypeLength(lobj));
|
addReplyLongLong(c,listTypeLength(lobj));
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +330,7 @@ void pushxGenericCommand(redisClient *c, robj *refval, robj *val, int where) {
|
|||||||
if (subject->encoding == REDIS_ENCODING_ZIPLIST &&
|
if (subject->encoding == REDIS_ENCODING_ZIPLIST &&
|
||||||
ziplistLen(subject->ptr) > server.list_max_ziplist_entries)
|
ziplistLen(subject->ptr) > server.list_max_ziplist_entries)
|
||||||
listTypeConvert(subject,REDIS_ENCODING_LINKEDLIST);
|
listTypeConvert(subject,REDIS_ENCODING_LINKEDLIST);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
} else {
|
} else {
|
||||||
/* Notify client of a failed insert */
|
/* Notify client of a failed insert */
|
||||||
@ -339,7 +339,7 @@ void pushxGenericCommand(redisClient *c, robj *refval, robj *val, int where) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
listTypePush(subject,val,where);
|
listTypePush(subject,val,where);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,7 +427,7 @@ void lsetCommand(redisClient *c) {
|
|||||||
o->ptr = ziplistInsert(o->ptr,p,value->ptr,sdslen(value->ptr));
|
o->ptr = ziplistInsert(o->ptr,p,value->ptr,sdslen(value->ptr));
|
||||||
decrRefCount(value);
|
decrRefCount(value);
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
} else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
|
} else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
|
||||||
@ -439,7 +439,7 @@ void lsetCommand(redisClient *c) {
|
|||||||
listNodeValue(ln) = value;
|
listNodeValue(ln) = value;
|
||||||
incrRefCount(value);
|
incrRefCount(value);
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -458,7 +458,7 @@ void popGenericCommand(redisClient *c, int where) {
|
|||||||
addReplyBulk(c,value);
|
addReplyBulk(c,value);
|
||||||
decrRefCount(value);
|
decrRefCount(value);
|
||||||
if (listTypeLength(o) == 0) dbDelete(c->db,c->argv[1]);
|
if (listTypeLength(o) == 0) dbDelete(c->db,c->argv[1]);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -573,7 +573,7 @@ void ltrimCommand(redisClient *c) {
|
|||||||
redisPanic("Unknown list encoding");
|
redisPanic("Unknown list encoding");
|
||||||
}
|
}
|
||||||
if (listTypeLength(o) == 0) dbDelete(c->db,c->argv[1]);
|
if (listTypeLength(o) == 0) dbDelete(c->db,c->argv[1]);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReply(c,shared.ok);
|
addReply(c,shared.ok);
|
||||||
}
|
}
|
||||||
@ -616,7 +616,7 @@ void lremCommand(redisClient *c) {
|
|||||||
|
|
||||||
if (listTypeLength(subject) == 0) dbDelete(c->db,c->argv[1]);
|
if (listTypeLength(subject) == 0) dbDelete(c->db,c->argv[1]);
|
||||||
addReplyLongLong(c,removed);
|
addReplyLongLong(c,removed);
|
||||||
if (removed) touchWatchedKey(c->db,c->argv[1]);
|
if (removed) signalModifiedKey(c->db,c->argv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the semantic of this command:
|
/* This is the semantic of this command:
|
||||||
@ -642,7 +642,7 @@ void rpoplpushHandlePush(redisClient *c, robj *dstkey, robj *dstobj, robj *value
|
|||||||
dstobj = createZiplistObject();
|
dstobj = createZiplistObject();
|
||||||
dbAdd(c->db,dstkey,dstobj);
|
dbAdd(c->db,dstkey,dstobj);
|
||||||
} else {
|
} else {
|
||||||
touchWatchedKey(c->db,dstkey);
|
signalModifiedKey(c->db,dstkey);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
listTypePush(dstobj,value,REDIS_HEAD);
|
listTypePush(dstobj,value,REDIS_HEAD);
|
||||||
@ -670,7 +670,7 @@ void rpoplpushCommand(redisClient *c) {
|
|||||||
|
|
||||||
/* Delete the source list when it is empty */
|
/* Delete the source list when it is empty */
|
||||||
if (listTypeLength(sobj) == 0) dbDelete(c->db,c->argv[1]);
|
if (listTypeLength(sobj) == 0) dbDelete(c->db,c->argv[1]);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
src/t_set.c
16
src/t_set.c
@ -231,7 +231,7 @@ void saddCommand(redisClient *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (setTypeAdd(set,c->argv[2])) {
|
if (setTypeAdd(set,c->argv[2])) {
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReply(c,shared.cone);
|
addReply(c,shared.cone);
|
||||||
} else {
|
} else {
|
||||||
@ -248,7 +248,7 @@ void sremCommand(redisClient *c) {
|
|||||||
c->argv[2] = tryObjectEncoding(c->argv[2]);
|
c->argv[2] = tryObjectEncoding(c->argv[2]);
|
||||||
if (setTypeRemove(set,c->argv[2])) {
|
if (setTypeRemove(set,c->argv[2])) {
|
||||||
if (setTypeSize(set) == 0) dbDelete(c->db,c->argv[1]);
|
if (setTypeSize(set) == 0) dbDelete(c->db,c->argv[1]);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReply(c,shared.cone);
|
addReply(c,shared.cone);
|
||||||
} else {
|
} else {
|
||||||
@ -287,8 +287,8 @@ void smoveCommand(redisClient *c) {
|
|||||||
|
|
||||||
/* Remove the src set from the database when empty */
|
/* 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]);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
touchWatchedKey(c->db,c->argv[2]);
|
signalModifiedKey(c->db,c->argv[2]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
|
|
||||||
/* Create the destination set when it doesn't exist */
|
/* Create the destination set when it doesn't exist */
|
||||||
@ -341,7 +341,7 @@ void spopCommand(redisClient *c) {
|
|||||||
setTypeRemove(set,ele);
|
setTypeRemove(set,ele);
|
||||||
}
|
}
|
||||||
if (setTypeSize(set) == 0) dbDelete(c->db,c->argv[1]);
|
if (setTypeSize(set) == 0) dbDelete(c->db,c->argv[1]);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,7 +382,7 @@ void sinterGenericCommand(redisClient *c, robj **setkeys, unsigned long setnum,
|
|||||||
zfree(sets);
|
zfree(sets);
|
||||||
if (dstkey) {
|
if (dstkey) {
|
||||||
if (dbDelete(c->db,dstkey)) {
|
if (dbDelete(c->db,dstkey)) {
|
||||||
touchWatchedKey(c->db,dstkey);
|
signalModifiedKey(c->db,dstkey);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
addReply(c,shared.czero);
|
addReply(c,shared.czero);
|
||||||
@ -486,7 +486,7 @@ void sinterGenericCommand(redisClient *c, robj **setkeys, unsigned long setnum,
|
|||||||
decrRefCount(dstset);
|
decrRefCount(dstset);
|
||||||
addReply(c,shared.czero);
|
addReply(c,shared.czero);
|
||||||
}
|
}
|
||||||
touchWatchedKey(c->db,dstkey);
|
signalModifiedKey(c->db,dstkey);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
} else {
|
} else {
|
||||||
setDeferredMultiBulkLength(c,replylen,cardinality);
|
setDeferredMultiBulkLength(c,replylen,cardinality);
|
||||||
@ -578,7 +578,7 @@ void sunionDiffGenericCommand(redisClient *c, robj **setkeys, int setnum, robj *
|
|||||||
decrRefCount(dstset);
|
decrRefCount(dstset);
|
||||||
addReply(c,shared.czero);
|
addReply(c,shared.czero);
|
||||||
}
|
}
|
||||||
touchWatchedKey(c->db,dstkey);
|
signalModifiedKey(c->db,dstkey);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
zfree(sets);
|
zfree(sets);
|
||||||
|
@ -38,7 +38,7 @@ void setGenericCommand(redisClient *c, int nx, robj *key, robj *val, robj *expir
|
|||||||
} else {
|
} else {
|
||||||
incrRefCount(val);
|
incrRefCount(val);
|
||||||
}
|
}
|
||||||
touchWatchedKey(c->db,key);
|
signalModifiedKey(c->db,key);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
removeExpire(c->db,key);
|
removeExpire(c->db,key);
|
||||||
if (expire) setExpire(c->db,key,time(NULL)+seconds);
|
if (expire) setExpire(c->db,key,time(NULL)+seconds);
|
||||||
@ -84,7 +84,7 @@ void getsetCommand(redisClient *c) {
|
|||||||
c->argv[2] = tryObjectEncoding(c->argv[2]);
|
c->argv[2] = tryObjectEncoding(c->argv[2]);
|
||||||
dbReplace(c->db,c->argv[1],c->argv[2]);
|
dbReplace(c->db,c->argv[1],c->argv[2]);
|
||||||
incrRefCount(c->argv[2]);
|
incrRefCount(c->argv[2]);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
removeExpire(c->db,c->argv[1]);
|
removeExpire(c->db,c->argv[1]);
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ void setbitCommand(redisClient *c) {
|
|||||||
byteval &= ~(1 << bit);
|
byteval &= ~(1 << bit);
|
||||||
byteval |= ((on & 0x1) << bit);
|
byteval |= ((on & 0x1) << bit);
|
||||||
((char*)o->ptr)[byte] = byteval;
|
((char*)o->ptr)[byte] = byteval;
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReply(c, bitval ? shared.cone : shared.czero);
|
addReply(c, bitval ? shared.cone : shared.czero);
|
||||||
}
|
}
|
||||||
@ -244,7 +244,7 @@ void setrangeCommand(redisClient *c) {
|
|||||||
if (sdslen(value) > 0) {
|
if (sdslen(value) > 0) {
|
||||||
o->ptr = sdsgrowzero(o->ptr,offset+sdslen(value));
|
o->ptr = sdsgrowzero(o->ptr,offset+sdslen(value));
|
||||||
memcpy((char*)o->ptr+offset,value,sdslen(value));
|
memcpy((char*)o->ptr+offset,value,sdslen(value));
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
addReplyLongLong(c,sdslen(o->ptr));
|
addReplyLongLong(c,sdslen(o->ptr));
|
||||||
@ -331,7 +331,7 @@ void msetGenericCommand(redisClient *c, int nx) {
|
|||||||
dbReplace(c->db,c->argv[j],c->argv[j+1]);
|
dbReplace(c->db,c->argv[j],c->argv[j+1]);
|
||||||
incrRefCount(c->argv[j+1]);
|
incrRefCount(c->argv[j+1]);
|
||||||
removeExpire(c->db,c->argv[j]);
|
removeExpire(c->db,c->argv[j]);
|
||||||
touchWatchedKey(c->db,c->argv[j]);
|
signalModifiedKey(c->db,c->argv[j]);
|
||||||
}
|
}
|
||||||
server.dirty += (c->argc-1)/2;
|
server.dirty += (c->argc-1)/2;
|
||||||
addReply(c, nx ? shared.cone : shared.ok);
|
addReply(c, nx ? shared.cone : shared.ok);
|
||||||
@ -361,7 +361,7 @@ void incrDecrCommand(redisClient *c, long long incr) {
|
|||||||
}
|
}
|
||||||
o = createStringObjectFromLongLong(value);
|
o = createStringObjectFromLongLong(value);
|
||||||
dbReplace(c->db,c->argv[1],o);
|
dbReplace(c->db,c->argv[1],o);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReply(c,shared.colon);
|
addReply(c,shared.colon);
|
||||||
addReply(c,o);
|
addReply(c,o);
|
||||||
@ -424,7 +424,7 @@ void appendCommand(redisClient *c) {
|
|||||||
o->ptr = sdscatlen(o->ptr,append->ptr,sdslen(append->ptr));
|
o->ptr = sdscatlen(o->ptr,append->ptr,sdslen(append->ptr));
|
||||||
totlen = sdslen(o->ptr);
|
totlen = sdslen(o->ptr);
|
||||||
}
|
}
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReplyLongLong(c,totlen);
|
addReplyLongLong(c,totlen);
|
||||||
}
|
}
|
||||||
|
14
src/t_zset.c
14
src/t_zset.c
@ -399,7 +399,7 @@ void zaddGenericCommand(redisClient *c, robj *key, robj *ele, double score, int
|
|||||||
de = dictFind(zs->dict,ele);
|
de = dictFind(zs->dict,ele);
|
||||||
redisAssert(de != NULL);
|
redisAssert(de != NULL);
|
||||||
dictGetEntryVal(de) = &znode->score;
|
dictGetEntryVal(de) = &znode->score;
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
if (incr)
|
if (incr)
|
||||||
addReplyDouble(c,score);
|
addReplyDouble(c,score);
|
||||||
@ -427,7 +427,7 @@ void zaddGenericCommand(redisClient *c, robj *key, robj *ele, double score, int
|
|||||||
|
|
||||||
/* Update the score in the current dict entry */
|
/* Update the score in the current dict entry */
|
||||||
dictGetEntryVal(de) = &znode->score;
|
dictGetEntryVal(de) = &znode->score;
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
if (incr)
|
if (incr)
|
||||||
@ -477,7 +477,7 @@ void zremCommand(redisClient *c) {
|
|||||||
dictDelete(zs->dict,c->argv[2]);
|
dictDelete(zs->dict,c->argv[2]);
|
||||||
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
|
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
|
||||||
if (dictSize(zs->dict) == 0) dbDelete(c->db,c->argv[1]);
|
if (dictSize(zs->dict) == 0) dbDelete(c->db,c->argv[1]);
|
||||||
touchWatchedKey(c->db,c->argv[1]);
|
signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
addReply(c,shared.cone);
|
addReply(c,shared.cone);
|
||||||
}
|
}
|
||||||
@ -501,7 +501,7 @@ void zremrangebyscoreCommand(redisClient *c) {
|
|||||||
deleted = zslDeleteRangeByScore(zs->zsl,range,zs->dict);
|
deleted = zslDeleteRangeByScore(zs->zsl,range,zs->dict);
|
||||||
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
|
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
|
||||||
if (dictSize(zs->dict) == 0) dbDelete(c->db,c->argv[1]);
|
if (dictSize(zs->dict) == 0) dbDelete(c->db,c->argv[1]);
|
||||||
if (deleted) touchWatchedKey(c->db,c->argv[1]);
|
if (deleted) signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty += deleted;
|
server.dirty += deleted;
|
||||||
addReplyLongLong(c,deleted);
|
addReplyLongLong(c,deleted);
|
||||||
}
|
}
|
||||||
@ -540,7 +540,7 @@ void zremrangebyrankCommand(redisClient *c) {
|
|||||||
deleted = zslDeleteRangeByRank(zs->zsl,start+1,end+1,zs->dict);
|
deleted = zslDeleteRangeByRank(zs->zsl,start+1,end+1,zs->dict);
|
||||||
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
|
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
|
||||||
if (dictSize(zs->dict) == 0) dbDelete(c->db,c->argv[1]);
|
if (dictSize(zs->dict) == 0) dbDelete(c->db,c->argv[1]);
|
||||||
if (deleted) touchWatchedKey(c->db,c->argv[1]);
|
if (deleted) signalModifiedKey(c->db,c->argv[1]);
|
||||||
server.dirty += deleted;
|
server.dirty += deleted;
|
||||||
addReplyLongLong(c, deleted);
|
addReplyLongLong(c, deleted);
|
||||||
}
|
}
|
||||||
@ -741,14 +741,14 @@ void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dbDelete(c->db,dstkey)) {
|
if (dbDelete(c->db,dstkey)) {
|
||||||
touchWatchedKey(c->db,dstkey);
|
signalModifiedKey(c->db,dstkey);
|
||||||
touched = 1;
|
touched = 1;
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
}
|
}
|
||||||
if (dstzset->zsl->length) {
|
if (dstzset->zsl->length) {
|
||||||
dbAdd(c->db,dstkey,dstobj);
|
dbAdd(c->db,dstkey,dstobj);
|
||||||
addReplyLongLong(c, dstzset->zsl->length);
|
addReplyLongLong(c, dstzset->zsl->length);
|
||||||
if (!touched) touchWatchedKey(c->db,dstkey);
|
if (!touched) signalModifiedKey(c->db,dstkey);
|
||||||
server.dirty++;
|
server.dirty++;
|
||||||
} else {
|
} else {
|
||||||
decrRefCount(dstobj);
|
decrRefCount(dstobj);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user