From: antirez Date: Tue, 1 Jun 2010 12:18:38 +0000 (+0200) Subject: Merge branch 'smallkeys' of github.com:antirez/redis into smallkeys X-Git-Url: https://git.saurik.com/redis.git/commitdiff_plain/4e538759c4125a2379fd625e5a92c72347017b7f?hp=-c Merge branch 'smallkeys' of github.com:antirez/redis into smallkeys --- 4e538759c4125a2379fd625e5a92c72347017b7f diff --combined redis.c index f5a43783,2d4dddfb..b5e10d46 --- a/redis.c +++ b/redis.c @@@ -90,7 -90,7 +90,7 @@@ #define REDIS_STATIC_ARGS 8 #define REDIS_DEFAULT_DBNUM 16 #define REDIS_CONFIGLINE_MAX 1024 - #define REDIS_OBJFREELIST_MAX 1000000 /* Max number of objects to cache */ + #define REDIS_OBJFREELIST_MAX 0 /* Max number of objects to cache */ #define REDIS_MAX_SYNC_TIME 60 /* Slave can't take more to sync */ #define REDIS_EXPIRELOOKUPS_PER_CRON 10 /* lookup 10 expires per loop */ #define REDIS_MAX_WRITE_PER_EVENT (1024*64) @@@ -3099,10 -3099,18 +3099,18 @@@ static void decrRefCount(void *obj) } if (o->refcount <= 0) redisPanic("decrRefCount against refcount <= 0"); - /* Object is in memory, or in the process of being swapped out. */ + /* Object is in memory, or in the process of being swapped out. + * + * If the object is being swapped out, abort the operation on + * decrRefCount even if the refcount does not drop to 0: the object + * is referenced at least two times, as value of the key AND as + * job->val in the iojob. So if we don't invalidate the iojob, when it is + * done but the relevant key was removed in the meantime, the + * complete jobs handler will not find the key about the job and the + * assert will fail. */ + if (server.vm_enabled && o->storage == REDIS_VM_SWAPPING) + vmCancelThreadedIOJob(o); if (--(o->refcount) == 0) { - if (server.vm_enabled && o->storage == REDIS_VM_SWAPPING) - vmCancelThreadedIOJob(obj); switch(o->type) { case REDIS_STRING: freeStringObject(o); break; case REDIS_LIST: freeListObject(o); break; @@@ -9120,12 -9128,10 +9128,12 @@@ static int vmWriteObjectOnSwap(robj *o return REDIS_OK; } -/* Swap the 'val' object relative to 'key' into disk. Store all the information - * needed to later retrieve the object into the key object. +/* Transfers the 'val' object to disk. Store all the information + * a 'vmpointer' object containing all the information needed to load the + * object back later is returned. + * * If we can't find enough contiguous empty pages to swap the object on disk - * REDIS_ERR is returned. */ + * NULL is returned. */ static vmpointer *vmSwapObjectBlocking(robj *val) { off_t pages = rdbSavedObjectPages(val,NULL); off_t page; @@@ -9411,11 -9417,9 +9419,9 @@@ static void freeIOJob(iojob *j) j->type == REDIS_IOJOB_DO_SWAP || j->type == REDIS_IOJOB_LOAD) && j->val != NULL) { - /* Our value object was successfully swapped if - * refcount == 1 and storage == REDIS_VM_SWAPPING, - * we fix the storage type, otherwise decrRefCount() will try to - * kill the I/O thread Job (that does no longer exists). */ - if (j->val->refcount == 1 && j->val->storage == REDIS_VM_SWAPPING) + /* we fix the storage type, otherwise decrRefCount() will try to + * kill the I/O thread Job (that does no longer exists). */ + if (j->val->storage == REDIS_VM_SWAPPING) j->val->storage = REDIS_VM_MEMORY; decrRefCount(j->val); } @@@ -9464,7 -9468,7 +9470,7 @@@ static void vmThreadedIOCompletedJob(ae * can do just here to avoid race conditions and/or invasive locks */ redisLog(REDIS_DEBUG,"COMPLETED Job type: %d, ID %p, key: %s", j->type, (void*)j->id, (unsigned char*)j->key->ptr); de = dictFind(j->db->dict,j->key); - assert(de != NULL); + redisAssert(de != NULL); if (j->type == REDIS_IOJOB_LOAD) { redisDb *db; vmpointer *vp = dictGetEntryVal(de); @@@ -9520,6 -9524,9 +9526,9 @@@ vp->page = j->page; vp->usedpages = j->pages; dictGetEntryVal(de) = vp; + /* Fix the storage otherwise decrRefCount will attempt to + * remove the associated I/O job */ + j->val->storage = REDIS_VM_MEMORY; decrRefCount(j->val); redisLog(REDIS_DEBUG, "VM: object %s swapped out at %lld (%lld pages) (threaded)", @@@ -9638,6 -9645,7 +9647,7 @@@ again else if (o->storage == REDIS_VM_SWAPPING) o->storage = REDIS_VM_MEMORY; unlockThreadedIO(); + redisLog(REDIS_DEBUG,"*** DONE"); return; } }