]> git.saurik.com Git - redis.git/commitdiff
Merged gnrfan patches fixing issues 191, 193, 194
authorantirez <antirez@gmail.com>
Mon, 22 Mar 2010 16:31:46 +0000 (17:31 +0100)
committerantirez <antirez@gmail.com>
Mon, 22 Mar 2010 16:31:46 +0000 (17:31 +0100)
Changelog
TODO
redis.c
redis.conf

index 09b80b715ef839f601875b6659a969cc4da6a041..13871ebfc15ad1cd3f9f8ad7a60a836076879380 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,11 @@
+2010-03-19 support for include directive in config parser
+2010-03-19 Removed a stupid overriding of config values due to a wrong cut&paste
+2010-03-19 VM hash type swappability implemented. Handling of failed pthread_create() call.
+2010-03-18 increment server.dirty on HDEL
+2010-03-18 Redis 1.3.6
+2010-03-18 test-redis.tcl dataset digest function Hash support
+2010-03-18 zipmap fix for large values
+2010-03-18 Optimization fixed and re-activated
 2010-03-18 reverted an optimization that makes Redis not stable
 2010-03-18 Fixed redis-cli auth code
 2010-03-17 HDEL fix, an optimization for comparison of objects in hash table lookups when they are integer encoding
diff --git a/TODO b/TODO
index f9fa8f2af736a2d7887f7ae4d3cd25bb3f303344..237fb649918f626836febe2e8a7c1234a7a7d43a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -8,8 +8,6 @@ VERSION 2.0 TODO
 * Save dataset / fsync() on SIGTERM
 * MULTI/EXEC should support the "EXEC FSYNC" form?
 * BLPOP & C. tests (write a non blocking Tcl client as first step)
-* ZCOUNT sortedset min max
-* ZRANK: http://docs.google.com/viewer?a=v&q=cache:tCQaP3ZeN4YJ:courses.csail.mit.edu/6.046/spring04/handouts/ps5-sol.pdf+skip+list+rank+operation+augmented&hl=en&pid=bl&srcid=ADGEEShXuNjTcZyXw_1cq9OaWpSXy3PprjXqVzmM-LE0ETFznLyrDXJKQ_mBPNT10R8ErkoiXD9JbMw_FaoHmOA4yoGVrA7tZWiy393JwfCwuewuP93sjbkzZ_gnEp83jYhPYjThaIzw&sig=AHIEtbRF0GkYCdYRFtTJBE69senXZwFY0w
 * Once ZRANK is implemented, change the implementation of ZCOUNT to use the augmented skiplist in order to be much faster.
 * Write doc for ZCOUNT, and for open / closed intervals of sorted sets range operations.
 
@@ -29,7 +27,7 @@ Virtual Memory sub-TODO:
 
 * Hashes (GET/SET/DEL/INCRBY/EXISTS/FIELDS/LEN/MSET/MGET). Special encoding for hashes with less than N elements.
 * Write documentation for APPEND
-* Implement LEN, SUBSTR, PEEK, POKE, SETBIT, GETBIT
+* Implement LEN, PEEK, POKE, SETBIT, GETBIT
 
 VERSION 2.2 TODO (Fault tolerant sharding)
 ===========================================
diff --git a/redis.c b/redis.c
index 3e07c5fb5e83cee008f3e7f514bf9271bf510b3d..ec74c0018d6dd6fd6ae9dc41f8461976c0776e85 100644 (file)
--- a/redis.c
+++ b/redis.c
@@ -27,7 +27,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#define REDIS_VERSION "1.3.6"
+#define REDIS_VERSION "1.3.7"
 
 #include "fmacros.h"
 #include "config.h"
@@ -1104,6 +1104,8 @@ static dictType keylistDictType = {
     dictListDestructor          /* val destructor */
 };
 
