#define REDIS_CONFIGLINE_MAX 1024
#define REDIS_OBJFREELIST_MAX 1000000 /* Max number of objects to cache */
#define REDIS_MAX_SYNC_TIME 60 /* Slave can't take more to sync */
-#define REDIS_EXPIRELOOKUPS_PER_CRON 100 /* try to expire 100 keys/second */
+#define REDIS_EXPIRELOOKUPS_PER_CRON 10 /* try to expire 10 keys/loop */
#define REDIS_MAX_WRITE_PER_EVENT (1024*64)
#define REDIS_REQUEST_MAX_SIZE (1024*1024*256) /* max bytes in inline command */
size = dictSlots(server.db[j].dict);
used = dictSize(server.db[j].dict);
vkeys = dictSize(server.db[j].expires);
- if (!(loops % 5) && (used || vkeys)) {
+ if (!(loops % 50) && (used || vkeys)) {
redisLog(REDIS_VERBOSE,"DB %d: %lld keys (%lld volatile) in %lld slots HT.",j,used,vkeys,size);
/* dictPrintStats(server.dict); */
}
* if we resize the HT while there is the saving child at work actually
* a lot of memory movements in the parent will cause a lot of pages
* copied. */
- if (server.bgsavechildpid == -1) tryResizeHashTables();
+ if (server.bgsavechildpid == -1 && !(loops % 10)) tryResizeHashTables();
/* Show information about connected clients */
- if (!(loops % 5)) {
+ if (!(loops % 50)) {
redisLog(REDIS_VERBOSE,"%d clients connected (%d slaves), %zu bytes in use, %d shared objects",
listLength(server.clients)-listLength(server.slaves),
listLength(server.slaves),
}
/* Close connections of timedout clients */
- if ((server.maxidletime && !(loops % 10)) || server.blpop_blocked_clients)
+ if ((server.maxidletime && !(loops % 100)) || server.blpop_blocked_clients)
closeTimedoutClients();
/* Check if a background saving or AOF rewrite in progress terminated */
retval = (server.vm_max_threads == 0) ?
vmSwapOneObjectBlocking() :
vmSwapOneObjectThreaded();
- if (retval == REDIS_ERR && (loops % 30) == 0 &&
+ if (retval == REDIS_ERR && !(loops % 300) &&
zmalloc_used_memory() >
(server.vm_max_memory+server.vm_max_memory/10))
{
}
/* Check if we should connect to a MASTER */
- if (server.replstate == REDIS_REPL_CONNECT) {
+ if (server.replstate == REDIS_REPL_CONNECT && !(loops % 10)) {
redisLog(REDIS_NOTICE,"Connecting to MASTER...");
if (syncWithMaster() == REDIS_OK) {
redisLog(REDIS_NOTICE,"MASTER <-> SLAVE sync succeeded");
}
}
- return 1000;
+ return 100;
}
/* This function gets called every time Redis is entering the
robj *ele = listNodeValue(ln);
addReplyBulk(c,ele);
listDelNode(list,ln);
+ if (listLength(list) == 0) deleteKey(c->db,c->argv[1]);
server.dirty++;
}
}
ln = listLast(list);
listDelNode(list,ln);
}
+ if (listLength(list) == 0) deleteKey(c->db,c->argv[1]);
server.dirty++;
addReply(c,shared.ok);
}
}
ln = next;
}
+ if (listLength(list) == 0) deleteKey(c->db,c->argv[1]);
addReplySds(c,sdscatprintf(sdsempty(),":%d\r\n",removed));
}
/* Finally remove the element from the source list */
listDelNode(srclist,ln);
+ if (listLength(srclist) == 0) deleteKey(c->db,c->argv[1]);
server.dirty++;
}
}
if (dictDelete(set->ptr,c->argv[2]) == DICT_OK) {
server.dirty++;
if (htNeedsResize(set->ptr)) dictResize(set->ptr);
+ if (dictSize((dict*)set->ptr) == 0) deleteKey(c->db,c->argv[1]);
addReply(c,shared.cone);
} else {
addReply(c,shared.czero);
addReply(c,shared.czero);
return;
}
+ if (dictSize((dict*)srcset->ptr) == 0 && srcset != dstset)
+ deleteKey(c->db,c->argv[1]);
server.dirty++;
/* Add the element to the destination set */
if (!dstset) {
addReplyBulk(c,ele);
dictDelete(set->ptr,ele);
if (htNeedsResize(set->ptr)) dictResize(set->ptr);
+ if (dictSize((dict*)set->ptr) == 0) deleteKey(c->db,c->argv[1]);
server.dirty++;
}
}
dictReleaseIterator(di);
if (dstkey) {
- /* Store the resulting set into the target */
+ /* Store the resulting set into the target, if the intersection
+ * is not an empty set. */
deleteKey(c->db,dstkey);
- dictAdd(c->db->dict,dstkey,dstset);
- incrRefCount(dstkey);
- }
-
- if (!dstkey) {
- lenobj->ptr = sdscatprintf(sdsempty(),"*%lu\r\n",cardinality);
- } else {
- addReplySds(c,sdscatprintf(sdsempty(),":%lu\r\n",
- dictSize((dict*)dstset->ptr)));
+ if (dictSize((dict*)dstset->ptr) > 0) {
+ dictAdd(c->db->dict,dstkey,dstset);
+ incrRefCount(dstkey);
+ addReplyLong(c,dictSize((dict*)dstset->ptr));
+ } else {
+ decrRefCount(dstset);
+ addReply(c,shared.czero);
+ }
server.dirty++;
+ } else {
+ lenobj->ptr = sdscatprintf(sdsempty(),"*%lu\r\n",cardinality);
}
zfree(dv);
}
}
dictReleaseIterator(di);
- if (op == REDIS_OP_DIFF && cardinality == 0) break; /* result set is empty */
+ /* result set is empty? Exit asap. */
+ if (op == REDIS_OP_DIFF && cardinality == 0) break;
}
/* Output the content of the resulting set, if not in STORE mode */
addReplyBulk(c,ele);
}
dictReleaseIterator(di);
+ decrRefCount(dstset);
} else {
/* If we have a target key where to store the resulting set
* create this key with the result set inside */
deleteKey(c->db,dstkey);
- dictAdd(c->db->dict,dstkey,dstset);
- incrRefCount(dstkey);
- }
-
- /* Cleanup */
- if (!dstkey) {
- decrRefCount(dstset);
- } else {
- addReplySds(c,sdscatprintf(sdsempty(),":%lu\r\n",
- dictSize((dict*)dstset->ptr)));
+ if (dictSize((dict*)dstset->ptr) > 0) {
+ dictAdd(c->db->dict,dstkey,dstset);
+ incrRefCount(dstkey);
+ addReplyLong(c,dictSize((dict*)dstset->ptr));
+ } else {
+ decrRefCount(dstset);
+ addReply(c,shared.czero);
+ }
server.dirty++;
}
zfree(dv);
/* Delete from the hash table */
dictDelete(zs->dict,c->argv[2]);
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
+ if (dictSize(zs->dict) == 0) deleteKey(c->db,c->argv[1]);
server.dirty++;
addReply(c,shared.cone);
}
zs = zsetobj->ptr;
deleted = zslDeleteRangeByScore(zs->zsl,min,max,zs->dict);
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
+ if (dictSize(zs->dict) == 0) deleteKey(c->db,c->argv[1]);
server.dirty += deleted;
addReplyLong(c,deleted);
}
* use 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) deleteKey(c->db,c->argv[1]);
server.dirty += deleted;
addReplyLong(c, deleted);
}
}
deleteKey(c->db,dstkey);
- dictAdd(c->db->dict,dstkey,dstobj);
- incrRefCount(dstkey);
-
- addReplyLong(c, dstzset->zsl->length);
- server.dirty++;
+ if (dstzset->zsl->length) {
+ dictAdd(c->db->dict,dstkey,dstobj);
+ incrRefCount(dstkey);
+ addReplyLong(c, dstzset->zsl->length);
+ server.dirty++;
+ } else {
+ decrRefCount(dstzset);
+ addReply(c, shared.czero);
+ }
zfree(src);
}
(unsigned char*) field->ptr,
sdslen(field->ptr), &deleted);
decrRefCount(field);
+ if (zipmapLen((unsigned char*) o->ptr) == 0)
+ deleteKey(c->db,c->argv[1]);
} else {
deleted = dictDelete((dict*)o->ptr,c->argv[2]) == DICT_OK;
+ if (htNeedsResize(o->ptr)) dictResize(o->ptr);
+ if (dictSize((dict*)o->ptr) == 0) deleteKey(c->db,c->argv[1]);
}
if (deleted) server.dirty++;
addReply(c,deleted ? shared.cone : shared.czero);