]> git.saurik.com Git - redis.git/blobdiff - src/vm.c
intset loading bug fixed
[redis.git] / src / vm.c
index 1aaa57eb54bd338bbd2c6ca963764e872ec924ad..a34387521d0cac989b73fe9f7021dd53ba917a3b 100644 (file)
--- a/src/vm.c
+++ b/src/vm.c
@@ -86,10 +86,9 @@ void vmInit(void) {
     } else {
         redisLog(REDIS_NOTICE,"Swap file allocated with success");
     }
     } else {
         redisLog(REDIS_NOTICE,"Swap file allocated with success");
     }
-    server.vm_bitmap = zmalloc((server.vm_pages+7)/8);
+    server.vm_bitmap = zcalloc((server.vm_pages+7)/8);
     redisLog(REDIS_VERBOSE,"Allocated %lld bytes page table for %lld pages",
         (long long) (server.vm_pages+7)/8, server.vm_pages);
     redisLog(REDIS_VERBOSE,"Allocated %lld bytes page table for %lld pages",
         (long long) (server.vm_pages+7)/8, server.vm_pages);
-    memset(server.vm_bitmap,0,(server.vm_pages+7)/8);
 
     /* Initialize threaded I/O (used by Virtual Memory) */
     server.io_newjobs = listCreate();
 
     /* Initialize threaded I/O (used by Virtual Memory) */
     server.io_newjobs = listCreate();
@@ -396,15 +395,20 @@ double computeObjectSwappability(robj *o) {
         z = (o->type == REDIS_ZSET);
         d = z ? ((zset*)o->ptr)->dict : o->ptr;
 
         z = (o->type == REDIS_ZSET);
         d = z ? ((zset*)o->ptr)->dict : o->ptr;
 
-        asize = sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d));
-        if (z) asize += sizeof(zset)-sizeof(dict);
-        if (dictSize(d)) {
-            de = dictGetRandomKey(d);
-            ele = dictGetEntryKey(de);
-            elesize = (ele->encoding == REDIS_ENCODING_RAW) ?
-                            (sizeof(*o)+sdslen(ele->ptr)) : sizeof(*o);
-            asize += (sizeof(struct dictEntry)+elesize)*dictSize(d);
-            if (z) asize += sizeof(zskiplistNode)*dictSize(d);
+        if (!z && o->encoding == REDIS_ENCODING_INTSET) {
+            intset *is = o->ptr;
+            asize = sizeof(*is)+is->encoding*is->length;
+        } else {
+            asize = sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d));
+            if (z) asize += sizeof(zset)-sizeof(dict);
+            if (dictSize(d)) {
+                de = dictGetRandomKey(d);
+                ele = dictGetEntryKey(de);
+                elesize = (ele->encoding == REDIS_ENCODING_RAW) ?
+                                (sizeof(*o)+sdslen(ele->ptr)) : sizeof(*o);
+                asize += (sizeof(struct dictEntry)+elesize)*dictSize(d);
+                if (z) asize += sizeof(zskiplistNode)*dictSize(d);
+            }
         }
         break;
     case REDIS_HASH:
         }
         break;
     case REDIS_HASH:
@@ -1075,6 +1079,11 @@ int dontWaitForSwappedKey(redisClient *c, robj *key) {
     listIter li;
     struct dictEntry *de;
 
     listIter li;
     struct dictEntry *de;
 
+    /* The key object might be destroyed when deleted from the c->io_keys
+     * list (and the "key" argument is physically the same object as the
+     * object inside the list), so we need to protect it. */
+    incrRefCount(key);
+
     /* Remove the key from the list of keys this client is waiting for. */
     listRewind(c->io_keys,&li);
     while ((ln = listNext(&li)) != NULL) {
     /* Remove the key from the list of keys this client is waiting for. */
     listRewind(c->io_keys,&li);
     while ((ln = listNext(&li)) != NULL) {
@@ -1095,6 +1104,7 @@ int dontWaitForSwappedKey(redisClient *c, robj *key) {
     if (listLength(l) == 0)
         dictDelete(c->db->io_keys,key);
 
     if (listLength(l) == 0)
         dictDelete(c->db->io_keys,key);
 
+    decrRefCount(key);
     return listLength(c->io_keys) == 0;
 }
 
     return listLength(c->io_keys) == 0;
 }