+static void version();
+
 /* ========================= Random utility functions ======================= */
 
 /* Redis generally does not try to recover from out of memory conditions
@@ -1706,6 +1708,8 @@ static void loadServerConfig(char *filename) {
             if (server.dbnum < 1) {
                 err = "Invalid number of databases"; goto loaderr;
             }
+        } else if (!strcasecmp(argv[0],"include") && argc == 2) {
+            loadServerConfig(argv[1]);
         } else if (!strcasecmp(argv[0],"maxclients") && argc == 2) {
             server.maxclients = atoi(argv[1]);
         } else if (!strcasecmp(argv[0],"maxmemory") && argc == 2) {
@@ -6489,9 +6493,6 @@ static sds genRedisInfoString(void) {
     int j;
     char hmem[64];
 
-    server.hash_max_zipmap_entries = REDIS_HASH_MAX_ZIPMAP_ENTRIES;
-    server.hash_max_zipmap_value = REDIS_HASH_MAX_ZIPMAP_VALUE;
-  
     bytesToHuman(hmem,zmalloc_used_memory());
     info = sdscatprintf(sdsempty(),
         "redis_version:%s\r\n"
@@ -8323,6 +8324,38 @@ static double computeObjectSwappability(robj *o) {
             if (z) asize += sizeof(zskiplistNode)*dictSize(d);
         }
         break;
+    case REDIS_HASH:
+        if (o->encoding == REDIS_ENCODING_ZIPMAP) {
+            unsigned char *p = zipmapRewind((unsigned char*)o->ptr);
+            unsigned int len = zipmapLen((unsigned char*)o->ptr);
+            unsigned int klen, vlen;
+            unsigned char *key, *val;
+
+            if ((p = zipmapNext(p,&key,&klen,&val,&vlen)) == NULL) {
+                klen = 0;
+                vlen = 0;
+            }
+            asize = len*(klen+vlen+3);
+        } else if (o->encoding == REDIS_ENCODING_HT) {
+            d = o->ptr;
+            asize = sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d));
+            if (dictSize(d)) {
+                long elesize;
+                robj *ele;
+
+                de = dictGetRandomKey(d);
+                ele = dictGetEntryKey(de);
+                elesize = (ele->encoding == REDIS_ENCODING_RAW) ?
+                                (sizeof(*o)+sdslen(ele->ptr)) :
+                                sizeof(*o);
+                ele = dictGetEntryVal(de);
+                elesize = (ele->encoding == REDIS_ENCODING_RAW) ?
+                                (sizeof(*o)+sdslen(ele->ptr)) :
+                                sizeof(*o);
+                asize += (sizeof(struct dictEntry)+elesize)*dictSize(d);
+            }
+        }
+        break;
     }
     return (double)age*log(1+asize);
 }
@@ -8725,13 +8758,18 @@ static void *IOThreadEntryPoint(void *arg) {
 static void spawnIOThread(void) {
     pthread_t thread;
     sigset_t mask, omask;
+    int err;
 
     sigemptyset(&mask);
     sigaddset(&mask,SIGCHLD);
     sigaddset(&mask,SIGHUP);
     sigaddset(&mask,SIGPIPE);
     pthread_sigmask(SIG_SETMASK, &mask, &omask);
-    pthread_create(&thread,&server.io_threads_attr,IOThreadEntryPoint,NULL);
+    while ((err = pthread_create(&thread,&server.io_threads_attr,IOThreadEntryPoint,NULL)) != 0) {
+        redisLog(REDIS_WARNING,"Unable to spawn an I/O thread: %s",
+            strerror(err));
+        usleep(1000000);
+    }
     pthread_sigmask(SIG_SETMASK, &omask, NULL);
     server.io_active_threads++;
 }
@@ -9127,6 +9165,11 @@ static void daemonize(void) {
     }
 }
 
+static void version() {
+    printf("Redis server version %s\n", REDIS_VERSION);
+    exit(0);
+}
+
 static void usage() {
     fprintf(stderr,"Usage: ./redis-server [/path/to/redis.conf]\n");
     exit(1);
@@ -9137,9 +9180,9 @@ int main(int argc, char **argv) {
 
     initServerConfig();
     if (argc == 2) {
-        if (strcmp(argv[1], "--help") == 0) {
-            usage();
-        }
+        if (strcmp(argv[1], "-v") == 0 ||
+            strcmp(argv[1], "--version") == 0) version();
+        if (strcmp(argv[1], "--help") == 0) usage();
         resetServerSaveParams();
         loadServerConfig(argv[1]);
     } else if ((argc > 2)) {
index 0ed593d2446f0a3222cf7c8bde8a3d3f931db186..fc5ac59d4db487d766a418e04055585b8caa6384 100644 (file)
@@ -278,3 +278,13 @@ shareobjectspoolsize 1024
 # configuration directives.
 hash-max-zipmap-entries 64
 hash-max-zipmap-value 512
+
+################################## INCLUDES ###################################
+
+# Include one or more other config files here.  This is useful if you
+# have a standard template that goes to all redis server but also need
+# to customize a few per-server settings.  Include files can include
+# other files, so use this wisely.
+#
+# include /path/to/local.conf
+# include /path/to/other.conf