From: antirez Date: Mon, 22 Mar 2010 16:31:46 +0000 (+0100) Subject: Merged gnrfan patches fixing issues 191, 193, 194 X-Git-Url: https://git.saurik.com/redis.git/commitdiff_plain/44efe66ef2ff2d6ae7df7363fb1e62df3b16f4ab?hp=723fb69b9e354abcf1c13a7a65b2e781b035d8b3 Merged gnrfan patches fixing issues 191, 193, 194 --- diff --git a/Changelog b/Changelog index 09b80b71..13871ebf 100644 --- 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 f9fa8f2a..237fb649 100644 --- 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 3e07c5fb..ec74c001 100644 --- 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)) { diff --git a/redis.conf b/redis.conf index 0ed593d2..fc5ac59d 100644 --- a/redis.conf +++ b/redis.conf @@ -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