* POSSIBILITY OF SUCH DAMAGE.
*/
-#define REDIS_VERSION "1.3.5"
+#define REDIS_VERSION "1.3.7"
#include "fmacros.h"
#include "config.h"
{NULL,NULL,0,0,NULL,0,0,0}
};
+static void usage();
+
/*============================ Utility functions ============================ */
/* Glob-style pattern matching. */
robj *o1 = (robj*) key1, *o2 = (robj*) key2;
int cmp;
+ if (o1->encoding == REDIS_ENCODING_INT &&
+ o2->encoding == REDIS_ENCODING_INT &&
+ o1->ptr == o2->ptr) return 1;
+
o1 = getDecodedObject(o1);
o2 = getDecodedObject(o2);
cmp = sdsDictKeyCompare(privdata,o1->ptr,o2->ptr);
dictListDestructor /* val destructor */
};
+static void version();
+
/* ========================= Random utility functions ======================= */
/* Redis generally does not try to recover from out of memory conditions
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);
}
}
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) {
checkType(c,o,REDIS_HASH)) return;
if (o->encoding == REDIS_ENCODING_ZIPMAP) {
+ robj *field = getDecodedObject(c->argv[2]);
+
o->ptr = zipmapDel((unsigned char*) o->ptr,
- (unsigned char*) c->argv[2]->ptr,
- sdslen(c->argv[2]->ptr), &deleted);
+ (unsigned char*) field->ptr,
+ sdslen(field->ptr), &deleted);
+ decrRefCount(field);
} else {
deleted = dictDelete((dict*)o->ptr,c->argv[2]) == DICT_OK;
}
+ if (deleted) server.dirty++;
addReply(c,deleted ? shared.cone : shared.czero);
}
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"
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);
}
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++;
}
}
}
+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);
+}
+
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], "--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'");
}