]> git.saurik.com Git - redis.git/commitdiff
Merge git://github.com/tmm1/redis
authorantirez <antirez@gmail.com>
Wed, 20 May 2009 08:42:43 +0000 (10:42 +0200)
committerantirez <antirez@gmail.com>
Wed, 20 May 2009 08:42:43 +0000 (10:42 +0200)
redis.c
redis.conf
test-redis.tcl

diff --git a/redis.c b/redis.c
index 12d211ab50e23ae8922b02a7a0d20d22e5c2fea2..fbd1bc3df1807678cc297dcdc8ec3958f4061c84 100644 (file)
--- a/redis.c
+++ b/redis.c
@@ -721,7 +721,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
     }
 
     /* Close connections of timedout clients */
-    if (!(loops % 10))
+    if (server.maxidletime && !(loops % 10))
         closeTimedoutClients();
 
     /* Check if a background saving in progress terminated */
@@ -960,7 +960,7 @@ static void loadServerConfig(char *filename) {
         /* Execute config directives */
         if (!strcasecmp(argv[0],"timeout") && argc == 2) {
             server.maxidletime = atoi(argv[1]);
-            if (server.maxidletime < 1) {
+            if (server.maxidletime < 0) {
                 err = "Invalid timeout value"; goto loaderr;
             }
         } else if (!strcasecmp(argv[0],"port") && argc == 2) {
@@ -3014,9 +3014,6 @@ static void sinterGenericCommand(redisClient *c, robj **setskeys, int setsnum, r
         /* If we have a target key where to store the resulting set
          * create this key with an empty set inside */
         dstset = createSetObject();
-        deleteKey(c->db,dstkey);
-        dictAdd(c->db->dict,dstkey,dstset);
-        incrRefCount(dstkey);
     }
 
     /* Iterate all the elements of the first (smallest) set, and test
@@ -3045,6 +3042,13 @@ static void sinterGenericCommand(redisClient *c, robj **setskeys, int setsnum, r
     }
     dictReleaseIterator(di);
 
+    if (dstkey) {
+        /* Store the resulting set into the target */
+        deleteKey(c->db,dstkey);
+        dictAdd(c->db->dict,dstkey,dstset);
+        incrRefCount(dstkey);
+    }
+
     if (!dstkey) {
         lenobj->ptr = sdscatprintf(sdsempty(),"*%d\r\n",cardinality);
     } else {
@@ -3096,23 +3100,10 @@ static void sunionDiffGenericCommand(redisClient *c, robj **setskeys, int setsnu
      * this set object will be the resulting object to set into the target key*/
     dstset = createSetObject();
 
-    /* The first thing we should output is the total number of elements...
-     * since this is a multi-bulk write, but at this stage we don't know
-     * the intersection set size, so we use a trick, append an empty object
-     * to the output list and save the pointer to later modify it with the
-     * right length */
-    if (dstkey) {
-        /* If we have a target key where to store the resulting set
-         * create this key with an empty set inside */
-        deleteKey(c->db,dstkey);
-        dictAdd(c->db->dict,dstkey,dstset);
-        incrRefCount(dstkey);
-        server.dirty++;
-    }
-
     /* Iterate all the elements of all the sets, add every element a single
      * time to the result set */
     for (j = 0; j < setsnum; j++) {
+        if (op == REDIS_OP_DIFF && j == 0 && !dv[j]) break; /* result set is empty */
         if (!dv[j]) continue; /* non existing keys are like empty sets */
 
         di = dictGetIterator(dv[j]);
@@ -3135,6 +3126,8 @@ static void sunionDiffGenericCommand(redisClient *c, robj **setskeys, int setsnu
             }
         }
         dictReleaseIterator(di);
+
+        if (op == REDIS_OP_DIFF && cardinality == 0) break; /* result set is empty */
     }
 
     /* Output the content of the resulting set, if not in STORE mode */
@@ -3152,6 +3145,13 @@ static void sunionDiffGenericCommand(redisClient *c, robj **setskeys, int setsnu
             addReply(c,shared.crlf);
         }
         dictReleaseIterator(di);
+    } 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);
+        server.dirty++;
     }
 
     /* Cleanup */
index 38592b02e6bc3c49c44fd717f4604d475456950f..e8c6cd828ade666975cfe448adbd133676e1d0e0 100644 (file)
@@ -16,7 +16,7 @@ port 6379
 #
 # bind 127.0.0.1
 
-# Close the connection after a client is idle for N seconds
+# Close the connection after a client is idle for N seconds (0 to disable)
 timeout 300
 
 # Save the DB on disk:
index bd58cb2e7183bea9fc62334ecad0f474ceeaf7c6..1672390346088270a423f5e33a80e78f558d9470 100644 (file)
@@ -481,6 +481,11 @@ proc main {server port} {
         lsort [$r smembers setres]
     } [lsort -uniq "[$r smembers set1] [$r smembers set2]"]
 
+    test {SUNIONSTORE with same src and dest} {
+        $r sunionstore set1 set1 set1
+        $r scard set1
+    } {1000}
+
     test {SINTER against three sets} {
         $r sadd set3 999
         $r sadd set3 995
@@ -494,6 +499,11 @@ proc main {server port} {
         lsort [$r smembers setres]
     } {995 999}
 
+    test {SINTERSTORE with same src and dest} {
+       $r sinterstore set1 set1 set1
+       $r scard set1
+    } {1000}
+
     test {SUNION with non existing keys} {
         lsort [$r sunion nokey1 set1 set2 nokey2]
     } [lsort -uniq "[$r smembers set1] [$r smembers set2]"]