]> git.saurik.com Git - redis.git/blobdiff - redis.c
Merged gnrfan patches fixing issues 191, 193, 194
[redis.git] / redis.c
diff --git a/redis.c b/redis.c
index ce4c50b693f187413179bd18fbe7f5208dddceb0..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"
@@ -799,6 +799,8 @@ static struct redisCommand cmdTable[] = {
     {NULL,NULL,0,0,NULL,0,0,0}
 };
 
+static void usage();
+
 /*============================ Utility functions ============================ */
 
 /* Glob-style pattern matching. */
@@ -1616,12 +1618,15 @@ static void loadServerConfig(char *filename) {
     char buf[REDIS_CONFIGLINE_MAX+1], *err = NULL;
     int linenum = 0;
     sds line = NULL;
+    char *errormsg = "Fatal error, can't open config file '%s'";
+    char *errorbuf = zmalloc(sizeof(char)*(strlen(errormsg)+strlen(filename)));
+    sprintf(errorbuf, errormsg, filename);
 
     if (filename[0] == '-' && filename[1] == '\0')
         fp = stdin;
     else {
         if ((fp = fopen(filename,"r")) == NULL) {
-            redisLog(REDIS_WARNING,"Fatal error, can't open config file");
+            redisLog(REDIS_WARNING, errorbuf);
             exit(1);
         }
     }
@@ -1703,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) {
@@ -6486,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"
@@ -8320,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);
 }
@@ -8722,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++;
 }
@@ -9129,19 +9170,23 @@ static void version() {
     exit(0);
 }
 
+static void usage() {
+    fprintf(stderr,"Usage: ./redis-server [/path/to/redis.conf]\n");
+    exit(1);
+}
+
 int main(int argc, char **argv) {
     time_t start;
 
     initServerConfig();
     if (argc == 2) {
-        if ((strcmp(argv[1], "-v") == 0) || (strcmp(argv[1], "--version") == 0)) {
-            version();
-        }
+        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) {
-        fprintf(stderr,"Usage: ./redis-server [/path/to/redis.conf]\n");
-        exit(1);
+    } else if ((argc > 2)) {
+        usage();
     } else {
         redisLog(REDIS_WARNING,"Warning: no config file specified, using the default config. In order to specify a config file use 'redis-server /path/to/redis.conf'");
     }