diff --git a/deps/hiredis/sds.h b/deps/hiredis/sds.h index 6b46297c2..bb99f7c52 100644 --- a/deps/hiredis/sds.h +++ b/deps/hiredis/sds.h @@ -45,31 +45,41 @@ typedef char *sds; * However is here to document the layout of type 5 SDS strings. */ struct __attribute__ ((__packed__)) sdshdr5 { unsigned char flags; /* 3 lsb of type, and 5 msb of string length */ +#ifndef __cplusplus char buf[]; +#endif }; struct __attribute__ ((__packed__)) sdshdr8 { uint8_t len; /* used */ uint8_t alloc; /* excluding the header and null terminator */ unsigned char flags; /* 3 lsb of type, 5 unused bits */ +#ifndef __cplusplus char buf[]; +#endif }; struct __attribute__ ((__packed__)) sdshdr16 { uint16_t len; /* used */ uint16_t alloc; /* excluding the header and null terminator */ unsigned char flags; /* 3 lsb of type, 5 unused bits */ +#ifndef __cplusplus char buf[]; +#endif }; struct __attribute__ ((__packed__)) sdshdr32 { uint32_t len; /* used */ uint32_t alloc; /* excluding the header and null terminator */ unsigned char flags; /* 3 lsb of type, 5 unused bits */ +#ifndef __cplusplus char buf[]; +#endif }; struct __attribute__ ((__packed__)) sdshdr64 { uint64_t len; /* used */ uint64_t alloc; /* excluding the header and null terminator */ unsigned char flags; /* 3 lsb of type, 5 unused bits */ +#ifndef __cplusplus char buf[]; +#endif }; #define SDS_TYPE_5 0 diff --git a/src/Makefile b/src/Makefile index e228a4ff2..c787de7f9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -197,9 +197,9 @@ endif REDIS_SERVER_NAME=keydb-server REDIS_SENTINEL_NAME=keydb-sentinel -REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o lolwut.o lolwut5.o acl.o storage.o rdb-s3.o fastlock.o gopher.o $(ASM_OBJ) +REDIS_SERVER_OBJ=adlist.o quicklist.o ae.o anet.o dict.o server.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o sha1.o ziplist.o release.o networking.o util.o object.o db.o replication.o rdb.o t_string.o t_list.o t_set.o t_zset.o t_hash.o config.o aof.o pubsub.o multi.o debug.o sort.o intset.o syncio.o cluster.o crc16.o endianconv.o slowlog.o scripting.o bio.o rio.o rand.o memtest.o crc64.o bitops.o sentinel.o notify.o setproctitle.o blocked.o hyperloglog.o latency.o sparkline.o redis-check-rdb.o redis-check-aof.o geo.o lazyfree.o module.o evict.o expire.o geohash.o geohash_helper.o childinfo.o defrag.o siphash.o rax.o t_stream.o listpack.o localtime.o acl.o storage.o rdb-s3.o fastlock.o $(ASM_OBJ) REDIS_CLI_NAME=keydb-cli -REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o zmalloc.o release.o anet.o ae.o crc64.o siphash.o crc16.o storage-lite.o fastlock.o $(ASM_OBJ) +REDIS_CLI_OBJ=anet.o adlist.o dict.o redis-cli.o redis-cli-cpphelper.o zmalloc.o release.o anet.o ae.o crc64.o siphash.o crc16.o storage-lite.o fastlock.o $(ASM_OBJ) REDIS_BENCHMARK_NAME=keydb-benchmark REDIS_BENCHMARK_OBJ=ae.o anet.o redis-benchmark.o adlist.o dict.o zmalloc.o siphash.o redis-benchmark.o storage-lite.o fastlock.o $(ASM_OBJ) REDIS_CHECK_RDB_NAME=keydb-check-rdb diff --git a/src/acl.c b/src/acl.cpp similarity index 96% rename from src/acl.c rename to src/acl.cpp index b7756df79..6478b74ec 100644 --- a/src/acl.c +++ b/src/acl.cpp @@ -157,17 +157,17 @@ uint64_t ACLGetCommandCategoryFlagByName(const char *name) { /* Method for passwords/pattern comparison used for the user->passwords list * so that we can search for items with listSearchKey(). */ int ACLListMatchSds(void *a, void *b) { - return sdscmp(a,b) == 0; + return sdscmp((sds)a,(sds)b) == 0; } /* Method to free list elements from ACL users password/ptterns lists. */ void ACLListFreeSds(void *item) { - sdsfree(item); + sdsfree((sds)item); } /* Method to duplicate list elements from ACL users password/ptterns lists. */ void *ACLListDupSds(void *item) { - return sdsdup(item); + return sdsdup((sds)item); } /* Create a new user with the specified name, store it in the list @@ -177,7 +177,7 @@ void *ACLListDupSds(void *item) { * If the user with such name already exists NULL is returned. */ user *ACLCreateUser(const char *name, size_t namelen) { if (raxFind(Users,(unsigned char*)name,namelen) != raxNotFound) return NULL; - user *u = zmalloc(sizeof(*u), MALLOC_LOCAL); + user *u = (user*)zmalloc(sizeof(*u), MALLOC_LOCAL); u->name = sdsnewlen(name,namelen); u->flags = USER_FLAG_DISABLED; u->allowed_subcommands = NULL; @@ -229,7 +229,7 @@ void ACLFreeUserAndKillClients(user *u) { listNode *ln; listRewind(server.clients,&li); while ((ln = listNext(&li)) != NULL) { - client *c = listNodeValue(ln); + client *c = (client*)listNodeValue(ln); if (c->puser == u) { /* We'll free the conenction asynchronously, so * in theory to set a different user is not needed. @@ -337,7 +337,7 @@ int ACLSetUserCommandBitsForCategory(user *u, const char *category, int value) { dictIterator *di = dictGetIterator(server.orig_commands); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct redisCommand *cmd = dictGetVal(de); + struct redisCommand *cmd = (redisCommand*)dictGetVal(de); if (cmd->flags & CMD_MODULE) continue; /* Ignore modules commands. */ if (cmd->flags & cflag) { ACLSetUserCommandBit(u,cmd->id,value); @@ -362,7 +362,7 @@ int ACLCountCategoryBitsForUser(user *u, unsigned long *on, unsigned long *off, dictIterator *di = dictGetIterator(server.orig_commands); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct redisCommand *cmd = dictGetVal(de); + struct redisCommand *cmd = (redisCommand*)dictGetVal(de); if (cmd->flags & cflag) { if (ACLGetUserCommandBit(u,cmd->id)) (*on)++; @@ -431,7 +431,7 @@ sds ACLDescribeUserCommandRules(user *u) { dictIterator *di = dictGetIterator(server.orig_commands); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct redisCommand *cmd = dictGetVal(de); + struct redisCommand *cmd = (redisCommand*)dictGetVal(de); int userbit = ACLGetUserCommandBit(u,cmd->id); int fakebit = ACLGetUserCommandBit(fakeuser,cmd->id); if (userbit != fakebit) { @@ -501,7 +501,7 @@ sds ACLDescribeUser(user *u) { listNode *ln; listRewind(u->passwords,&li); while((ln = listNext(&li))) { - sds thispass = listNodeValue(ln); + sds thispass = (sds)listNodeValue(ln); res = sdscatlen(res,">",1); res = sdscatsds(res,thispass); res = sdscatlen(res," ",1); @@ -513,7 +513,7 @@ sds ACLDescribeUser(user *u) { } else { listRewind(u->patterns,&li); while((ln = listNext(&li))) { - sds thispat = listNodeValue(ln); + sds thispat = (sds)listNodeValue(ln); res = sdscatlen(res,"~",1); res = sdscatsds(res,thispat); res = sdscatlen(res," ",1); @@ -533,7 +533,7 @@ sds ACLDescribeUser(user *u) { struct redisCommand *ACLLookupCommand(const char *name) { struct redisCommand *cmd; sds sdsname = sdsnew(name); - cmd = dictFetchValue(server.orig_commands, sdsname); + cmd = (redisCommand*)dictFetchValue(server.orig_commands, sdsname); sdsfree(sdsname); return cmd; } @@ -570,7 +570,7 @@ void ACLAddAllowedSubcommand(user *u, unsigned long id, const char *sub) { /* If this is the first subcommand to be configured for * this user, we have to allocate the subcommands array. */ if (u->allowed_subcommands == NULL) { - u->allowed_subcommands = zcalloc(USER_COMMAND_BITS_COUNT * + u->allowed_subcommands = (sds**)zcalloc(USER_COMMAND_BITS_COUNT * sizeof(sds*), MALLOC_LOCAL); } @@ -589,7 +589,7 @@ void ACLAddAllowedSubcommand(user *u, unsigned long id, const char *sub) { /* Now we can make space for the new item (and the null term). */ items += 2; - u->allowed_subcommands[id] = zrealloc(u->allowed_subcommands[id], + u->allowed_subcommands[id] = (sds*)zrealloc(u->allowed_subcommands[id], sizeof(sds)*items, MALLOC_LOCAL); u->allowed_subcommands[id][items-2] = sdsnew(sub); u->allowed_subcommands[id][items-1] = NULL; @@ -802,8 +802,8 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen) { /* Return a description of the error that occurred in ACLSetUser() according to * the errno value set by the function on error. */ -char *ACLSetUserStringError(void) { - char *errmsg = "Wrong format"; +const char *ACLSetUserStringError(void) { + const char *errmsg = "Wrong format"; if (errno == ENOENT) errmsg = "Unknown command or category name in ACL"; else if (errno == EINVAL) @@ -830,7 +830,7 @@ char *ACLSetUserStringError(void) { sds ACLDefaultUserFirstPassword(void) { if (listLength(DefaultUser->passwords) == 0) return NULL; listNode *first = listFirst(DefaultUser->passwords); - return listNodeValue(first); + return (sds)listNodeValue(first); } /* Initialize the default user, that will always exist for all the process @@ -857,7 +857,7 @@ void ACLInit(void) { * ENONENT: if the specified user does not exist at all. */ int ACLCheckUserCredentials(robj *username, robj *password) { - user *u = ACLGetUserByName(ptrFromObj(username),sdslen(ptrFromObj(username))); + user *u = ACLGetUserByName(szFromObj(username),sdslen(szFromObj(username))); if (u == NULL) { errno = ENOENT; return C_ERR; @@ -878,8 +878,8 @@ int ACLCheckUserCredentials(robj *username, robj *password) { listNode *ln; listRewind(u->passwords,&li); while((ln = listNext(&li))) { - sds thispass = listNodeValue(ln); - if (!time_independent_strcmp(ptrFromObj(password), thispass)) + sds thispass = (sds)listNodeValue(ln); + if (!time_independent_strcmp(szFromObj(password), thispass)) return C_OK; } @@ -944,7 +944,7 @@ unsigned long ACLGetCommandID(const char *cmdname) { user *ACLGetUserByName(const char *name, size_t namelen) { void *myuser = raxFind(Users,(unsigned char*)name,namelen); if (myuser == raxNotFound) return NULL; - return myuser; + return (user*)myuser; } /* Check if the command ready to be excuted in the client 'c', and already @@ -982,7 +982,7 @@ int ACLCheckCommandPerm(client *c) { while (1) { if (u->allowed_subcommands[id][subid] == NULL) return ACL_DENIED_CMD; - if (!strcasecmp(ptrFromObj(c->argv[1]), + if (!strcasecmp(szFromObj(c->argv[1]), u->allowed_subcommands[id][subid])) break; /* Subcommand match found. Stop here. */ subid++; @@ -1005,11 +1005,11 @@ int ACLCheckCommandPerm(client *c) { /* Test this key against every pattern. */ int match = 0; while((ln = listNext(&li))) { - sds pattern = listNodeValue(ln); + sds pattern = (sds)listNodeValue(ln); size_t plen = sdslen(pattern); int idx = keyidx[j]; - if (stringmatchlen(pattern,plen,ptrFromObj(c->argv[idx]), - sdslen(ptrFromObj(c->argv[idx])),0)) + if (stringmatchlen(pattern,plen,szFromObj(c->argv[idx]), + sdslen(szFromObj(c->argv[idx])),0)) { match = 1; break; @@ -1071,7 +1071,7 @@ int ACLAppendUserForLoading(sds *argv, int argc, int *argc_err) { } /* Rules look valid, let's append the user to the list. */ - sds *copy = zmalloc(sizeof(sds)*argc, MALLOC_LOCAL); + sds *copy = (sds*)zmalloc(sizeof(sds)*argc, MALLOC_LOCAL); for (int j = 1; j < argc; j++) copy[j-1] = sdsdup(argv[j]); copy[argc-1] = NULL; listAddNodeTail(UsersToLoad,copy); @@ -1087,7 +1087,7 @@ int ACLLoadConfiguredUsers(void) { listNode *ln; listRewind(UsersToLoad,&li); while ((ln = listNext(&li)) != NULL) { - sds *aclrules = listNodeValue(ln); + sds *aclrules = (sds*)listNodeValue(ln); sds username = aclrules[0]; user *u = ACLCreateUser(username,sdslen(username)); if (!u) { @@ -1099,7 +1099,7 @@ int ACLLoadConfiguredUsers(void) { /* Load every rule defined for this user. */ for (int j = 1; aclrules[j]; j++) { if (ACLSetUser(u,aclrules[j],sdslen(aclrules[j])) != C_OK) { - char *errmsg = ACLSetUserStringError(); + const char *errmsg = ACLSetUserStringError(); serverLog(LL_WARNING,"Error loading ACL rule '%s' for " "the user named '%s': %s", aclrules[j],aclrules[0],errmsg); @@ -1220,7 +1220,7 @@ sds ACLLoadFromFile(const char *filename) { int j; for (j = 2; j < argc; j++) { if (ACLSetUser(fakeuser,argv[j],sdslen(argv[j])) != C_OK) { - char *errmsg = ACLSetUserStringError(); + const char *errmsg = ACLSetUserStringError(); errors = sdscatprintf(errors, "%s:%d: %s. ", server.acl_filename, linenum, errmsg); @@ -1262,10 +1262,10 @@ sds ACLLoadFromFile(const char *filename) { /* The default user pointer is referenced in different places: instead * of replacing such occurrences it is much simpler to copy the new * default user configuration in the old one. */ - user *new = ACLGetUserByName("default",7); - serverAssert(new != NULL); - ACLCopyUser(DefaultUser,new); - ACLFreeUser(new); + user *newuser = ACLGetUserByName("default",7); + serverAssert(newuser != NULL); + ACLCopyUser(DefaultUser,newuser); + ACLFreeUser(newuser); raxInsert(Users,(unsigned char*)"default",7,DefaultUser,NULL); raxRemove(old_users,(unsigned char*)"default",7,NULL); ACLFreeUsersSet(old_users); @@ -1294,7 +1294,7 @@ int ACLSaveToFile(const char *filename) { raxStart(&ri,Users); raxSeek(&ri,"^",NULL,0); while(raxNext(&ri)) { - user *u = ri.data; + user *u = (user*)ri.data; /* Return information in the configuration file format. */ sds user = sdsnew("user "); user = sdscatsds(user,u->name); @@ -1393,9 +1393,9 @@ void ACLLoadUsersAtStartup(void) { * ACL WHOAMI */ void aclCommand(client *c) { - char *sub = ptrFromObj(c->argv[1]); + char *sub = szFromObj(c->argv[1]); if (!strcasecmp(sub,"setuser") && c->argc >= 3) { - sds username = ptrFromObj(c->argv[2]); + sds username = szFromObj(c->argv[2]); /* Create a temporary user to validate and stage all changes against * before applying to an existing user or creating a new user. If all * arguments are valid the user parameters will all be applied together. @@ -1405,8 +1405,8 @@ void aclCommand(client *c) { if (u) ACLCopyUser(tempu, u); for (int j = 3; j < c->argc; j++) { - if (ACLSetUser(tempu,ptrFromObj(c->argv[j]),sdslen(ptrFromObj(c->argv[j]))) != C_OK) { - char *errmsg = ACLSetUserStringError(); + if (ACLSetUser(tempu,szFromObj(c->argv[j]),sdslen(szFromObj(c->argv[j]))) != C_OK) { + const char *errmsg = ACLSetUserStringError(); addReplyErrorFormat(c, "Error in ACL SETUSER modifier '%s': %s", (char*)ptrFromObj(c->argv[j]), errmsg); @@ -1425,7 +1425,7 @@ void aclCommand(client *c) { } else if (!strcasecmp(sub,"deluser") && c->argc >= 3) { int deleted = 0; for (int j = 2; j < c->argc; j++) { - sds username = ptrFromObj(c->argv[j]); + sds username = szFromObj(c->argv[j]); if (!strcmp(username,"default")) { addReplyError(c,"The 'default' user cannot be removed"); return; @@ -1433,7 +1433,7 @@ void aclCommand(client *c) { } for (int j = 2; j < c->argc; j++) { - sds username = ptrFromObj(c->argv[j]); + sds username = szFromObj(c->argv[j]); user *u; if (raxRemove(Users,(unsigned char*)username, sdslen(username), @@ -1445,7 +1445,7 @@ void aclCommand(client *c) { } addReplyLongLong(c,deleted); } else if (!strcasecmp(sub,"getuser") && c->argc == 3) { - user *u = ACLGetUserByName(ptrFromObj(c->argv[2]),sdslen(ptrFromObj(c->argv[2]))); + user *u = ACLGetUserByName(szFromObj(c->argv[2]),sdslen(szFromObj(c->argv[2]))); if (u == NULL) { addReplyNull(c); return; @@ -1472,7 +1472,7 @@ void aclCommand(client *c) { listNode *ln; listRewind(u->passwords,&li); while((ln = listNext(&li))) { - sds thispass = listNodeValue(ln); + sds thispass = (sds)listNodeValue(ln); addReplyBulkCBuffer(c,thispass,sdslen(thispass)); } @@ -1492,7 +1492,7 @@ void aclCommand(client *c) { listNode *ln; listRewind(u->patterns,&li); while((ln = listNext(&li))) { - sds thispat = listNodeValue(ln); + sds thispat = (sds)listNodeValue(ln); addReplyBulkCBuffer(c,thispat,sdslen(thispat)); } } @@ -1505,7 +1505,7 @@ void aclCommand(client *c) { raxStart(&ri,Users); raxSeek(&ri,"^",NULL,0); while(raxNext(&ri)) { - user *u = ri.data; + user *u = (user*)ri.data; if (justnames) { addReplyBulkCBuffer(c,u->name,sdslen(u->name)); } else { @@ -1554,7 +1554,7 @@ void aclCommand(client *c) { addReplyBulkCString(c,ACLCommandCategories[j].name); setDeferredArrayLen(c,dl,j); } else if (!strcasecmp(sub,"cat") && c->argc == 3) { - uint64_t cflag = ACLGetCommandCategoryFlagByName(ptrFromObj(c->argv[2])); + uint64_t cflag = ACLGetCommandCategoryFlagByName(szFromObj(c->argv[2])); if (cflag == 0) { addReplyErrorFormat(c, "Unknown category '%s'", (char*)ptrFromObj(c->argv[2])); return; @@ -1564,7 +1564,7 @@ void aclCommand(client *c) { dictIterator *di = dictGetIterator(server.orig_commands); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct redisCommand *cmd = dictGetVal(de); + struct redisCommand *cmd = (redisCommand*)dictGetVal(de); if (cmd->flags & CMD_MODULE) continue; if (cmd->flags & cflag) { addReplyBulkCString(c,cmd->name); diff --git a/src/aof.c b/src/aof.cpp similarity index 97% rename from src/aof.c rename to src/aof.cpp index fb8360bf5..049e75e93 100644 --- a/src/aof.c +++ b/src/aof.cpp @@ -83,7 +83,7 @@ unsigned long aofRewriteBufferSize(void) { listRewind(server.aof_rewrite_buf_blocks,&li); while((ln = listNext(&li))) { - aofrwblock *block = listNodeValue(ln); + aofrwblock *block = (aofrwblock*)listNodeValue(ln); size += block->used; } return size; @@ -105,7 +105,7 @@ void aofChildWriteDiffData(aeEventLoop *el, int fd, void *privdata, int mask) { while(1) { ln = listFirst(server.aof_rewrite_buf_blocks); - block = ln ? ln->value : NULL; + block = (aofrwblock*)(ln ? ln->value : NULL); if (server.aof_stop_sending_diff || !block) { aeDeleteFileEvent(el,server.aof_pipe_write_data_to_child, AE_WRITABLE); @@ -126,7 +126,7 @@ void aofChildWriteDiffData(aeEventLoop *el, int fd, void *privdata, int mask) { /* Append data to the AOF rewrite buffer, allocating new blocks if needed. */ void aofRewriteBufferAppend(unsigned char *s, unsigned long len) { listNode *ln = listLast(server.aof_rewrite_buf_blocks); - aofrwblock *block = ln ? ln->value : NULL; + aofrwblock *block = (aofrwblock*)(ln ? ln->value : NULL); while(len) { /* If we already got at least an allocated block, try appending @@ -145,7 +145,7 @@ void aofRewriteBufferAppend(unsigned char *s, unsigned long len) { if (len) { /* First block to allocate, or need another block. */ int numblocks; - block = zmalloc(sizeof(*block), MALLOC_LOCAL); + block = (aofrwblock*)zmalloc(sizeof(*block), MALLOC_LOCAL); block->free = AOF_RW_BUF_BLOCK_SIZE; block->used = 0; listAddNodeTail(server.aof_rewrite_buf_blocks,block); @@ -180,7 +180,7 @@ ssize_t aofRewriteBufferWrite(int fd) { listRewind(server.aof_rewrite_buf_blocks,&li); while((ln = listNext(&li))) { - aofrwblock *block = listNodeValue(ln); + aofrwblock *block = (aofrwblock*)listNodeValue(ln); ssize_t nwritten; if (block->used) { @@ -508,11 +508,11 @@ sds catAppendOnlyGenericCommand(sds dst, int argc, robj **argv) { for (j = 0; j < argc; j++) { o = getDecodedObject(argv[j]); buf[0] = '$'; - len = 1+ll2string(buf+1,sizeof(buf)-1,sdslen(ptrFromObj(o))); + len = 1+ll2string(buf+1,sizeof(buf)-1,sdslen(szFromObj(o))); buf[len++] = '\r'; buf[len++] = '\n'; dst = sdscatlen(dst,buf,len); - dst = sdscatlen(dst,ptrFromObj(o),sdslen(ptrFromObj(o))); + dst = sdscatlen(dst,ptrFromObj(o),sdslen(szFromObj(o))); dst = sdscatlen(dst,"\r\n",2); decrRefCount(o); } @@ -532,7 +532,7 @@ sds catAppendOnlyExpireAtCommand(sds buf, struct redisCommand *cmd, robj *key, r /* Make sure we can use strtoll */ seconds = getDecodedObject(seconds); - when = strtoll(ptrFromObj(seconds),NULL,10); + when = strtoll(szFromObj(seconds),NULL,10); /* Convert argument into milliseconds for EXPIRE, SETEX, EXPIREAT */ if (cmd->proc == expireCommand || cmd->proc == setexCommand || cmd->proc == expireatCommand) @@ -589,8 +589,8 @@ void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv, int a /* Translate SET [EX seconds][PX milliseconds] to SET and PEXPIREAT */ buf = catAppendOnlyGenericCommand(buf,3,argv); for (i = 3; i < argc; i ++) { - if (!strcasecmp(ptrFromObj(argv[i]), "ex")) exarg = argv[i+1]; - if (!strcasecmp(ptrFromObj(argv[i]), "px")) pxarg = argv[i+1]; + if (!strcasecmp(szFromObj(argv[i]), "ex")) exarg = argv[i+1]; + if (!strcasecmp(szFromObj(argv[i]), "px")) pxarg = argv[i+1]; } serverAssert(!(exarg && pxarg)); if (exarg) @@ -628,8 +628,8 @@ void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv, int a /* In Redis commands are always executed in the context of a client, so in * order to load the append only file we need to create a fake client. */ -struct client *createFakeClient(void) { - struct client *c = zmalloc(sizeof(*c), MALLOC_LOCAL); +client *createFakeClient(void) { + client *c = (client*)zmalloc(sizeof(*c), MALLOC_LOCAL); selectDb(c,0); c->fd = -1; @@ -762,7 +762,7 @@ int loadAppendOnlyFile(char *filename) { argc = atoi(buf+1); if (argc < 1) goto fmterr; - argv = zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL); + argv = (robj**)zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL); fakeClient->argc = argc; fakeClient->argv = argv; @@ -790,7 +790,7 @@ int loadAppendOnlyFile(char *filename) { } /* Command lookup */ - cmd = lookupCommand(ptrFromObj(argv[0])); + cmd = lookupCommand(szFromObj(argv[0])); if (!cmd) { serverLog(LL_WARNING, "Unknown command '%s' reading the append only file", @@ -898,7 +898,7 @@ int rioWriteBulkObject(rio *r, robj *obj) { if (obj->encoding == OBJ_ENCODING_INT) { return rioWriteBulkLongLong(r,(long)obj->m_ptr); } else if (sdsEncodedObject(obj)) { - return rioWriteBulkString(r,ptrFromObj(obj),sdslen(ptrFromObj(obj))); + return rioWriteBulkString(r,szFromObj(obj),sdslen(szFromObj(obj))); } else { serverPanic("Unknown string encoding"); } @@ -910,7 +910,7 @@ int rewriteListObject(rio *r, robj *key, robj *o) { long long count = 0, items = listTypeLength(o); if (o->encoding == OBJ_ENCODING_QUICKLIST) { - quicklist *list = ptrFromObj(o); + quicklist *list = (quicklist*)ptrFromObj(o); quicklistIter *li = quicklistGetIterator(list, AL_START_HEAD); quicklistEntry entry; @@ -947,7 +947,7 @@ int rewriteSetObject(rio *r, robj *key, robj *o) { int ii = 0; int64_t llval; - while(intsetGet(ptrFromObj(o),ii++,&llval)) { + while(intsetGet((intset*)ptrFromObj(o),ii++,&llval)) { if (count == 0) { int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? AOF_REWRITE_ITEMS_PER_CMD : items; @@ -961,11 +961,11 @@ int rewriteSetObject(rio *r, robj *key, robj *o) { items--; } } else if (o->encoding == OBJ_ENCODING_HT) { - dictIterator *di = dictGetIterator(ptrFromObj(o)); + dictIterator *di = dictGetIterator((dict*)ptrFromObj(o)); dictEntry *de; while((de = dictNext(di)) != NULL) { - sds ele = dictGetKey(de); + sds ele = (sds)dictGetKey(de); if (count == 0) { int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? AOF_REWRITE_ITEMS_PER_CMD : items; @@ -991,7 +991,7 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) { long long count = 0, items = zsetLength(o); if (o->encoding == OBJ_ENCODING_ZIPLIST) { - unsigned char *zl = ptrFromObj(o); + unsigned char *zl = (unsigned char*)ptrFromObj(o); unsigned char *eptr, *sptr; unsigned char *vstr; unsigned int vlen; @@ -1026,13 +1026,13 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) { items--; } } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = ptrFromObj(o); + zset *zs = (zset*)ptrFromObj(o); dictIterator *di = dictGetIterator(zs->pdict); dictEntry *de; while((de = dictNext(di)) != NULL) { - sds ele = dictGetKey(de); - double *score = dictGetVal(de); + sds ele = (sds)dictGetKey(de); + double *score = (double*)dictGetVal(de); if (count == 0) { int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? @@ -1147,7 +1147,7 @@ int rioWriteStreamPendingEntry(rio *r, robj *key, const char *groupname, size_t /* Emit the commands needed to rebuild a stream object. * The function returns 0 on error, 1 on success. */ int rewriteStreamObject(rio *r, robj *key, robj *o) { - stream *s = ptrFromObj(o); + stream *s = (stream*)ptrFromObj(o); streamIterator si; streamIteratorStart(&si,s,NULL,NULL,0); streamID id; @@ -1200,7 +1200,7 @@ int rewriteStreamObject(rio *r, robj *key, robj *o) { raxStart(&ri,s->cgroups); raxSeek(&ri,"^",NULL,0); while(raxNext(&ri)) { - streamCG *group = ri.data; + streamCG *group = (streamCG*)ri.data; /* Emit the XGROUP CREATE in order to create the group. */ if (rioWriteBulkCount(r,'*',5) == 0) return 0; if (rioWriteBulkString(r,"XGROUP",6) == 0) return 0; @@ -1216,14 +1216,14 @@ int rewriteStreamObject(rio *r, robj *key, robj *o) { raxStart(&ri_cons,group->consumers); raxSeek(&ri_cons,"^",NULL,0); while(raxNext(&ri_cons)) { - streamConsumer *consumer = ri_cons.data; + streamConsumer *consumer = (streamConsumer*)ri_cons.data; /* For the current consumer, iterate all the PEL entries * to emit the XCLAIM protocol. */ raxIterator ri_pel; raxStart(&ri_pel,consumer->pel); raxSeek(&ri_pel,"^",NULL,0); while(raxNext(&ri_pel)) { - streamNACK *nack = ri_pel.data; + streamNACK *nack = (streamNACK*)ri_pel.data; if (rioWriteStreamPendingEntry(r,key,(char*)ri.key, ri.key_len,consumer, ri_pel.key,nack) == 0) @@ -1247,7 +1247,7 @@ int rewriteStreamObject(rio *r, robj *key, robj *o) { * The function returns 0 on error, 1 on success. */ int rewriteModuleObject(rio *r, robj *key, robj *o) { RedisModuleIO io; - moduleValue *mv = ptrFromObj(o); + moduleValue *mv = (moduleValue*)ptrFromObj(o); moduleType *mt = mv->type; moduleInitIOContext(io,mt,r,key); mt->aof_rewrite(&io,key,mv->value); @@ -1296,8 +1296,8 @@ int rewriteAppendOnlyFileRio(rio *aof) { robj key, *o; long long expiretime; - keystr = dictGetKey(de); - o = dictGetVal(de); + keystr = (sds)dictGetKey(de); + o = (robj*)dictGetVal(de); initStaticStringObject(key,keystr); expiretime = getExpire(db,&key); @@ -1360,6 +1360,8 @@ int rewriteAppendOnlyFile(char *filename) { FILE *fp; char tmpfile[256]; char byte; + int nodata = 0; + mstime_t start = 0; /* Note that we have to use a different temp name here compared to the * one used by rewriteAppendOnlyFileBackground() function. */ @@ -1397,8 +1399,7 @@ int rewriteAppendOnlyFile(char *filename) { * some more data in a loop as soon as there is a good chance more data * will come. If it looks like we are wasting time, we abort (this * happens after 20 ms without new data). */ - int nodata = 0; - mstime_t start = mstime(); + start = mstime(); while(mstime()-start < 1000 && nodata < 20) { if (aeWait(server.aof_pipe_read_data_from_parent, AE_READABLE, 1) <= 0) { diff --git a/src/bio.c b/src/bio.cpp similarity index 96% rename from src/bio.c rename to src/bio.cpp index 023340b97..effedbebd 100644 --- a/src/bio.c +++ b/src/bio.cpp @@ -129,7 +129,7 @@ void bioInit(void) { } void bioCreateBackgroundJob(int type, void *arg1, void *arg2, void *arg3) { - struct bio_job *job = zmalloc(sizeof(*job), MALLOC_LOCAL); + struct bio_job *job = (bio_job*)zmalloc(sizeof(*job), MALLOC_LOCAL); job->time = time(NULL); job->arg1 = arg1; @@ -178,7 +178,7 @@ void *bioProcessBackgroundJobs(void *arg) { } /* Pop the job from the queue. */ ln = listFirst(bio_jobs[type]); - job = ln->value; + job = (bio_job*)ln->value; /* It is now possible to unlock the background system as we know have * a stand alone job structure to process.*/ pthread_mutex_unlock(&bio_mutex[type]); @@ -194,11 +194,11 @@ void *bioProcessBackgroundJobs(void *arg) { * arg2 & arg3 -> free two dictionaries (a Redis DB). * only arg3 -> free the skiplist. */ if (job->arg1) - lazyfreeFreeObjectFromBioThread(job->arg1); + lazyfreeFreeObjectFromBioThread((robj*)job->arg1); else if (job->arg2 && job->arg3) - lazyfreeFreeDatabaseFromBioThread(job->arg2,job->arg3); + lazyfreeFreeDatabaseFromBioThread((dict*)job->arg2,(dict*)job->arg3); else if (job->arg3) - lazyfreeFreeSlotsMapFromBioThread(job->arg3); + lazyfreeFreeSlotsMapFromBioThread((rax*)job->arg3); } else { serverPanic("Wrong job type in bioProcessBackgroundJobs()."); } diff --git a/src/bitops.c b/src/bitops.cpp similarity index 96% rename from src/bitops.c rename to src/bitops.cpp index b473d9b97..ea9b9acfa 100644 --- a/src/bitops.c +++ b/src/bitops.cpp @@ -39,7 +39,7 @@ * work with a input string length up to 512 MB. */ size_t redisPopcount(void *s, long count) { size_t bits = 0; - unsigned char *p = s; + unsigned char *p = (unsigned char*)s; uint32_t *p4; static const unsigned char bitsinbyte[256] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8}; @@ -410,8 +410,8 @@ void printBits(unsigned char *p, unsigned long count) { * is multiplied by 'bits'. This is useful for the BITFIELD command. */ int getBitOffsetFromArgument(client *c, robj *o, size_t *offset, int hash, int bits) { long long loffset; - char *err = "bit offset is not an integer or out of range"; - char *p = ptrFromObj(o); + const char *err = "bit offset is not an integer or out of range"; + char *p = szFromObj(o); size_t plen = sdslen(p); int usehash = 0; @@ -445,8 +445,8 @@ int getBitOffsetFromArgument(client *c, robj *o, size_t *offset, int hash, int b * * On error C_ERR is returned and an error is sent to the client. */ int getBitfieldTypeFromArgument(client *c, robj *o, int *sign, int *bits) { - char *p = ptrFromObj(o); - char *err = "Invalid bitfield type. Use something like i16 u8. Note that u64 is not supported but i64 is."; + char *p = szFromObj(o); + const char *err = "Invalid bitfield type. Use something like i16 u8. Note that u64 is not supported but i64 is."; long long llbits; if (p[0] == 'i') { @@ -485,7 +485,7 @@ robj *lookupStringForBitCommand(client *c, size_t maxbit) { } else { if (checkType(c,o,OBJ_STRING)) return NULL; o = dbUnshareStringValue(c->db,c->argv[1],o); - o->m_ptr = sdsgrowzero(ptrFromObj(o),byte+1); + o->m_ptr = sdsgrowzero(szFromObj(o),byte+1); } return o; } @@ -514,7 +514,7 @@ unsigned char *getObjectReadOnlyString(robj *o, long *len, char *llbuf) { if (len) *len = ll2string(llbuf,LONG_STR_SIZE,(long)ptrFromObj(o)); } else if (o) { p = (unsigned char*) ptrFromObj(o); - if (len) *len = sdslen(ptrFromObj(o)); + if (len) *len = sdslen(szFromObj(o)); } else { if (len) *len = 0; } @@ -524,7 +524,7 @@ unsigned char *getObjectReadOnlyString(robj *o, long *len, char *llbuf) { /* SETBIT key offset bitvalue */ void setbitCommand(client *c) { robj *o; - char *err = "bit is not an integer or out of range"; + const char *err = "bit is not an integer or out of range"; size_t bitoffset; ssize_t byte, bit; int byteval, bitval; @@ -577,7 +577,7 @@ void getbitCommand(client *c) { byte = bitoffset >> 3; bit = 7 - (bitoffset & 0x7); if (sdsEncodedObject(o)) { - if (byte < sdslen(ptrFromObj(o))) + if (byte < sdslen(szFromObj(o))) bitval = ((uint8_t*)ptrFromObj(o))[byte] & (1 << bit); } else { if (byte < (size_t)ll2string(llbuf,sizeof(llbuf),(long)ptrFromObj(o))) @@ -589,7 +589,7 @@ void getbitCommand(client *c) { /* BITOP op_name target_key src_key1 src_key2 src_key3 ... src_keyN */ void bitopCommand(client *c) { - char *opname = ptrFromObj(c->argv[1]); + char *opname = szFromObj(c->argv[1]); robj *o, *targetkey = c->argv[2]; unsigned long op, j, numkeys; robj **objects; /* Array of source objects. */ @@ -621,9 +621,9 @@ void bitopCommand(client *c) { /* Lookup keys, and store pointers to the string objects into an array. */ numkeys = c->argc - 3; - src = zmalloc(sizeof(unsigned char*) * numkeys, MALLOC_LOCAL); - len = zmalloc(sizeof(long) * numkeys, MALLOC_LOCAL); - objects = zmalloc(sizeof(robj*) * numkeys, MALLOC_LOCAL); + src = (unsigned char**)zmalloc(sizeof(unsigned char*) * numkeys, MALLOC_LOCAL); + len = (unsigned long*)zmalloc(sizeof(long) * numkeys, MALLOC_LOCAL); + objects = (robj**)zmalloc(sizeof(robj*) * numkeys, MALLOC_LOCAL); for (j = 0; j < numkeys; j++) { o = lookupKeyRead(c->db,c->argv[j+3]); /* Handle non-existing keys as empty strings. */ @@ -647,8 +647,8 @@ void bitopCommand(client *c) { return; } objects[j] = getDecodedObject(o); - src[j] = ptrFromObj(objects[j]); - len[j] = sdslen(ptrFromObj(objects[j])); + src[j] = (unsigned char*)ptrFromObj(objects[j]); + len[j] = sdslen(szFromObj(objects[j])); if (len[j] > maxlen) maxlen = len[j]; if (j == 0 || len[j] < minlen) minlen = len[j]; } @@ -922,7 +922,7 @@ void bitfieldCommand(client *c) { for (j = 2; j < c->argc; j++) { int remargs = c->argc-j-1; /* Remaining args other than current. */ - char *subcmd = ptrFromObj(c->argv[j]); /* Current command name. */ + char *subcmd = szFromObj(c->argv[j]); /* Current command name. */ int opcode; /* Current operation code. */ long long i64 = 0; /* Signed SET value. */ int sign = 0; /* Signed or unsigned type? */ @@ -935,7 +935,7 @@ void bitfieldCommand(client *c) { else if (!strcasecmp(subcmd,"incrby") && remargs >= 3) opcode = BITFIELDOP_INCRBY; else if (!strcasecmp(subcmd,"overflow") && remargs >= 1) { - char *owtypename = ptrFromObj(c->argv[j+1]); + char *owtypename = szFromObj(c->argv[j+1]); j++; if (!strcasecmp(owtypename,"wrap")) owtype = BFOVERFLOW_WRAP; @@ -978,7 +978,7 @@ void bitfieldCommand(client *c) { } /* Populate the array of operations we'll process. */ - ops = zrealloc(ops,sizeof(*ops)*(numops+1), MALLOC_SHARED); + ops = (bitfieldOp*)zrealloc(ops,sizeof(*ops)*(numops+1), MALLOC_SHARED); ops[numops].offset = bitoffset; ops[numops].i64 = i64; ops[numops].opcode = opcode; @@ -1023,7 +1023,7 @@ void bitfieldCommand(client *c) { int64_t oldval, newval, wrapped, retval; int overflow; - oldval = getSignedBitfield(ptrFromObj(o),thisop->offset, + oldval = getSignedBitfield((unsigned char*)ptrFromObj(o),thisop->offset, thisop->bits); if (thisop->opcode == BITFIELDOP_INCRBY) { @@ -1044,7 +1044,7 @@ void bitfieldCommand(client *c) { * NULL to signal the condition. */ if (!(overflow && thisop->owtype == BFOVERFLOW_FAIL)) { addReplyLongLong(c,retval); - setSignedBitfield(ptrFromObj(o),thisop->offset, + setSignedBitfield((unsigned char*)ptrFromObj(o),thisop->offset, thisop->bits,newval); } else { addReplyNull(c); @@ -1053,7 +1053,7 @@ void bitfieldCommand(client *c) { uint64_t oldval, newval, wrapped, retval; int overflow; - oldval = getUnsignedBitfield(ptrFromObj(o),thisop->offset, + oldval = getUnsignedBitfield((unsigned char*)ptrFromObj(o),thisop->offset, thisop->bits); if (thisop->opcode == BITFIELDOP_INCRBY) { @@ -1073,7 +1073,7 @@ void bitfieldCommand(client *c) { * NULL to signal the condition. */ if (!(overflow && thisop->owtype == BFOVERFLOW_FAIL)) { addReplyLongLong(c,retval); - setUnsignedBitfield(ptrFromObj(o),thisop->offset, + setUnsignedBitfield((unsigned char*)ptrFromObj(o),thisop->offset, thisop->bits,newval); } else { addReplyNull(c); diff --git a/src/childinfo.c b/src/childinfo.cpp similarity index 100% rename from src/childinfo.c rename to src/childinfo.cpp diff --git a/src/cluster.c b/src/cluster.cpp similarity index 96% rename from src/cluster.c rename to src/cluster.cpp index 5448fa434..b86d8b7cc 100644 --- a/src/cluster.c +++ b/src/cluster.cpp @@ -82,7 +82,7 @@ struct redisMaster *getFirstMaster() serverAssert(listLength(server.masters) <= 1); if (!listLength(server.masters)) return NULL; - return listFirst(server.masters)->value; + return (redisMaster*)listFirst(server.masters)->value; } /* ----------------------------------------------------------------------------- @@ -127,7 +127,7 @@ int clusterLoadConfig(char *filename) { * * To simplify we allocate 1024+CLUSTER_SLOTS*128 bytes per line. */ maxline = 1024+CLUSTER_SLOTS*128; - line = zmalloc(maxline, MALLOC_LOCAL); + line = (char*)zmalloc(maxline, MALLOC_LOCAL); while(fgets(line,maxline,fp) != NULL) { int argc; sds *argv; @@ -442,7 +442,7 @@ void clusterInit(void) { exit(EXIT_FAILURE); } - server.cluster = zmalloc(sizeof(clusterState), MALLOC_LOCAL); + server.cluster = (clusterState*)zmalloc(sizeof(clusterState), MALLOC_LOCAL); server.cluster->myself = NULL; server.cluster->currentEpoch = 0; server.cluster->state = CLUSTER_FAIL; @@ -552,7 +552,7 @@ void clusterReset(int hard) { if (listLength(server.masters) > 0) { serverAssert(listLength(server.masters) == 1); - replicationUnsetMaster(listFirst(server.masters)->value); + replicationUnsetMaster((redisMaster*)listFirst(server.masters)->value); } emptyDb(-1,EMPTYDB_NO_FLAGS,NULL); } @@ -567,7 +567,7 @@ void clusterReset(int hard) { /* Forget all the nodes, but myself. */ di = dictGetSafeIterator(server.cluster->nodes); while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); if (node == myself) continue; clusterDelNode(node); @@ -604,7 +604,7 @@ void clusterReset(int hard) { * -------------------------------------------------------------------------- */ clusterLink *createClusterLink(clusterNode *node) { - clusterLink *link = zmalloc(sizeof(*link), MALLOC_LOCAL); + clusterLink *link = (clusterLink*)zmalloc(sizeof(*link), MALLOC_LOCAL); link->ctime = mstime(); link->sndbuf = sdsempty(); link->rcvbuf = sdsempty(); @@ -709,7 +709,7 @@ unsigned int keyHashSlot(char *key, int keylen) { * The node is created and returned to the user, but it is not automatically * added to the nodes hash table. */ clusterNode *createClusterNode(char *nodename, int flags) { - clusterNode *node = zmalloc(sizeof(*node), MALLOC_LOCAL); + clusterNode *node = (clusterNode*)zmalloc(sizeof(*node), MALLOC_LOCAL); if (nodename) memcpy(node->name, nodename, CLUSTER_NAMELEN); @@ -758,7 +758,7 @@ int clusterNodeAddFailureReport(clusterNode *failing, clusterNode *sender) { * the timestamp. */ listRewind(l,&li); while ((ln = listNext(&li)) != NULL) { - fr = ln->value; + fr = (clusterNodeFailReport*)ln->value; if (fr->node == sender) { fr->time = mstime(); return 0; @@ -766,7 +766,7 @@ int clusterNodeAddFailureReport(clusterNode *failing, clusterNode *sender) { } /* Otherwise create a new report. */ - fr = zmalloc(sizeof(*fr), MALLOC_LOCAL); + fr = (clusterNodeFailReport*)zmalloc(sizeof(*fr), MALLOC_LOCAL); fr->node = sender; fr->time = mstime(); listAddNodeTail(l,fr); @@ -789,7 +789,7 @@ void clusterNodeCleanupFailureReports(clusterNode *node) { listRewind(l,&li); while ((ln = listNext(&li)) != NULL) { - fr = ln->value; + fr = (clusterNodeFailReport*)ln->value; if (now - fr->time > maxtime) listDelNode(l,ln); } } @@ -814,7 +814,7 @@ int clusterNodeDelFailureReport(clusterNode *node, clusterNode *sender) { /* Search for a failure report from this sender. */ listRewind(l,&li); while ((ln = listNext(&li)) != NULL) { - fr = ln->value; + fr = (clusterNodeFailReport*)ln->value; if (fr->node == sender) break; } if (!ln) return 0; /* No failure report from this sender. */ @@ -858,7 +858,7 @@ int clusterNodeAddSlave(clusterNode *master, clusterNode *slave) { /* If it's already a slave, don't add it again. */ for (j = 0; j < master->numslaves; j++) if (master->slaves[j] == slave) return C_ERR; - master->slaves = zrealloc(master->slaves, + master->slaves = (clusterNode**)zrealloc(master->slaves, sizeof(clusterNode*)*(master->numslaves+1), MALLOC_LOCAL); master->slaves[master->numslaves] = slave; master->numslaves++; @@ -937,7 +937,7 @@ void clusterDelNode(clusterNode *delnode) { /* 2) Remove failure reports. */ di = dictGetSafeIterator(server.cluster->nodes); while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); if (node == delnode) continue; clusterNodeDelFailureReport(node,delnode); @@ -956,7 +956,7 @@ clusterNode *clusterLookupNode(const char *name) { de = dictFind(server.cluster->nodes,s); sdsfree(s); if (de == NULL) return NULL; - return dictGetVal(de); + return (clusterNode*)dictGetVal(de); } /* This is only used after the handshake. When we connect a given IP/PORT @@ -989,7 +989,7 @@ uint64_t clusterGetMaxEpoch(void) { di = dictGetSafeIterator(server.cluster->nodes); while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); if (node->configEpoch > max) max = node->configEpoch; } dictReleaseIterator(di); @@ -1277,7 +1277,7 @@ int clusterHandshakeInProgress(char *ip, int port, int cport) { di = dictGetSafeIterator(server.cluster->nodes); while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); if (!nodeInHandshake(node)) continue; if (!strcasecmp(node->ip,ip) && @@ -2253,12 +2253,12 @@ void clusterBroadcastMessage(void *buf, size_t len) { di = dictGetSafeIterator(server.cluster->nodes); while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); if (!node->link) continue; if (node->flags & (CLUSTER_NODE_MYSELF|CLUSTER_NODE_HANDSHAKE)) continue; - clusterSendMessage(node->link,buf,len); + clusterSendMessage(node->link,(unsigned char*)buf,len); } dictReleaseIterator(di); } @@ -2422,7 +2422,7 @@ void clusterSendPing(clusterLink *link, int type) { /* Note: clusterBuildMessageHdr() expects the buffer to be always at least * sizeof(clusterMsg) or more. */ if (totlen < (int)sizeof(clusterMsg)) totlen = sizeof(clusterMsg); - buf = zcalloc(totlen, MALLOC_LOCAL); + buf = (unsigned char*)zcalloc(totlen, MALLOC_LOCAL); hdr = (clusterMsg*) buf; /* Populate the header. */ @@ -2434,32 +2434,32 @@ void clusterSendPing(clusterLink *link, int type) { int maxiterations = wanted*3; while(freshnodes > 0 && gossipcount < wanted && maxiterations--) { dictEntry *de = dictGetRandomKey(server.cluster->nodes); - clusterNode *this = dictGetVal(de); + clusterNode *thisNode = (clusterNode*)dictGetVal(de); /* Don't include this node: the whole packet header is about us * already, so we just gossip about other nodes. */ - if (this == myself) continue; + if (thisNode == myself) continue; /* PFAIL nodes will be added later. */ - if (this->flags & CLUSTER_NODE_PFAIL) continue; + if (thisNode->flags & CLUSTER_NODE_PFAIL) continue; /* In the gossip section don't include: * 1) Nodes in HANDSHAKE state. * 3) Nodes with the NOADDR flag set. * 4) Disconnected nodes if they don't have configured slots. */ - if (this->flags & (CLUSTER_NODE_HANDSHAKE|CLUSTER_NODE_NOADDR) || - (this->link == NULL && this->numslots == 0)) + if (thisNode->flags & (CLUSTER_NODE_HANDSHAKE|CLUSTER_NODE_NOADDR) || + (thisNode->link == NULL && thisNode->numslots == 0)) { freshnodes--; /* Tecnically not correct, but saves CPU. */ continue; } /* Do not add a node we already have. */ - if (clusterNodeIsInGossipSection(hdr,gossipcount,this)) continue; + if (clusterNodeIsInGossipSection(hdr,gossipcount,thisNode)) continue; /* Add it */ - clusterSetGossipEntry(hdr,gossipcount,this); + clusterSetGossipEntry(hdr,gossipcount,thisNode); freshnodes--; gossipcount++; } @@ -2471,7 +2471,7 @@ void clusterSendPing(clusterLink *link, int type) { di = dictGetSafeIterator(server.cluster->nodes); while((de = dictNext(di)) != NULL && pfail_wanted > 0) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); if (node->flags & CLUSTER_NODE_HANDSHAKE) continue; if (node->flags & CLUSTER_NODE_NOADDR) continue; if (!(node->flags & CLUSTER_NODE_PFAIL)) continue; @@ -2518,7 +2518,7 @@ void clusterBroadcastPong(int target) { di = dictGetSafeIterator(server.cluster->nodes); while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); if (!node->link) continue; if (node == myself || nodeInHandshake(node)) continue; @@ -2544,8 +2544,8 @@ void clusterSendPublish(clusterLink *link, robj *channel, robj *message) { channel = getDecodedObject(channel); message = getDecodedObject(message); - channel_len = sdslen(ptrFromObj(channel)); - message_len = sdslen(ptrFromObj(message)); + channel_len = sdslen(szFromObj(channel)); + message_len = sdslen(szFromObj(message)); clusterBuildMessageHdr(hdr,CLUSTERMSG_TYPE_PUBLISH); totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData); @@ -2559,13 +2559,13 @@ void clusterSendPublish(clusterLink *link, robj *channel, robj *message) { if (totlen < sizeof(buf)) { payload = buf; } else { - payload = zmalloc(totlen, MALLOC_LOCAL); + payload = (unsigned char*)zmalloc(totlen, MALLOC_LOCAL); memcpy(payload,hdr,sizeof(*hdr)); hdr = (clusterMsg*) payload; } - memcpy(hdr->data.publish.msg.bulk_data,ptrFromObj(channel),sdslen(ptrFromObj(channel))); - memcpy(hdr->data.publish.msg.bulk_data+sdslen(ptrFromObj(channel)), - ptrFromObj(message),sdslen(ptrFromObj(message))); + memcpy(hdr->data.publish.msg.bulk_data,ptrFromObj(channel),sdslen(szFromObj(channel))); + memcpy(hdr->data.publish.msg.bulk_data+sdslen(szFromObj(channel)), + ptrFromObj(message),sdslen(szFromObj(message))); if (link) clusterSendMessage(link,payload,totlen); @@ -2628,7 +2628,7 @@ void clusterSendModule(clusterLink *link, uint64_t module_id, uint8_t type, if (totlen < sizeof(buf)) { heapbuf = buf; } else { - heapbuf = zmalloc(totlen, MALLOC_LOCAL); + heapbuf = (unsigned char*)zmalloc(totlen, MALLOC_LOCAL); memcpy(heapbuf,hdr,sizeof(*hdr)); hdr = (clusterMsg*) heapbuf; } @@ -2879,7 +2879,7 @@ int clusterGetSlaveRank(void) { * * The function is guaranteed to be called only if 'myself' is a slave. */ void clusterLogCantFailover(int reason) { - char *msg; + const char *msg; static time_t lastlog_time = 0; mstime_t nolog_fail_time = server.cluster_node_timeout + 5000; @@ -3192,7 +3192,7 @@ void clusterHandleSlaveMigration(int max_slaves) { candidate = myself; di = dictGetSafeIterator(server.cluster->nodes); while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); int okslaves = 0, is_orphaned = 1; /* We want to migrate only if this master is working, orphaned, and @@ -3386,7 +3386,7 @@ void clusterCron(void) { di = dictGetSafeIterator(server.cluster->nodes); server.cluster->stats_pfail_nodes = 0; while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); /* Not interested in reconnecting the link with myself or nodes * for which we have no address. */ @@ -3463,15 +3463,15 @@ void clusterCron(void) { * pong_received time. */ for (j = 0; j < 5; j++) { de = dictGetRandomKey(server.cluster->nodes); - clusterNode *this = dictGetVal(de); + clusterNode *thisNode = (clusterNode*)dictGetVal(de); /* Don't ping nodes disconnected or with a ping currently active. */ - if (this->link == NULL || this->ping_sent != 0) continue; - if (this->flags & (CLUSTER_NODE_MYSELF|CLUSTER_NODE_HANDSHAKE)) + if (thisNode->link == NULL || thisNode->ping_sent != 0) continue; + if (thisNode->flags & (CLUSTER_NODE_MYSELF|CLUSTER_NODE_HANDSHAKE)) continue; - if (min_pong_node == NULL || min_pong > this->pong_received) { - min_pong_node = this; - min_pong = this->pong_received; + if (min_pong_node == NULL || min_pong > thisNode->pong_received) { + min_pong_node = thisNode; + min_pong = thisNode->pong_received; } } if (min_pong_node) { @@ -3491,7 +3491,7 @@ void clusterCron(void) { this_slaves = 0; di = dictGetSafeIterator(server.cluster->nodes); while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); now = mstime(); /* Use an updated time at every iteration. */ mstime_t delay; @@ -3672,7 +3672,7 @@ int clusterMastersHaveSlaves(void) { dictEntry *de; int slaves = 0; while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); if (nodeIsSlave(node)) continue; slaves += node->numslaves; @@ -3824,7 +3824,7 @@ void clusterUpdateState(void) { server.cluster->size = 0; di = dictGetSafeIterator(server.cluster->nodes); while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); if (nodeIsMaster(node) && node->numslots) { server.cluster->size++; @@ -3974,7 +3974,7 @@ void clusterSetMaster(clusterNode *n) { struct redisNodeFlags { uint16_t flag; - char *name; + const char *name; }; static struct redisNodeFlags redisNodeFlagsTable[] = { @@ -4091,7 +4091,7 @@ sds clusterGenNodesDescription(int filter) { di = dictGetSafeIterator(server.cluster->nodes); while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); if (node->flags & filter) continue; ni = clusterGenNodeDescription(node); @@ -4153,7 +4153,7 @@ void clusterReplyMultiBulkSlots(client *c) { dictEntry *de; dictIterator *di = dictGetSafeIterator(server.cluster->nodes); while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); int j = 0, start = -1; /* Skip slaves (that are iterated when producing the output of their @@ -4215,7 +4215,7 @@ void clusterCommand(client *c) { return; } - if (c->argc == 2 && !strcasecmp(ptrFromObj(c->argv[1]),"help")) { + if (c->argc == 2 && !strcasecmp(szFromObj(c->argv[1]),"help")) { const char *help[] = { "ADDSLOTS [slot ...] -- Assign slots to current node.", "BUMPEPOCH -- Advance the cluster config epoch.", @@ -4242,7 +4242,7 @@ void clusterCommand(client *c) { NULL }; addReplyHelp(c, help); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"meet") && (c->argc == 4 || c->argc == 5)) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"meet") && (c->argc == 4 || c->argc == 5)) { /* CLUSTER MEET [cport] */ long long port, cport; @@ -4262,7 +4262,7 @@ NULL cport = port + CLUSTER_PORT_INCR; } - if (clusterStartHandshake(ptrFromObj(c->argv[2]),port,cport) == 0 && + if (clusterStartHandshake(szFromObj(c->argv[2]),port,cport) == 0 && errno == EINVAL) { addReplyErrorFormat(c,"Invalid node address specified: %s:%s", @@ -4270,7 +4270,7 @@ NULL } else { addReply(c,shared.ok); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"nodes") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"nodes") && c->argc == 2) { /* CLUSTER NODES */ robj *o; sds ci = clusterGenNodesDescription(0); @@ -4278,13 +4278,13 @@ NULL o = createObject(OBJ_STRING,ci); addReplyBulk(c,o); decrRefCount(o); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"myid") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"myid") && c->argc == 2) { /* CLUSTER MYID */ addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"slots") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterReplyMultiBulkSlots(c); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"flushslots") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"flushslots") && c->argc == 2) { /* CLUSTER FLUSHSLOTS */ if (dictSize(server.db[0].pdict) != 0) { addReplyError(c,"DB must be empty to perform CLUSTER FLUSHSLOTS."); @@ -4293,14 +4293,14 @@ NULL clusterDelNodeSlots(myself); clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); addReply(c,shared.ok); - } else if ((!strcasecmp(ptrFromObj(c->argv[1]),"addslots") || - !strcasecmp(ptrFromObj(c->argv[1]),"delslots")) && c->argc >= 3) + } else if ((!strcasecmp(szFromObj(c->argv[1]),"addslots") || + !strcasecmp(szFromObj(c->argv[1]),"delslots")) && c->argc >= 3) { /* CLUSTER ADDSLOTS [slot] ... */ /* CLUSTER DELSLOTS [slot] ... */ int j, slot; - unsigned char *slots = zmalloc(CLUSTER_SLOTS, MALLOC_LOCAL); - int del = !strcasecmp(ptrFromObj(c->argv[1]),"delslots"); + unsigned char *slots = (unsigned char*)zmalloc(CLUSTER_SLOTS, MALLOC_LOCAL); + int del = !strcasecmp(szFromObj(c->argv[1]),"delslots"); memset(slots,0,CLUSTER_SLOTS); /* Check that all the arguments are parseable and that all the @@ -4343,7 +4343,7 @@ NULL zfree(slots); clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"setslot") && c->argc >= 4) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"setslot") && c->argc >= 4) { /* SETSLOT 10 MIGRATING */ /* SETSLOT 10 IMPORTING */ /* SETSLOT 10 STABLE */ @@ -4358,36 +4358,36 @@ NULL if ((slot = getSlotOrReply(c,c->argv[2])) == -1) return; - if (!strcasecmp(ptrFromObj(c->argv[3]),"migrating") && c->argc == 5) { + if (!strcasecmp(szFromObj(c->argv[3]),"migrating") && c->argc == 5) { if (server.cluster->slots[slot] != myself) { addReplyErrorFormat(c,"I'm not the owner of hash slot %u",slot); return; } - if ((n = clusterLookupNode(ptrFromObj(c->argv[4]))) == NULL) { + if ((n = clusterLookupNode(szFromObj(c->argv[4]))) == NULL) { addReplyErrorFormat(c,"I don't know about node %s", (char*)ptrFromObj(c->argv[4])); return; } server.cluster->migrating_slots_to[slot] = n; - } else if (!strcasecmp(ptrFromObj(c->argv[3]),"importing") && c->argc == 5) { + } else if (!strcasecmp(szFromObj(c->argv[3]),"importing") && c->argc == 5) { if (server.cluster->slots[slot] == myself) { addReplyErrorFormat(c, "I'm already the owner of hash slot %u",slot); return; } - if ((n = clusterLookupNode(ptrFromObj(c->argv[4]))) == NULL) { + if ((n = clusterLookupNode(szFromObj(c->argv[4]))) == NULL) { addReplyErrorFormat(c,"I don't know about node %s", (char*)ptrFromObj(c->argv[4])); return; } server.cluster->importing_slots_from[slot] = n; - } else if (!strcasecmp(ptrFromObj(c->argv[3]),"stable") && c->argc == 4) { + } else if (!strcasecmp(szFromObj(c->argv[3]),"stable") && c->argc == 4) { /* CLUSTER SETSLOT STABLE */ server.cluster->importing_slots_from[slot] = NULL; server.cluster->migrating_slots_to[slot] = NULL; - } else if (!strcasecmp(ptrFromObj(c->argv[3]),"node") && c->argc == 5) { + } else if (!strcasecmp(szFromObj(c->argv[3]),"node") && c->argc == 5) { /* CLUSTER SETSLOT NODE */ - clusterNode *n = clusterLookupNode(ptrFromObj(c->argv[4])); + clusterNode *n = clusterLookupNode(szFromObj(c->argv[4])); if (!n) { addReplyErrorFormat(c,"Unknown node %s", @@ -4440,16 +4440,16 @@ NULL } clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_UPDATE_STATE); addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"bumpepoch") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"bumpepoch") && c->argc == 2) { /* CLUSTER BUMPEPOCH */ int retval = clusterBumpConfigEpochWithoutConsensus(); sds reply = sdscatprintf(sdsempty(),"+%s %llu\r\n", (retval == C_OK) ? "BUMPED" : "STILL", (unsigned long long) myself->configEpoch); addReplySds(c,reply); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"info") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"info") && c->argc == 2) { /* CLUSTER INFO */ - char *statestr[] = {"ok","fail","needhelp"}; + const char *statestr[] = {"ok","fail","needhelp"}; int slots_assigned = 0, slots_ok = 0, slots_pfail = 0, slots_fail = 0; uint64_t myepoch; int j; @@ -4523,7 +4523,7 @@ NULL (unsigned long)sdslen(info))); addReplySds(c,info); addReply(c,shared.crlf); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"saveconfig") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"saveconfig") && c->argc == 2) { int retval = clusterSaveConfig(1); if (retval == 0) @@ -4531,12 +4531,12 @@ NULL else addReplyErrorFormat(c,"error saving the cluster node config: %s", strerror(errno)); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"keyslot") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"keyslot") && c->argc == 3) { /* CLUSTER KEYSLOT */ - sds key = ptrFromObj(c->argv[2]); + sds key = szFromObj(c->argv[2]); addReplyLongLong(c,keyHashSlot(key,sdslen(key))); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"countkeysinslot") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"countkeysinslot") && c->argc == 3) { /* CLUSTER COUNTKEYSINSLOT */ long long slot; @@ -4547,7 +4547,7 @@ NULL return; } addReplyLongLong(c,countKeysInSlot(slot)); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"getkeysinslot") && c->argc == 4) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"getkeysinslot") && c->argc == 4) { /* CLUSTER GETKEYSINSLOT */ long long maxkeys, slot; unsigned int numkeys, j; @@ -4568,7 +4568,7 @@ NULL unsigned int keys_in_slot = countKeysInSlot(slot); if (maxkeys > keys_in_slot) maxkeys = keys_in_slot; - keys = zmalloc(sizeof(robj*)*maxkeys, MALLOC_LOCAL); + keys = (robj**)zmalloc(sizeof(robj*)*maxkeys, MALLOC_LOCAL); numkeys = getKeysInSlot(slot, keys, maxkeys); addReplyArrayLen(c,numkeys); for (j = 0; j < numkeys; j++) { @@ -4576,9 +4576,9 @@ NULL decrRefCount(keys[j]); } zfree(keys); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"forget") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"forget") && c->argc == 3) { /* CLUSTER FORGET */ - clusterNode *n = clusterLookupNode(ptrFromObj(c->argv[2])); + clusterNode *n = clusterLookupNode(szFromObj(c->argv[2])); if (!n) { addReplyErrorFormat(c,"Unknown node %s", (char*)ptrFromObj(c->argv[2])); @@ -4595,9 +4595,9 @@ NULL clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE| CLUSTER_TODO_SAVE_CONFIG); addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"replicate") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"replicate") && c->argc == 3) { /* CLUSTER REPLICATE */ - clusterNode *n = clusterLookupNode(ptrFromObj(c->argv[2])); + clusterNode *n = clusterLookupNode(szFromObj(c->argv[2])); /* Lookup the specified node in our table. */ if (!n) { @@ -4632,10 +4632,10 @@ NULL clusterSetMaster(n); clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); addReply(c,shared.ok); - } else if ((!strcasecmp(ptrFromObj(c->argv[1]),"slaves") || - !strcasecmp(ptrFromObj(c->argv[1]),"replicas")) && c->argc == 3) { + } else if ((!strcasecmp(szFromObj(c->argv[1]),"slaves") || + !strcasecmp(szFromObj(c->argv[1]),"replicas")) && c->argc == 3) { /* CLUSTER SLAVES */ - clusterNode *n = clusterLookupNode(ptrFromObj(c->argv[2])); + clusterNode *n = clusterLookupNode(szFromObj(c->argv[2])); int j; /* Lookup the specified node in our table. */ @@ -4655,11 +4655,11 @@ NULL addReplyBulkCString(c,ni); sdsfree(ni); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"count-failure-reports") && + } else if (!strcasecmp(szFromObj(c->argv[1]),"count-failure-reports") && c->argc == 3) { /* CLUSTER COUNT-FAILURE-REPORTS */ - clusterNode *n = clusterLookupNode(ptrFromObj(c->argv[2])); + clusterNode *n = clusterLookupNode(szFromObj(c->argv[2])); if (!n) { addReplyErrorFormat(c,"Unknown node %s", (char*)ptrFromObj(c->argv[2])); @@ -4667,16 +4667,16 @@ NULL } else { addReplyLongLong(c,clusterNodeFailureReportsCount(n)); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"failover") && + } else if (!strcasecmp(szFromObj(c->argv[1]),"failover") && (c->argc == 2 || c->argc == 3)) { /* CLUSTER FAILOVER [FORCE|TAKEOVER] */ int force = 0, takeover = 0; if (c->argc == 3) { - if (!strcasecmp(ptrFromObj(c->argv[2]),"force")) { + if (!strcasecmp(szFromObj(c->argv[2]),"force")) { force = 1; - } else if (!strcasecmp(ptrFromObj(c->argv[2]),"takeover")) { + } else if (!strcasecmp(szFromObj(c->argv[2]),"takeover")) { takeover = 1; force = 1; /* Takeover also implies force. */ } else { @@ -4722,7 +4722,7 @@ NULL clusterSendMFStart(myself->slaveof); } addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"set-config-epoch") && c->argc == 3) + } else if (!strcasecmp(szFromObj(c->argv[1]),"set-config-epoch") && c->argc == 3) { /* CLUSTER SET-CONFIG-EPOCH * @@ -4758,7 +4758,7 @@ NULL CLUSTER_TODO_SAVE_CONFIG); addReply(c,shared.ok); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"reset") && + } else if (!strcasecmp(szFromObj(c->argv[1]),"reset") && (c->argc == 2 || c->argc == 3)) { /* CLUSTER RESET [SOFT|HARD] */ @@ -4766,9 +4766,9 @@ NULL /* Parse soft/hard argument. Default is soft. */ if (c->argc == 3) { - if (!strcasecmp(ptrFromObj(c->argv[2]),"hard")) { + if (!strcasecmp(szFromObj(c->argv[2]),"hard")) { hard = 1; - } else if (!strcasecmp(ptrFromObj(c->argv[2]),"soft")) { + } else if (!strcasecmp(szFromObj(c->argv[2]),"soft")) { hard = 0; } else { addReply(c,shared.syntaxerr); @@ -4882,11 +4882,11 @@ void restoreCommand(client *c) { /* Parse additional options */ for (j = 4; j < c->argc; j++) { int additional = c->argc-j-1; - if (!strcasecmp(ptrFromObj(c->argv[j]),"replace")) { + if (!strcasecmp(szFromObj(c->argv[j]),"replace")) { replace = 1; - } else if (!strcasecmp(ptrFromObj(c->argv[j]),"absttl")) { + } else if (!strcasecmp(szFromObj(c->argv[j]),"absttl")) { absttl = 1; - } else if (!strcasecmp(ptrFromObj(c->argv[j]),"idletime") && additional >= 1 && + } else if (!strcasecmp(szFromObj(c->argv[j]),"idletime") && additional >= 1 && lfu_freq == -1) { if (getLongLongFromObjectOrReply(c,c->argv[j+1],&lru_idle,NULL) @@ -4897,7 +4897,7 @@ void restoreCommand(client *c) { } lru_clock = LRU_CLOCK(); j++; /* Consume additional arg. */ - } else if (!strcasecmp(ptrFromObj(c->argv[j]),"freq") && additional >= 1 && + } else if (!strcasecmp(szFromObj(c->argv[j]),"freq") && additional >= 1 && lru_idle == -1) { if (getLongLongFromObjectOrReply(c,c->argv[j+1],&lfu_freq,NULL) @@ -4928,13 +4928,13 @@ void restoreCommand(client *c) { } /* Verify RDB version and data checksum. */ - if (verifyDumpPayload(ptrFromObj(c->argv[3]),sdslen(ptrFromObj(c->argv[3]))) == C_ERR) + if (verifyDumpPayload((unsigned char*)ptrFromObj(c->argv[3]),sdslen(szFromObj(c->argv[3]))) == C_ERR) { addReplyError(c,"DUMP payload version or checksum are wrong"); return; } - rioInitWithBuffer(&payload,ptrFromObj(c->argv[3])); + rioInitWithBuffer(&payload,szFromObj(c->argv[3])); if (((type = rdbLoadObjectType(&payload)) == -1) || ((obj = rdbLoadObject(type,&payload,c->argv[1])) == NULL)) { @@ -4989,10 +4989,10 @@ migrateCachedSocket* migrateGetSocket(client *c, robj *host, robj *port, long ti migrateCachedSocket *cs; /* Check if we have an already cached socket for this ip:port pair. */ - name = sdscatlen(name,ptrFromObj(host),sdslen(ptrFromObj(host))); + name = sdscatlen(name,ptrFromObj(host),sdslen(szFromObj(host))); name = sdscatlen(name,":",1); - name = sdscatlen(name,ptrFromObj(port),sdslen(ptrFromObj(port))); - cs = dictFetchValue(server.migrate_cached_sockets,name); + name = sdscatlen(name,ptrFromObj(port),sdslen(szFromObj(port))); + cs = (migrateCachedSocket*)dictFetchValue(server.migrate_cached_sockets,name); if (cs) { sdsfree(name); cs->last_use_time = server.unixtime; @@ -5003,15 +5003,15 @@ migrateCachedSocket* migrateGetSocket(client *c, robj *host, robj *port, long ti if (dictSize(server.migrate_cached_sockets) == MIGRATE_SOCKET_CACHE_ITEMS) { /* Too many items, drop one at random. */ dictEntry *de = dictGetRandomKey(server.migrate_cached_sockets); - cs = dictGetVal(de); + cs = (migrateCachedSocket*)dictGetVal(de); close(cs->fd); zfree(cs); dictDelete(server.migrate_cached_sockets,dictGetKey(de)); } /* Create the socket */ - fd = anetTcpNonBlockConnect(server.neterr,ptrFromObj(c->argv[1]), - atoi(ptrFromObj(c->argv[2]))); + fd = anetTcpNonBlockConnect(server.neterr,szFromObj(c->argv[1]), + atoi(szFromObj(c->argv[2]))); if (fd == -1) { sdsfree(name); addReplyErrorFormat(c,"Can't connect to target node: %s", @@ -5030,7 +5030,7 @@ migrateCachedSocket* migrateGetSocket(client *c, robj *host, robj *port, long ti } /* Add to the cache and return it to the caller. */ - cs = zmalloc(sizeof(*cs), MALLOC_LOCAL); + cs = (migrateCachedSocket*)zmalloc(sizeof(*cs), MALLOC_LOCAL); cs->fd = fd; cs->last_dbid = -1; cs->last_use_time = server.unixtime; @@ -5043,10 +5043,10 @@ void migrateCloseSocket(robj *host, robj *port) { sds name = sdsempty(); migrateCachedSocket *cs; - name = sdscatlen(name,ptrFromObj(host),sdslen(ptrFromObj(host))); + name = sdscatlen(name,ptrFromObj(host),sdslen(szFromObj(host))); name = sdscatlen(name,":",1); - name = sdscatlen(name,ptrFromObj(port),sdslen(ptrFromObj(port))); - cs = dictFetchValue(server.migrate_cached_sockets,name); + name = sdscatlen(name,ptrFromObj(port),sdslen(szFromObj(port))); + cs = (migrateCachedSocket*)dictFetchValue(server.migrate_cached_sockets,name); if (!cs) { sdsfree(name); return; @@ -5063,7 +5063,7 @@ void migrateCloseTimedoutSockets(void) { dictEntry *de; while((de = dictNext(di)) != NULL) { - migrateCachedSocket *cs = dictGetVal(de); + migrateCachedSocket *cs = (migrateCachedSocket*)dictGetVal(de); if ((server.unixtime - cs->last_use_time) > MIGRATE_SOCKET_CACHE_TTL) { close(cs->fd); @@ -5101,19 +5101,19 @@ void migrateCommand(client *c) { /* Parse additional options */ for (j = 6; j < c->argc; j++) { int moreargs = j < c->argc-1; - if (!strcasecmp(ptrFromObj(c->argv[j]),"copy")) { + if (!strcasecmp(szFromObj(c->argv[j]),"copy")) { copy = 1; - } else if (!strcasecmp(ptrFromObj(c->argv[j]),"replace")) { + } else if (!strcasecmp(szFromObj(c->argv[j]),"replace")) { replace = 1; - } else if (!strcasecmp(ptrFromObj(c->argv[j]),"auth")) { + } else if (!strcasecmp(szFromObj(c->argv[j]),"auth")) { if (!moreargs) { addReply(c,shared.syntaxerr); return; } j++; - password = ptrFromObj(c->argv[j]); - } else if (!strcasecmp(ptrFromObj(c->argv[j]),"keys")) { - if (sdslen(ptrFromObj(c->argv[3])) != 0) { + password = szFromObj(c->argv[j]); + } else if (!strcasecmp(szFromObj(c->argv[j]),"keys")) { + if (sdslen(szFromObj(c->argv[3])) != 0) { addReplyError(c, "When using MIGRATE KEYS option, the key argument" " must be set to the empty string"); @@ -5141,8 +5141,8 @@ void migrateCommand(client *c) { * the caller there was nothing to migrate. We don't return an error in * this case, since often this is due to a normal condition like the key * expiring in the meantime. */ - ov = zrealloc(ov,sizeof(robj*)*num_keys, MALLOC_LOCAL); - kv = zrealloc(kv,sizeof(robj*)*num_keys, MALLOC_LOCAL); + ov = (robj**)zrealloc(ov,sizeof(robj*)*num_keys, MALLOC_LOCAL); + kv = (robj**)zrealloc(kv,sizeof(robj*)*num_keys, MALLOC_LOCAL); int oi = 0; for (j = 0; j < num_keys; j++) { @@ -5218,8 +5218,8 @@ try_again: else serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"RESTORE",7)); serverAssertWithInfo(c,NULL,sdsEncodedObject(kv[j])); - serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,ptrFromObj(kv[j]), - sdslen(ptrFromObj(kv[j])))); + serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,szFromObj(kv[j]), + sdslen(szFromObj(kv[j])))); serverAssertWithInfo(c,NULL,rioWriteBulkLongLong(&cmd,ttl)); /* Emit the payload argument, that is the serialized object using @@ -5239,6 +5239,13 @@ try_again: /* Fix the actual number of keys we are migrating. */ num_keys = non_expired; + char buf0[1024]; /* Auth reply. */ + char buf1[1024]; /* Select reply. */ + char buf2[1024]; /* Restore reply. */ + int error_from_target = 0; + int socket_error = 0; + int del_idx = 1; /* Index of the key argument for the replicated DEL op. */ + /* Transfer the query to the other node in 64K chunks. */ errno = 0; { @@ -5257,9 +5264,6 @@ try_again: } } - char buf0[1024]; /* Auth reply. */ - char buf1[1024]; /* Select reply. */ - char buf2[1024]; /* Restore reply. */ /* Read the AUTH reply if needed. */ if (password && syncReadLine(cs->fd, buf0, sizeof(buf0), timeout) <= 0) @@ -5269,17 +5273,13 @@ try_again: if (select && syncReadLine(cs->fd, buf1, sizeof(buf1), timeout) <= 0) goto socket_err; - /* Read the RESTORE replies. */ - int error_from_target = 0; - int socket_error = 0; - int del_idx = 1; /* Index of the key argument for the replicated DEL op. */ - /* Allocate the new argument vector that will replace the current command, * to propagate the MIGRATE as a DEL command (if no COPY option was given). * We allocate num_keys+1 because the additional argument is for "DEL" * command name itself. */ - if (!copy) newargv = zmalloc(sizeof(robj*)*(num_keys+1), MALLOC_LOCAL); + if (!copy) newargv = (robj**)zmalloc(sizeof(robj*)*(num_keys+1), MALLOC_LOCAL); + /* Read the RESTORE replies. */ for (j = 0; j < num_keys; j++) { if (syncReadLine(cs->fd, buf2, sizeof(buf2), timeout) <= 0) { socket_error = 1; @@ -5531,7 +5531,7 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in for (j = 0; j < numkeys; j++) { robj *thiskey = margv[keyindex[j]]; int thisslot = keyHashSlot((char*)ptrFromObj(thiskey), - sdslen(ptrFromObj(thiskey))); + sdslen(szFromObj(thiskey))); if (firstkey == NULL) { /* This is the first key we see. Check what is the slot @@ -5711,8 +5711,8 @@ int clusterRedirectBlockedClientIfNeeded(client *c) { /* All keys must belong to the same slot, so check first key only. */ di = dictGetIterator(c->bpop.keys); if ((de = dictNext(di)) != NULL) { - robj *key = dictGetKey(de); - int slot = keyHashSlot((char*)ptrFromObj(key), sdslen(ptrFromObj(key))); + robj *key = (robj*)dictGetKey(de); + int slot = keyHashSlot((char*)ptrFromObj(key), sdslen(szFromObj(key))); clusterNode *node = server.cluster->slots[slot]; /* We send an error and unblock the client if: diff --git a/src/config.c b/src/config.cpp similarity index 96% rename from src/config.c rename to src/config.cpp index 9852bbc6d..bcd4052aa 100644 --- a/src/config.c +++ b/src/config.cpp @@ -143,7 +143,7 @@ int yesnotoi(char *s) { } void appendServerSaveParams(time_t seconds, int changes) { - server.saveparams = zrealloc(server.saveparams,sizeof(struct saveparam)*(server.saveparamslen+1), MALLOC_LOCAL); + server.saveparams = (saveparam*)zrealloc(server.saveparams,sizeof(struct saveparam)*(server.saveparamslen+1), MALLOC_LOCAL); server.saveparams[server.saveparamslen].seconds = seconds; server.saveparams[server.saveparamslen].changes = changes; server.saveparamslen++; @@ -159,8 +159,8 @@ void queueLoadModule(sds path, sds *argv, int argc) { int i; struct moduleLoadQueueEntry *loadmod; - loadmod = zmalloc(sizeof(struct moduleLoadQueueEntry), MALLOC_LOCAL); - loadmod->argv = zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL); + loadmod = (moduleLoadQueueEntry*)zmalloc(sizeof(struct moduleLoadQueueEntry), MALLOC_LOCAL); + loadmod->argv = (robj**)zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL); loadmod->path = sdsnew(path); loadmod->argc = argc; for (i = 0; i < argc; i++) { @@ -170,7 +170,7 @@ void queueLoadModule(sds path, sds *argv, int argc) { } void loadServerConfigFromString(char *config) { - char *err = NULL; + const char *err = NULL; int linenum = 0, totlines, i; int slaveof_linenum = 0; sds *lines; @@ -216,10 +216,6 @@ void loadServerConfigFromString(char *config) { if ((server.protected_mode = yesnotoi(argv[1])) == -1) { err = "argument must be 'yes' or 'no'"; goto loaderr; } - } else if (!strcasecmp(argv[0],"gopher-enabled") && argc == 2) { - if ((server.gopher_enabled = yesnotoi(argv[1])) == -1) { - err = "argument must be 'yes' or 'no'"; goto loaderr; - } } else if (!strcasecmp(argv[0],"port") && argc == 2) { server.port = atoi(argv[1]); if (server.port < 0 || server.port > 65535) { @@ -729,11 +725,11 @@ void loadServerConfigFromString(char *config) { } else if (!strcasecmp(argv[0],"client-output-buffer-limit") && argc == 5) { - int class = getClientTypeByName(argv[1]); + int type = getClientTypeByName(argv[1]); unsigned long long hard, soft; int soft_seconds; - if (class == -1 || class == CLIENT_TYPE_MASTER) { + if (type == -1 || type == CLIENT_TYPE_MASTER) { err = "Unrecognized client limit class: the user specified " "an invalid one, or 'master' which has no buffer limits."; goto loaderr; @@ -745,9 +741,9 @@ void loadServerConfigFromString(char *config) { err = "Negative number of seconds in soft limit is invalid"; goto loaderr; } - server.client_obuf_limits[class].hard_limit_bytes = hard; - server.client_obuf_limits[class].soft_limit_bytes = soft; - server.client_obuf_limits[class].soft_limit_seconds = soft_seconds; + server.client_obuf_limits[type].hard_limit_bytes = hard; + server.client_obuf_limits[type].soft_limit_bytes = soft; + server.client_obuf_limits[type].soft_limit_seconds = soft_seconds; } else if (!strcasecmp(argv[0],"stop-writes-on-bgsave-error") && argc == 2) { if ((server.stop_writes_on_bgsave_err = yesnotoi(argv[1])) == -1) { @@ -806,7 +802,7 @@ void loadServerConfigFromString(char *config) { int argc_err; if (ACLAppendUserForLoading(argv,argc,&argc_err) == C_ERR) { char buf[1024]; - char *errmsg = ACLSetUserStringError(); + const char *errmsg = ACLSetUserStringError(); snprintf(buf,sizeof(buf),"Error in user declaration '%s': %s", argv[argc_err],errmsg); err = buf; @@ -928,36 +924,36 @@ void loadServerConfig(char *filename, char *options) { *----------------------------------------------------------------------------*/ #define config_set_bool_field(_name,_var) \ - } else if (!strcasecmp(ptrFromObj(c->argv[2]),_name)) { \ - int yn = yesnotoi(ptrFromObj(o)); \ + } else if (!strcasecmp(szFromObj(c->argv[2]),_name)) { \ + int yn = yesnotoi(szFromObj(o)); \ if (yn == -1) goto badfmt; \ _var = yn; #define config_set_numerical_field(_name,_var,min,max) \ - } else if (!strcasecmp(ptrFromObj(c->argv[2]),_name)) { \ + } else if (!strcasecmp(szFromObj(c->argv[2]),_name)) { \ if (getLongLongFromObject(o,&ll) == C_ERR) goto badfmt; \ if (min != LLONG_MIN && ll < min) goto badfmt; \ if (max != LLONG_MAX && ll > max) goto badfmt; \ _var = ll; #define config_set_memory_field(_name,_var) \ - } else if (!strcasecmp(ptrFromObj(c->argv[2]),_name)) { \ - ll = memtoll(ptrFromObj(o),&err); \ + } else if (!strcasecmp(szFromObj(c->argv[2]),_name)) { \ + ll = memtoll(szFromObj(o),&err); \ if (err || ll < 0) goto badfmt; \ _var = ll; #define config_set_enum_field(_name,_var,_enumvar) \ - } else if (!strcasecmp(ptrFromObj(c->argv[2]),_name)) { \ - int enumval = configEnumGetValue(_enumvar,ptrFromObj(o)); \ + } else if (!strcasecmp(szFromObj(c->argv[2]),_name)) { \ + int enumval = configEnumGetValue(_enumvar,szFromObj(o)); \ if (enumval == INT_MIN) goto badfmt; \ _var = enumval; #define config_set_special_field(_name) \ - } else if (!strcasecmp(ptrFromObj(c->argv[2]),_name)) { + } else if (!strcasecmp(szFromObj(c->argv[2]),_name)) { #define config_set_special_field_with_alias(_name1,_name2) \ - } else if (!strcasecmp(ptrFromObj(c->argv[2]),_name1) || \ - !strcasecmp(ptrFromObj(c->argv[2]),_name2)) { + } else if (!strcasecmp(szFromObj(c->argv[2]),_name1) || \ + !strcasecmp(szFromObj(c->argv[2]),_name2)) { #define config_set_else } else @@ -973,14 +969,14 @@ void configSetCommand(client *c) { /* Special fields that can't be handled with general macros. */ config_set_special_field("dbfilename") { - if (!pathIsBaseName(ptrFromObj(o))) { + if (!pathIsBaseName(szFromObj(o))) { addReplyError(c, "dbfilename can't be a path, just a filename"); return; } zfree(server.rdb_filename); - server.rdb_filename = zstrdup(ptrFromObj(o)); + server.rdb_filename = zstrdup(szFromObj(o)); } config_set_special_field("requirepass") { - if (sdslen(ptrFromObj(o)) > CONFIG_AUTHPASS_MAX_LEN) goto badfmt; + if (sdslen(szFromObj(o)) > CONFIG_AUTHPASS_MAX_LEN) goto badfmt; /* The old "requirepass" directive just translates to setting * a password to the default user. */ ACLSetUser(DefaultUser,"resetpass",-1); @@ -989,13 +985,13 @@ void configSetCommand(client *c) { sdsfree(aclop); } config_set_special_field("masteruser") { zfree(server.default_masteruser); - server.default_masteruser = ((char*)ptrFromObj(o))[0] ? zstrdup(ptrFromObj(o)) : NULL; + server.default_masteruser = ((char*)ptrFromObj(o))[0] ? zstrdup(szFromObj(o)) : NULL; } config_set_special_field("masterauth") { zfree(server.default_masterauth); - server.default_masterauth = ((char*)ptrFromObj(o))[0] ? zstrdup(ptrFromObj(o)) : NULL; + server.default_masterauth = ((char*)ptrFromObj(o))[0] ? zstrdup(szFromObj(o)) : NULL; } config_set_special_field("cluster-announce-ip") { zfree(server.cluster_announce_ip); - server.cluster_announce_ip = ((char*)ptrFromObj(o))[0] ? zstrdup(ptrFromObj(o)) : NULL; + server.cluster_announce_ip = ((char*)ptrFromObj(o))[0] ? zstrdup(szFromObj(o)) : NULL; } config_set_special_field("maxclients") { int orig_value = server.maxclients; @@ -1027,7 +1023,7 @@ void configSetCommand(client *c) { } } } config_set_special_field("appendonly") { - int enable = yesnotoi(ptrFromObj(o)); + int enable = yesnotoi(szFromObj(o)); if (enable == -1) goto badfmt; if (enable == 0 && server.aof_state != AOF_OFF) { @@ -1041,7 +1037,7 @@ void configSetCommand(client *c) { } } config_set_special_field("save") { int vlen, j; - sds *v = sdssplitlen(ptrFromObj(o),sdslen(ptrFromObj(o))," ",1,&vlen); + sds *v = sdssplitlen(szFromObj(o),sdslen(szFromObj(o))," ",1,&vlen); /* Perform sanity check before setting the new config: * - Even number of args @@ -1080,7 +1076,7 @@ void configSetCommand(client *c) { } } config_set_special_field("client-output-buffer-limit") { int vlen, j; - sds *v = sdssplitlen(ptrFromObj(o),sdslen(ptrFromObj(o))," ",1,&vlen); + sds *v = sdssplitlen(szFromObj(o),sdslen(szFromObj(o))," ",1,&vlen); /* We need a multiple of 4: */ if (vlen % 4) { @@ -1095,8 +1091,8 @@ void configSetCommand(client *c) { long val; if ((j % 4) == 0) { - int class = getClientTypeByName(v[j]); - if (class == -1 || class == CLIENT_TYPE_MASTER) { + int type = getClientTypeByName(v[j]); + if (type == -1 || type == CLIENT_TYPE_MASTER) { sdsfreesplitres(v,vlen); goto badfmt; } @@ -1110,22 +1106,21 @@ void configSetCommand(client *c) { } /* Finally set the new config */ for (j = 0; j < vlen; j += 4) { - int class; unsigned long long hard, soft; int soft_seconds; - class = getClientTypeByName(v[j]); + int type = getClientTypeByName(v[j]); hard = memtoll(v[j+1],NULL); soft = memtoll(v[j+2],NULL); soft_seconds = strtoll(v[j+3],NULL,10); - server.client_obuf_limits[class].hard_limit_bytes = hard; - server.client_obuf_limits[class].soft_limit_bytes = soft; - server.client_obuf_limits[class].soft_limit_seconds = soft_seconds; + server.client_obuf_limits[type].hard_limit_bytes = hard; + server.client_obuf_limits[type].soft_limit_bytes = soft; + server.client_obuf_limits[type].soft_limit_seconds = soft_seconds; } sdsfreesplitres(v,vlen); } config_set_special_field("notify-keyspace-events") { - int flags = keyspaceEventsStringToFlags(ptrFromObj(o)); + int flags = keyspaceEventsStringToFlags(szFromObj(o)); if (flags == -1) goto badfmt; server.notify_keyspace_events = flags; @@ -1133,7 +1128,7 @@ void configSetCommand(client *c) { "replica-announce-ip") { zfree(server.slave_announce_ip); - server.slave_announce_ip = ((char*)ptrFromObj(o))[0] ? zstrdup(ptrFromObj(o)) : NULL; + server.slave_announce_ip = ((char*)ptrFromObj(o))[0] ? zstrdup(szFromObj(o)) : NULL; /* Boolean fields. * config_set_bool_field(name,var). */ @@ -1186,8 +1181,6 @@ void configSetCommand(client *c) { #endif } config_set_bool_field( "protected-mode",server.protected_mode) { - } config_set_bool_field( - "gopher-enabled",server.gopher_enabled) { } config_set_bool_field( "stop-writes-on-bgsave-error",server.stop_writes_on_bgsave_err) { } config_set_bool_field( @@ -1402,7 +1395,7 @@ badfmt: /* Bad format errors */ void configGetCommand(client *c) { robj *o = c->argv[2]; void *replylen = addReplyDeferredLen(c); - char *pattern = ptrFromObj(o); + char *pattern = szFromObj(o); char buf[128]; int matches = 0; serverAssertWithInfo(c,o,sdsEncodedObject(o)); @@ -1521,7 +1514,6 @@ void configGetCommand(client *c) { config_get_bool_field("activerehashing", server.activerehashing); config_get_bool_field("activedefrag", server.active_defrag_enabled); config_get_bool_field("protected-mode", server.protected_mode); - config_get_bool_field("gopher-enabled", server.gopher_enabled); config_get_bool_field("repl-disable-tcp-nodelay", server.repl_disable_tcp_nodelay); config_get_bool_field("repl-diskless-sync", @@ -1620,7 +1612,7 @@ void configGetCommand(client *c) { if (stringmatch(pattern,"slaveof",1) || stringmatch(pattern,"replicaof",1)) { - char *optname = stringmatch(pattern,"slaveof",1) ? + const char *optname = stringmatch(pattern,"slaveof",1) ? "slaveof" : "replicaof"; char buf[256]; addReplyBulkCString(c,optname); @@ -1722,13 +1714,13 @@ struct rewriteConfigState { /* Append the new line to the current configuration state. */ void rewriteConfigAppendLine(struct rewriteConfigState *state, sds line) { - state->lines = zrealloc(state->lines, sizeof(char*) * (state->numlines+1), MALLOC_LOCAL); + state->lines = (sds*)zrealloc(state->lines, sizeof(char*) * (state->numlines+1), MALLOC_LOCAL); state->lines[state->numlines++] = line; } /* Populate the option -> list of line numbers map. */ void rewriteConfigAddLineNumberToOption(struct rewriteConfigState *state, sds option, int linenum) { - list *l = dictFetchValue(state->option_to_line,option); + list *l = (list*)dictFetchValue(state->option_to_line,option); if (l == NULL) { l = listCreate(); @@ -1754,7 +1746,7 @@ void rewriteConfigMarkAsProcessed(struct rewriteConfigState *state, const char * * If the old file does not exist at all, an empty state is returned. */ struct rewriteConfigState *rewriteConfigReadOldFile(char *path) { FILE *fp = fopen(path,"r"); - struct rewriteConfigState *state = zmalloc(sizeof(*state), MALLOC_LOCAL); + struct rewriteConfigState *state = (rewriteConfigState*)zmalloc(sizeof(*state), MALLOC_LOCAL); char buf[CONFIG_MAX_LINE+1]; int linenum = -1; @@ -1839,7 +1831,7 @@ struct rewriteConfigState *rewriteConfigReadOldFile(char *path) { * in any way. */ void rewriteConfigRewriteLine(struct rewriteConfigState *state, const char *option, sds line, int force) { sds o = sdsnew(option); - list *l = dictFetchValue(state->option_to_line,o); + list *l = (list*)dictFetchValue(state->option_to_line,o); rewriteConfigMarkAsProcessed(state,option); @@ -1891,7 +1883,7 @@ int rewriteConfigFormatMemory(char *buf, size_t len, long long bytes) { } /* Rewrite a simple "option-name " configuration option. */ -void rewriteConfigBytesOption(struct rewriteConfigState *state, char *option, long long value, long long defvalue) { +void rewriteConfigBytesOption(struct rewriteConfigState *state, const char *option, long long value, long long defvalue) { char buf[64]; int force = value != defvalue; sds line; @@ -1902,7 +1894,7 @@ void rewriteConfigBytesOption(struct rewriteConfigState *state, char *option, lo } /* Rewrite a yes/no option. */ -void rewriteConfigYesNoOption(struct rewriteConfigState *state, char *option, int value, int defvalue) { +void rewriteConfigYesNoOption(struct rewriteConfigState *state, const char *option, int value, int defvalue) { int force = value != defvalue; sds line = sdscatprintf(sdsempty(),"%s %s",option, value ? "yes" : "no"); @@ -1911,7 +1903,7 @@ void rewriteConfigYesNoOption(struct rewriteConfigState *state, char *option, in } /* Rewrite a string option. */ -void rewriteConfigStringOption(struct rewriteConfigState *state, char *option, char *value, char *defvalue) { +void rewriteConfigStringOption(struct rewriteConfigState *state, const char *option, const char *value, const char *defvalue) { int force = 1; sds line; @@ -1933,7 +1925,7 @@ void rewriteConfigStringOption(struct rewriteConfigState *state, char *option, c } /* Rewrite a numerical (long long range) option. */ -void rewriteConfigNumericalOption(struct rewriteConfigState *state, char *option, long long value, long long defvalue) { +void rewriteConfigNumericalOption(struct rewriteConfigState *state, const char *option, long long value, long long defvalue) { int force = value != defvalue; sds line = sdscatprintf(sdsempty(),"%s %lld",option,value); @@ -1941,7 +1933,7 @@ void rewriteConfigNumericalOption(struct rewriteConfigState *state, char *option } /* Rewrite a octal option. */ -void rewriteConfigOctalOption(struct rewriteConfigState *state, char *option, int value, int defvalue) { +void rewriteConfigOctalOption(struct rewriteConfigState *state, const char *option, int value, int defvalue) { int force = value != defvalue; sds line = sdscatprintf(sdsempty(),"%s %o",option,value); @@ -1951,7 +1943,7 @@ void rewriteConfigOctalOption(struct rewriteConfigState *state, char *option, in /* Rewrite an enumeration option. It takes as usually state and option name, * and in addition the enumeration array and the default value for the * option. */ -void rewriteConfigEnumOption(struct rewriteConfigState *state, char *option, int value, configEnum *ce, int defval) { +void rewriteConfigEnumOption(struct rewriteConfigState *state, const char *option, int value, configEnum *ce, int defval) { sds line; const char *name = configEnumGetNameOrUnknown(ce,value); int force = value != defval; @@ -2006,7 +1998,7 @@ void rewriteConfigUserOption(struct rewriteConfigState *state) { raxStart(&ri,Users); raxSeek(&ri,"^",NULL,0); while(raxNext(&ri)) { - user *u = ri.data; + user *u = (user*)ri.data; sds line = sdsnew("user "); line = sdscatsds(line,u->name); line = sdscatlen(line," ",1); @@ -2033,7 +2025,7 @@ void rewriteConfigDirOption(struct rewriteConfigState *state) { } /* Rewrite the slaveof option. */ -void rewriteConfigSlaveofOption(struct rewriteConfigState *state, char *option) { +void rewriteConfigSlaveofOption(struct rewriteConfigState *state, const char *option) { /* If this is a master, we want all the slaveof config options * in the file to be removed. Note that if this is a cluster instance * we don't want a slaveof directive inside redis.conf. */ @@ -2059,7 +2051,7 @@ void rewriteConfigSlaveofOption(struct rewriteConfigState *state, char *option) /* Rewrite the notify-keyspace-events option. */ void rewriteConfigNotifykeyspaceeventsOption(struct rewriteConfigState *state) { int force = server.notify_keyspace_events != 0; - char *option = "notify-keyspace-events"; + const char *option = "notify-keyspace-events"; sds line, flags; flags = keyspaceEventsFlagsToString(server.notify_keyspace_events); @@ -2073,7 +2065,7 @@ void rewriteConfigNotifykeyspaceeventsOption(struct rewriteConfigState *state) { /* Rewrite the client-output-buffer-limit option. */ void rewriteConfigClientoutputbufferlimitOption(struct rewriteConfigState *state) { int j; - char *option = "client-output-buffer-limit"; + const char *option = "client-output-buffer-limit"; for (j = 0; j < CLIENT_TYPE_OBUF_COUNT; j++) { int force = (server.client_obuf_limits[j].hard_limit_bytes != @@ -2090,10 +2082,10 @@ void rewriteConfigClientoutputbufferlimitOption(struct rewriteConfigState *state rewriteConfigFormatMemory(soft,sizeof(soft), server.client_obuf_limits[j].soft_limit_bytes); - const char *typename = getClientTypeName(j); - if (!strcmp(typename,"slave")) typename = "replica"; + const char *tname = getClientTypeName(j); + if (!strcmp(tname,"slave")) tname = "replica"; line = sdscatprintf(sdsempty(),"%s %s %s %s %ld", - option, typename, hard, soft, + option, tname, hard, soft, (long) server.client_obuf_limits[j].soft_limit_seconds); rewriteConfigRewriteLine(state,option,line,force); } @@ -2103,7 +2095,7 @@ void rewriteConfigClientoutputbufferlimitOption(struct rewriteConfigState *state void rewriteConfigBindOption(struct rewriteConfigState *state) { int force = 1; sds line, addresses; - char *option = "bind"; + const char *option = "bind"; /* Nothing to rewrite if we don't have bind addresses. */ if (server.bindaddr_count == 0) { @@ -2122,7 +2114,7 @@ void rewriteConfigBindOption(struct rewriteConfigState *state) { } /* Rewrite the requirepass option. */ -void rewriteConfigRequirepassOption(struct rewriteConfigState *state, char *option) { +void rewriteConfigRequirepassOption(struct rewriteConfigState *state, const char *option) { int force = 1; sds line; sds password = ACLDefaultUserFirstPassword(); @@ -2182,8 +2174,8 @@ void rewriteConfigRemoveOrphaned(struct rewriteConfigState *state) { dictEntry *de; while((de = dictNext(di)) != NULL) { - list *l = dictGetVal(de); - sds option = dictGetKey(de); + list *l = (list*)dictGetVal(de); + sds option = (sds)dictGetKey(de); /* Don't blank lines about options the rewrite process * don't understand. */ @@ -2370,7 +2362,6 @@ int rewriteConfig(char *path) { rewriteConfigYesNoOption(state,"activerehashing",server.activerehashing,CONFIG_DEFAULT_ACTIVE_REHASHING); rewriteConfigYesNoOption(state,"activedefrag",server.active_defrag_enabled,CONFIG_DEFAULT_ACTIVE_DEFRAG); rewriteConfigYesNoOption(state,"protected-mode",server.protected_mode,CONFIG_DEFAULT_PROTECTED_MODE); - rewriteConfigYesNoOption(state,"gopher-enabled",server.gopher_enabled,CONFIG_DEFAULT_GOPHER_ENABLED); rewriteConfigClientoutputbufferlimitOption(state); rewriteConfigNumericalOption(state,"hz",server.config_hz,CONFIG_DEFAULT_HZ); rewriteConfigYesNoOption(state,"aof-rewrite-incremental-fsync",server.aof_rewrite_incremental_fsync,CONFIG_DEFAULT_AOF_REWRITE_INCREMENTAL_FSYNC); @@ -2410,12 +2401,12 @@ int rewriteConfig(char *path) { void configCommand(client *c) { /* Only allow CONFIG GET while loading. */ - if (server.loading && strcasecmp(ptrFromObj(c->argv[1]),"get")) { + if (server.loading && strcasecmp(szFromObj(c->argv[1]),"get")) { addReplyError(c,"Only CONFIG GET is allowed during loading"); return; } - if (c->argc == 2 && !strcasecmp(ptrFromObj(c->argv[1]),"help")) { + if (c->argc == 2 && !strcasecmp(szFromObj(c->argv[1]),"help")) { const char *help[] = { "GET -- Return parameters matching the glob-like and their values.", "SET -- Set parameter to value.", @@ -2424,15 +2415,15 @@ void configCommand(client *c) { NULL }; addReplyHelp(c, help); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"set") && c->argc == 4) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"set") && c->argc == 4) { configSetCommand(c); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"get") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"get") && c->argc == 3) { configGetCommand(c); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"resetstat") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"resetstat") && c->argc == 2) { resetServerStats(); resetCommandTableStats(); addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"rewrite") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"rewrite") && c->argc == 2) { if (server.configfile == NULL) { addReplyError(c,"The server is running without a config file"); return; diff --git a/src/crc16.c b/src/crc16.c index 7b8c1dad0..5c8d79c02 100644 --- a/src/crc16.c +++ b/src/crc16.c @@ -1,5 +1,3 @@ -#include "server.h" - /* * Copyright 2001-2010 Georges Menie (www.menie.org) * Copyright 2010-2012 Salvatore Sanfilippo (adapted to Redis coding style) @@ -29,6 +27,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + /* CRC16 implementation according to CCITT standards. * * Note by @antirez: this is actually the XMODEM CRC 16 algorithm, using the diff --git a/src/debug.c b/src/debug.cpp similarity index 93% rename from src/debug.c rename to src/debug.cpp index 91ecde52b..0d0011f6c 100644 --- a/src/debug.c +++ b/src/debug.cpp @@ -61,9 +61,10 @@ typedef ucontext_t sigcontext_t; * "add" digests relative to unordered elements. * * So digest(a,b,c,d) will be the same of digest(b,a,c,d) */ -void xorDigest(unsigned char *digest, void *ptr, size_t len) { +extern "C" void xorDigest(unsigned char *digest, const void *ptr, size_t len) { SHA1_CTX ctx; - unsigned char hash[20], *s = ptr; + unsigned char hash[20]; + const unsigned char *s = (const unsigned char*)ptr; int j; SHA1Init(&ctx); @@ -76,7 +77,7 @@ void xorDigest(unsigned char *digest, void *ptr, size_t len) { void xorStringObjectDigest(unsigned char *digest, robj *o) { o = getDecodedObject(o); - xorDigest(digest,ptrFromObj(o),sdslen(ptrFromObj(o))); + xorDigest(digest,(const unsigned char*)ptrFromObj(o),sdslen(szFromObj(o))); decrRefCount(o); } @@ -96,7 +97,7 @@ void xorStringObjectDigest(unsigned char *digest, robj *o) { */ void mixDigest(unsigned char *digest, void *ptr, size_t len) { SHA1_CTX ctx; - char *s = ptr; + char *s = (char*)ptr; xorDigest(digest,s,len); SHA1Init(&ctx); @@ -106,7 +107,7 @@ void mixDigest(unsigned char *digest, void *ptr, size_t len) { void mixStringObjectDigest(unsigned char *digest, robj *o) { o = getDecodedObject(o); - mixDigest(digest,ptrFromObj(o),sdslen(ptrFromObj(o))); + mixDigest(digest,ptrFromObj(o),sdslen(szFromObj(o))); decrRefCount(o); } @@ -148,7 +149,7 @@ void xorObjectDigest(redisDb *db, robj *keyobj, unsigned char *digest, robj *o) unsigned char eledigest[20]; if (o->encoding == OBJ_ENCODING_ZIPLIST) { - unsigned char *zl = ptrFromObj(o); + unsigned char *zl = (unsigned char*)ptrFromObj(o); unsigned char *eptr, *sptr; unsigned char *vstr; unsigned int vlen; @@ -178,13 +179,13 @@ void xorObjectDigest(redisDb *db, robj *keyobj, unsigned char *digest, robj *o) zzlNext(zl,&eptr,&sptr); } } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = ptrFromObj(o); + zset *zs = (zset*)ptrFromObj(o); dictIterator *di = dictGetIterator(zs->pdict); dictEntry *de; while((de = dictNext(di)) != NULL) { - sds sdsele = dictGetKey(de); - double *score = dictGetVal(de); + sds sdsele = (sds)dictGetKey(de); + double *score = (double*)dictGetVal(de); snprintf(buf,sizeof(buf),"%.17g",*score); memset(eledigest,0,20); @@ -214,7 +215,7 @@ void xorObjectDigest(redisDb *db, robj *keyobj, unsigned char *digest, robj *o) hashTypeReleaseIterator(hi); } else if (o->type == OBJ_STREAM) { streamIterator si; - streamIteratorStart(&si,ptrFromObj(o),NULL,NULL,0); + streamIteratorStart(&si,(stream*)ptrFromObj(o),NULL,NULL,0); streamID id; int64_t numfields; @@ -235,7 +236,7 @@ void xorObjectDigest(redisDb *db, robj *keyobj, unsigned char *digest, robj *o) streamIteratorStop(&si); } else if (o->type == OBJ_MODULE) { RedisModuleDigest md; - moduleValue *mv = ptrFromObj(o); + moduleValue *mv = (moduleValue*)ptrFromObj(o); moduleType *mt = mv->type; moduleInitDigestContext(md); if (mt->digest) { @@ -281,12 +282,12 @@ void computeDatasetDigest(unsigned char *final) { robj *keyobj, *o; memset(digest,0,20); /* This key-val digest */ - key = dictGetKey(de); + key = (sds)dictGetKey(de); keyobj = createStringObject(key,sdslen(key)); mixDigest(digest,key,sdslen(key)); - o = dictGetVal(de); + o = (robj*)dictGetVal(de); xorObjectDigest(db,keyobj,digest,o); /* We can finally xor the key-val digest to the final digest */ @@ -298,7 +299,7 @@ void computeDatasetDigest(unsigned char *final) { } void debugCommand(client *c) { - if (c->argc == 2 && !strcasecmp(ptrFromObj(c->argv[1]),"help")) { + if (c->argc == 2 && !strcasecmp(szFromObj(c->argv[1]),"help")) { const char *help[] = { "ASSERT -- Crash by assertion failed.", "CHANGE-REPL-ID -- Change the replication IDs of the instance. Dangerous, should be used only for testing the replication subsystem.", @@ -326,12 +327,12 @@ void debugCommand(client *c) { NULL }; addReplyHelp(c, help); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"segfault")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"segfault")) { *((char*)-1) = 'x'; - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"panic")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"panic")) { serverPanic("DEBUG PANIC called at Unix time %ld", time(NULL)); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"restart") || - !strcasecmp(ptrFromObj(c->argv[1]),"crash-and-recover")) + } else if (!strcasecmp(szFromObj(c->argv[1]),"restart") || + !strcasecmp(szFromObj(c->argv[1]),"crash-and-recover")) { long long delay = 0; if (c->argc >= 3) { @@ -339,21 +340,21 @@ NULL != C_OK) return; if (delay < 0) delay = 0; } - int flags = !strcasecmp(ptrFromObj(c->argv[1]),"restart") ? + int flags = !strcasecmp(szFromObj(c->argv[1]),"restart") ? (RESTART_SERVER_GRACEFULLY|RESTART_SERVER_CONFIG_REWRITE) : RESTART_SERVER_NONE; restartServer(flags,delay); addReplyError(c,"failed to restart the server. Check server logs."); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"oom")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"oom")) { void *ptr = zmalloc(ULONG_MAX, MALLOC_LOCAL); /* Should trigger an out of memory. */ zfree(ptr); addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"assert")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"assert")) { serverAssertWithInfo(c,c->argv[0],1 == 2); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"log") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"log") && c->argc == 3) { serverLog(LL_WARNING, "DEBUG LOG: %s", (char*)ptrFromObj(c->argv[2])); addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"reload")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"reload")) { rdbSaveInfo rsi, *rsiptr; rsiptr = rdbPopulateSaveInfo(&rsi); if (rdbSave(rsiptr) != C_OK) { @@ -371,7 +372,7 @@ NULL } serverLog(LL_WARNING,"DB reloaded by DEBUG RELOAD"); addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"loadaof")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"loadaof")) { if (server.aof_state != AOF_OFF) flushAppendOnlyFile(1); emptyDb(-1,EMPTYDB_NO_FLAGS,NULL); protectClient(c); @@ -384,23 +385,23 @@ NULL server.dirty = 0; /* Prevent AOF / replication */ serverLog(LL_WARNING,"Append Only File loaded by DEBUG LOADAOF"); addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"object") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"object") && c->argc == 3) { dictEntry *de; robj *val; - char *strenc; + const char *strenc; if ((de = dictFind(c->db->pdict,ptrFromObj(c->argv[2]))) == NULL) { addReply(c,shared.nokeyerr); return; } - val = dictGetVal(de); + val = (robj*)dictGetVal(de); strenc = strEncoding(val->encoding); char extra[138] = {0}; if (val->encoding == OBJ_ENCODING_QUICKLIST) { char *nextra = extra; int remaining = sizeof(extra); - quicklist *ql = val->m_ptr; + quicklist *ql = (quicklist*)val->m_ptr; /* Add number of quicklist nodes */ int used = snprintf(nextra, remaining, " ql_nodes:%lu", ql->len); nextra += used; @@ -436,7 +437,7 @@ NULL (void*)val, val->refcount, strenc, rdbSavedObjectLen(val), val->lru, estimateObjectIdleTime(val)/1000, extra); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"sdslen") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"sdslen") && c->argc == 3) { dictEntry *de; robj *val; sds key; @@ -445,8 +446,8 @@ NULL addReply(c,shared.nokeyerr); return; } - val = dictGetVal(de); - key = dictGetKey(de); + val = (robj*)dictGetVal(de); + key = (sds)dictGetKey(de); if (val->type != OBJ_STRING || !sdsEncodedObject(val)) { addReplyError(c,"Not an sds encoded string."); @@ -457,11 +458,11 @@ NULL (long long) sdslen(key), (long long) sdsavail(key), (long long) sdsZmallocSize(key), - (long long) sdslen(ptrFromObj(val)), - (long long) sdsavail(ptrFromObj(val)), + (long long) sdslen(szFromObj(val)), + (long long) sdsavail(szFromObj(val)), (long long) getStringObjectSdsUsedMemory(val)); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"ziplist") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"ziplist") && c->argc == 3) { robj *o; if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nokeyerr)) @@ -470,10 +471,10 @@ NULL if (o->encoding != OBJ_ENCODING_ZIPLIST) { addReplyError(c,"Not an sds encoded string."); } else { - ziplistRepr(ptrFromObj(o)); + ziplistRepr((unsigned char*)ptrFromObj(o)); addReplyStatus(c,"Ziplist structure printed on stdout"); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"populate") && + } else if (!strcasecmp(szFromObj(c->argv[1]),"populate") && c->argc >= 3 && c->argc <= 5) { long keys, j; robj *key, *val; @@ -507,7 +508,7 @@ NULL decrRefCount(key); } addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"digest") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"digest") && c->argc == 2) { /* DEBUG DIGEST (form without keys specified) */ unsigned char digest[20]; sds d = sdsempty(); @@ -516,7 +517,7 @@ NULL for (int i = 0; i < 20; i++) d = sdscatprintf(d, "%02x",digest[i]); addReplyStatus(c,d); sdsfree(d); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"digest-value") && c->argc >= 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"digest-value") && c->argc >= 2) { /* DEBUG DIGEST-VALUE key key key ... key. */ addReplyArrayLen(c,c->argc-2); for (int j = 2; j < c->argc; j++) { @@ -530,10 +531,10 @@ NULL addReplyStatus(c,d); sdsfree(d); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"protocol") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"protocol") && c->argc == 3) { /* DEBUG PROTOCOL [string|integer|double|bignum|null|array|set|map| * attrib|push|verbatim|true|false|state|err|bloberr] */ - char *name = ptrFromObj(c->argv[2]); + char *name = szFromObj(c->argv[2]); if (!strcasecmp(name,"string")) { addReplyBulkCString(c,"Hello World"); } else if (!strcasecmp(name,"integer")) { @@ -582,8 +583,8 @@ NULL } else { addReplyError(c,"Wrong protocol type name. Please use one of the following: string|integer|double|bignum|null|array|set|map|attrib|push|verbatim|true|false|state|err|bloberr"); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"sleep") && c->argc == 3) { - double dtime = strtod(ptrFromObj(c->argv[2]),NULL); + } else if (!strcasecmp(szFromObj(c->argv[1]),"sleep") && c->argc == 3) { + double dtime = strtod(szFromObj(c->argv[2]),NULL); long long utime = dtime*1000000; struct timespec tv; @@ -591,24 +592,24 @@ NULL tv.tv_nsec = (utime % 1000000) * 1000; nanosleep(&tv, NULL); addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"set-active-expire") && + } else if (!strcasecmp(szFromObj(c->argv[1]),"set-active-expire") && c->argc == 3) { - server.active_expire_enabled = atoi(ptrFromObj(c->argv[2])); + server.active_expire_enabled = atoi(szFromObj(c->argv[2])); addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"lua-always-replicate-commands") && + } else if (!strcasecmp(szFromObj(c->argv[1]),"lua-always-replicate-commands") && c->argc == 3) { - server.lua_always_replicate_commands = atoi(ptrFromObj(c->argv[2])); + server.lua_always_replicate_commands = atoi(szFromObj(c->argv[2])); addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"error") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"error") && c->argc == 3) { sds errstr = sdsnewlen("-",1); - errstr = sdscatsds(errstr,ptrFromObj(c->argv[2])); + errstr = sdscatsds(errstr,szFromObj(c->argv[2])); errstr = sdsmapchars(errstr,"\n\r"," ",2); /* no newlines in errors. */ errstr = sdscatlen(errstr,"\r\n",2); addReplySds(c,errstr); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"structsize") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"structsize") && c->argc == 2) { sds sizes = sdsempty(); sizes = sdscatprintf(sizes,"bits:%d ",(sizeof(void*) == 8)?64:32); sizes = sdscatprintf(sizes,"robj:%d ",(int)sizeof(robj)); @@ -619,7 +620,7 @@ NULL sizes = sdscatprintf(sizes,"sdshdr32:%d ",(int)sizeof(struct sdshdr32)); sizes = sdscatprintf(sizes,"sdshdr64:%d ",(int)sizeof(struct sdshdr64)); addReplyBulkSds(c,sizes); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"htstats") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"htstats") && c->argc == 3) { long dbid; sds stats = sdsempty(); char buf[4096]; @@ -640,7 +641,7 @@ NULL stats = sdscat(stats,buf); addReplyBulkSds(c,stats); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"htstats-key") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"htstats-key") && c->argc == 3) { robj *o; dict *ht = NULL; @@ -651,12 +652,12 @@ NULL switch (o->encoding) { case OBJ_ENCODING_SKIPLIST: { - zset *zs = ptrFromObj(o); + zset *zs = (zset*)ptrFromObj(o); ht = zs->pdict; } break; case OBJ_ENCODING_HT: - ht = ptrFromObj(o); + ht = (dict*)ptrFromObj(o); break; } @@ -668,12 +669,12 @@ NULL dictGetStats(buf,sizeof(buf),ht); addReplyBulkCString(c,buf); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"change-repl-id") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"change-repl-id") && c->argc == 2) { serverLog(LL_WARNING,"Changing replication IDs after receiving DEBUG change-repl-id"); changeReplicationId(); clearReplicationId2(); addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"stringmatch-test") && c->argc == 2) + } else if (!strcasecmp(szFromObj(c->argv[1]),"stringmatch-test") && c->argc == 2) { stringmatchlen_fuzz_test(); addReplyStatus(c,"Apparently Redis did not crash: test passed"); @@ -727,9 +728,9 @@ void serverLogObjectDebugInfo(const robj *o) { serverLog(LL_WARNING,"Object encoding: %d", o->encoding); serverLog(LL_WARNING,"Object refcount: %d", o->refcount); if (o->type == OBJ_STRING && sdsEncodedObject(o)) { - serverLog(LL_WARNING,"Object raw string len: %zu", sdslen(ptrFromObj(o))); - if (sdslen(ptrFromObj(o)) < 4096) { - sds repr = sdscatrepr(sdsempty(),ptrFromObj(o),sdslen(ptrFromObj(o))); + serverLog(LL_WARNING,"Object raw string len: %zu", sdslen(szFromObj(o))); + if (sdslen(szFromObj(o)) < 4096) { + sds repr = sdscatrepr(sdsempty(),szFromObj(o),sdslen(szFromObj(o))); serverLog(LL_WARNING,"Object raw string content: %s", repr); sdsfree(repr); } @@ -1149,8 +1150,8 @@ void logStackTrace(ucontext_t *uc) { trace_size = backtrace(trace+1, 100); if (getMcontextEip(uc) != NULL) { - char *msg1 = "EIP:\n"; - char *msg2 = "\nBacktrace:\n"; + const char *msg1 = "EIP:\n"; + const char *msg2 = "\nBacktrace:\n"; if (write(fd,msg1,strlen(msg1)) == -1) {/* Avoid warning. */}; trace[0] = getMcontextEip(uc); backtrace_symbols_fd(trace, 1, fd); @@ -1195,7 +1196,7 @@ void logCurrentClient(void) { key = getDecodedObject(cc->argv[1]); de = dictFind(cc->db->pdict, ptrFromObj(key)); if (de) { - val = dictGetVal(de); + val = (robj*)dictGetVal(de); serverLog(LL_WARNING,"key '%s' found in DB containing the following object:", (char*)ptrFromObj(key)); serverLogObjectDebugInfo(val); } @@ -1256,7 +1257,7 @@ int memtest_test_linux_anonymous_maps(void) { int errors = 0; for (j = 0; j < regions; j++) { if (write(fd,".",1) == -1) { /* Nothing to do. */ } - errors += memtest_preserving_test((void*)start_vect[j],size_vect[j],1); + errors += memtest_preserving_test((unsigned long*)start_vect[j],size_vect[j],1); if (write(fd, errors ? "E" : "O",1) == -1) { /* Nothing to do. */ } } if (write(fd,"\n",1) == -1) { /* Nothing to do. */ } @@ -1275,7 +1276,7 @@ int memtest_test_linux_anonymous_maps(void) { * and the call offset if they appear to be valid. */ void dumpX86Calls(void *addr, size_t len) { size_t j; - unsigned char *p = addr; + unsigned char *p = (unsigned char*)addr; Dl_info info; /* Hash table to best-effort avoid printing the same symbol * multiple times. */ @@ -1404,7 +1405,7 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) { void serverLogHexDump(int level, const char *descr, void *value, size_t len) { char buf[65], *b; - unsigned char *v = value; + unsigned char *v = (unsigned char*)value; char charset[] = "0123456789abcdef"; serverLog(level,"%s (hexdump of %zu bytes):", descr, len); diff --git a/src/defrag.c b/src/defrag.cpp similarity index 89% rename from src/defrag.c rename to src/defrag.cpp index af12289f3..2cdf2c286 100644 --- a/src/defrag.c +++ b/src/defrag.cpp @@ -43,7 +43,7 @@ /* this method was added to jemalloc in order to help us understand which * pointers are worthwhile moving and which aren't */ -int je_get_defrag_hint(void* ptr, int *bin_util, int *run_util); +extern "C" int je_get_defrag_hint(void* ptr, int *bin_util, int *run_util); /* forward declarations*/ void defragDictBucketCallback(void *privdata, dictEntry **bucketref); @@ -107,7 +107,7 @@ robj *activeDefragStringOb(robj* ob, long *defragged) { /* try to defrag robj (only if not an EMBSTR type (handled below). */ if (ob->type!=OBJ_STRING || ob->encoding!=OBJ_ENCODING_EMBSTR) { - if ((ret = activeDefragAlloc(ob))) { + if ((ret = (robj*)activeDefragAlloc(ob))) { ob = ret; (*defragged)++; } @@ -124,7 +124,7 @@ robj *activeDefragStringOb(robj* ob, long *defragged) { } else if (ob->encoding==OBJ_ENCODING_EMBSTR) { /* The sds is embedded in the object allocation, calculate the * offset and update the pointer in the new allocation. */ - if ((ret = activeDefragAlloc(ob))) { + if ((ret = (robj*)activeDefragAlloc(ob))) { (*defragged)++; } } else if (ob->encoding!=OBJ_ENCODING_INT) { @@ -145,7 +145,7 @@ long dictIterDefragEntry(dictIterator *iter) { /* Handle the next entry (if there is one), and update the pointer in the * current entry. */ if (iter->nextEntry) { - dictEntry *newde = activeDefragAlloc(iter->nextEntry); + dictEntry *newde = (dictEntry*)activeDefragAlloc(iter->nextEntry); if (newde) { defragged++; iter->nextEntry = newde; @@ -155,7 +155,7 @@ long dictIterDefragEntry(dictIterator *iter) { /* handle the case of the first entry in the hash bucket. */ ht = &iter->d->ht[iter->table]; if (ht->table[iter->index] == iter->entry) { - dictEntry *newde = activeDefragAlloc(iter->entry); + dictEntry *newde = (dictEntry*)activeDefragAlloc(iter->entry); if (newde) { iter->entry = newde; ht->table[iter->index] = newde; @@ -172,12 +172,12 @@ long dictDefragTables(dict* d) { dictEntry **newtable; long defragged = 0; /* handle the first hash table */ - newtable = activeDefragAlloc(d->ht[0].table); + newtable = (dictEntry**)activeDefragAlloc(d->ht[0].table); if (newtable) defragged++, d->ht[0].table = newtable; /* handle the second hash table */ if (d->ht[1].table) { - newtable = activeDefragAlloc(d->ht[1].table); + newtable = (dictEntry**)activeDefragAlloc(d->ht[1].table); if (newtable) defragged++, d->ht[1].table = newtable; } @@ -188,13 +188,13 @@ long dictDefragTables(dict* d) { void zslUpdateNode(zskiplist *zsl, zskiplistNode *oldnode, zskiplistNode *newnode, zskiplistNode **update) { int i; for (i = 0; i < zsl->level; i++) { - if (update[i]->level[i].forward == oldnode) - update[i]->level[i].forward = newnode; + if (update[i]->level(i)->forward == oldnode) + update[i]->level(i)->forward = newnode; } serverAssert(zsl->header!=oldnode); - if (newnode->level[0].forward) { - serverAssert(newnode->level[0].forward->backward==oldnode); - newnode->level[0].forward->backward = newnode; + if (newnode->level(0)->forward) { + serverAssert(newnode->level(0)->forward->backward==oldnode); + newnode->level(0)->forward->backward = newnode; } else { serverAssert(zsl->tail==oldnode); zsl->tail = newnode; @@ -217,25 +217,25 @@ double *zslDefrag(zskiplist *zsl, double score, sds oldele, sds newele) { * and all pointers that need to be updated if we'll end up moving the skiplist node. */ x = zsl->header; for (i = zsl->level-1; i >= 0; i--) { - while (x->level[i].forward && - x->level[i].forward->ele != oldele && /* make sure not to access the + while (x->level(i)->forward && + x->level(i)->forward->ele != oldele && /* make sure not to access the ->obj pointer if it matches oldele */ - (x->level[i].forward->score < score || - (x->level[i].forward->score == score && - sdscmp(x->level[i].forward->ele,ele) < 0))) - x = x->level[i].forward; + (x->level(i)->forward->score < score || + (x->level(i)->forward->score == score && + sdscmp(x->level(i)->forward->ele,ele) < 0))) + x = x->level(i)->forward; update[i] = x; } /* update the robj pointer inside the skip list record. */ - x = x->level[0].forward; + x = x->level(0)->forward; serverAssert(x && score == x->score && x->ele==oldele); if (newele) x->ele = newele; /* try to defrag the skiplist record itself */ - newx = activeDefragAlloc(x); + newx = (zskiplistNode*)activeDefragAlloc(x); if (newx) { zslUpdateNode(zsl, x, newx, update); return &newx->score; @@ -249,7 +249,7 @@ long activeDefragZsetEntry(zset *zs, dictEntry *de) { sds newsds; double* newscore; long defragged = 0; - sds sdsele = dictGetKey(de); + sds sdsele = (sds)dictGetKey(de); if ((newsds = activeDefragSds(sdsele))) defragged++, de->key = newsds; newscore = zslDefrag(zs->zsl, *(double*)dictGetVal(de), sdsele, newsds); @@ -272,16 +272,16 @@ long activeDefragSdsDict(dict* d, int val_type) { long defragged = 0; di = dictGetIterator(d); while((de = dictNext(di)) != NULL) { - sds sdsele = dictGetKey(de), newsds; + sds sdsele = (sds)dictGetKey(de), newsds; if ((newsds = activeDefragSds(sdsele))) de->key = newsds, defragged++; /* defrag the value */ if (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) { - sdsele = dictGetVal(de); + sdsele = (sds)dictGetVal(de); if ((newsds = activeDefragSds(sdsele))) de->v.val = newsds, defragged++; } else if (val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) { - robj *newele, *ele = dictGetVal(de); + robj *newele, *ele = (robj*)dictGetVal(de); if ((newele = activeDefragStringOb(ele, &defragged))) de->v.val = newele; } else if (val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) { @@ -300,7 +300,7 @@ long activeDefragList(list *l, int val_type) { long defragged = 0; listNode *ln, *newln; for (ln = l->head; ln; ln = ln->next) { - if ((newln = activeDefragAlloc(ln))) { + if ((newln = (listNode*)activeDefragAlloc(ln))) { if (newln->prev) newln->prev->next = newln; else @@ -313,11 +313,11 @@ long activeDefragList(list *l, int val_type) { defragged++; } if (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) { - sds newsds, sdsele = ln->value; + sds newsds, sdsele = (sds)ln->value; if ((newsds = activeDefragSds(sdsele))) ln->value = newsds, defragged++; } else if (val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) { - robj *newele, *ele = ln->value; + robj *newele, *ele = (robj*)ln->value; if ((newele = activeDefragStringOb(ele, &defragged))) ln->value = newele; } else if (val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) { @@ -338,7 +338,7 @@ long activeDefragSdsListAndDict(list *l, dict *d, int dict_val_type) { dictEntry *de; /* Defrag the list and it's sds values */ for (ln = l->head; ln; ln = ln->next) { - if ((newln = activeDefragAlloc(ln))) { + if ((newln = (listNode*)activeDefragAlloc(ln))) { if (newln->prev) newln->prev->next = newln; else @@ -350,7 +350,7 @@ long activeDefragSdsListAndDict(list *l, dict *d, int dict_val_type) { ln = newln; defragged++; } - sdsele = ln->value; + sdsele = (sds)ln->value; if ((newsds = activeDefragSds(sdsele))) { /* When defragging an sds value, we need to update the dict key */ unsigned int hash = dictGetHash(d, sdsele); @@ -364,11 +364,11 @@ long activeDefragSdsListAndDict(list *l, dict *d, int dict_val_type) { di = dictGetIterator(d); while((de = dictNext(di)) != NULL) { if (dict_val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) { - sds newsds, sdsele = dictGetVal(de); + sds newsds, sdsele = (sds)dictGetVal(de); if ((newsds = activeDefragSds(sdsele))) de->v.val = newsds, defragged++; } else if (dict_val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) { - robj *newele, *ele = dictGetVal(de); + robj *newele, *ele = (robj*)dictGetVal(de); if ((newele = activeDefragStringOb(ele, &defragged))) de->v.val = newele, defragged++; } else if (dict_val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) { @@ -394,7 +394,7 @@ dictEntry* replaceSateliteDictKeyPtrAndOrDefragDictEntry(dict *d, sds oldkey, sd dictEntry **deref = dictFindEntryRefByPtrAndHash(d, oldkey, hash); if (deref) { dictEntry *de = *deref; - dictEntry *newde = activeDefragAlloc(de); + dictEntry *newde = (dictEntry*)activeDefragAlloc(de); if (newde) { de = *deref = newde; (*defragged)++; @@ -411,7 +411,7 @@ long activeDefragQuickListNodes(quicklist *ql) { long defragged = 0; unsigned char *newzl; while (node) { - if ((newnode = activeDefragAlloc(node))) { + if ((newnode = (quicklistNode*)activeDefragAlloc(node))) { if (newnode->prev) newnode->prev->next = newnode; else @@ -423,7 +423,7 @@ long activeDefragQuickListNodes(quicklist *ql) { node = newnode; defragged++; } - if ((newzl = activeDefragAlloc(node->zl))) + if ((newzl = (unsigned char*)activeDefragAlloc(node->zl))) defragged++, node->zl = newzl; node = node->next; } @@ -434,12 +434,12 @@ long activeDefragQuickListNodes(quicklist *ql) { * oart of the main dictionary scan. this is needed in order to prevent latency * spikes when handling large items */ void defragLater(redisDb *db, dictEntry *kde) { - sds key = sdsdup(dictGetKey(kde)); + sds key = sdsdup((sds)dictGetKey(kde)); listAddNodeTail(db->defrag_later, key); } long scanLaterList(robj *ob) { - quicklist *ql = ptrFromObj(ob); + quicklist *ql = (quicklist*)ptrFromObj(ob); if (ob->type != OBJ_LIST || ob->encoding != OBJ_ENCODING_QUICKLIST) return 0; server.stat_active_defrag_scanned+=ql->len; @@ -453,7 +453,7 @@ typedef struct { void scanLaterZsetCallback(void *privdata, const dictEntry *_de) { dictEntry *de = (dictEntry*)_de; - scanLaterZsetData *data = privdata; + scanLaterZsetData *data = (scanLaterZsetData*)privdata; data->defragged += activeDefragZsetEntry(data->zs, de); server.stat_active_defrag_scanned++; } @@ -470,8 +470,8 @@ long scanLaterZset(robj *ob, unsigned long *cursor) { void scanLaterSetCallback(void *privdata, const dictEntry *_de) { dictEntry *de = (dictEntry*)_de; - long *defragged = privdata; - sds sdsele = dictGetKey(de), newsds; + long *defragged = (long*)privdata; + sds sdsele = (sds)dictGetKey(de), newsds; if ((newsds = activeDefragSds(sdsele))) (*defragged)++, de->key = newsds; server.stat_active_defrag_scanned++; @@ -481,18 +481,18 @@ long scanLaterSet(robj *ob, unsigned long *cursor) { long defragged = 0; if (ob->type != OBJ_SET || ob->encoding != OBJ_ENCODING_HT) return 0; - dict *d = ptrFromObj(ob); + dict *d = (dict*)ptrFromObj(ob); *cursor = dictScan(d, *cursor, scanLaterSetCallback, defragDictBucketCallback, &defragged); return defragged; } void scanLaterHashCallback(void *privdata, const dictEntry *_de) { dictEntry *de = (dictEntry*)_de; - long *defragged = privdata; - sds sdsele = dictGetKey(de), newsds; + long *defragged = (long*)privdata; + sds sdsele = (sds)dictGetKey(de), newsds; if ((newsds = activeDefragSds(sdsele))) (*defragged)++, de->key = newsds; - sdsele = dictGetVal(de); + sdsele = (sds)dictGetVal(de); if ((newsds = activeDefragSds(sdsele))) (*defragged)++, de->v.val = newsds; server.stat_active_defrag_scanned++; @@ -502,17 +502,17 @@ long scanLaterHash(robj *ob, unsigned long *cursor) { long defragged = 0; if (ob->type != OBJ_HASH || ob->encoding != OBJ_ENCODING_HT) return 0; - dict *d = ptrFromObj(ob); + dict *d = (dict*)ptrFromObj(ob); *cursor = dictScan(d, *cursor, scanLaterHashCallback, defragDictBucketCallback, &defragged); return defragged; } long defragQuicklist(redisDb *db, dictEntry *kde) { - robj *ob = dictGetVal(kde); + robj *ob = (robj*)dictGetVal(kde); long defragged = 0; - quicklist *ql = ptrFromObj(ob), *newql; + quicklist *ql = (quicklist*)ptrFromObj(ob), *newql; serverAssert(ob->type == OBJ_LIST && ob->encoding == OBJ_ENCODING_QUICKLIST); - if ((newql = activeDefragAlloc(ql))) + if ((newql = (quicklist*)activeDefragAlloc(ql))) defragged++, ob->m_ptr = ql = newql; if (ql->len > server.active_defrag_max_scan_fields) defragLater(db, kde); @@ -522,7 +522,7 @@ long defragQuicklist(redisDb *db, dictEntry *kde) { } long defragZsetSkiplist(redisDb *db, dictEntry *kde) { - robj *ob = dictGetVal(kde); + robj *ob = (robj*)dictGetVal(kde); long defragged = 0; zset *zs = (zset*)ptrFromObj(ob); zset *newzs; @@ -531,11 +531,11 @@ long defragZsetSkiplist(redisDb *db, dictEntry *kde) { dictEntry *de; struct zskiplistNode *newheader; serverAssert(ob->type == OBJ_ZSET && ob->encoding == OBJ_ENCODING_SKIPLIST); - if ((newzs = activeDefragAlloc(zs))) + if ((newzs = (zset*)activeDefragAlloc(zs))) defragged++, ob->m_ptr = zs = newzs; - if ((newzsl = activeDefragAlloc(zs->zsl))) + if ((newzsl = (zskiplist*)activeDefragAlloc(zs->zsl))) defragged++, zs->zsl = newzsl; - if ((newheader = activeDefragAlloc(zs->zsl->header))) + if ((newheader = (zskiplistNode*)activeDefragAlloc(zs->zsl->header))) defragged++, zs->zsl->header = newheader; if (dictSize(zs->pdict) > server.active_defrag_max_scan_fields) defragLater(db, kde); @@ -547,7 +547,7 @@ long defragZsetSkiplist(redisDb *db, dictEntry *kde) { dictReleaseIterator(di); } /* handle the dict struct */ - if ((newdict = activeDefragAlloc(zs->pdict))) + if ((newdict = (dict*)activeDefragAlloc(zs->pdict))) defragged++, zs->pdict = newdict; /* defrag the dict tables */ defragged += dictDefragTables(zs->pdict); @@ -556,44 +556,44 @@ long defragZsetSkiplist(redisDb *db, dictEntry *kde) { long defragHash(redisDb *db, dictEntry *kde) { long defragged = 0; - robj *ob = dictGetVal(kde); + robj *ob = (robj*)dictGetVal(kde); dict *d, *newd; serverAssert(ob->type == OBJ_HASH && ob->encoding == OBJ_ENCODING_HT); - d = ptrFromObj(ob); + d = (dict*)ptrFromObj(ob); if (dictSize(d) > server.active_defrag_max_scan_fields) defragLater(db, kde); else defragged += activeDefragSdsDict(d, DEFRAG_SDS_DICT_VAL_IS_SDS); /* handle the dict struct */ - if ((newd = activeDefragAlloc(ptrFromObj(ob)))) + if ((newd = (dict*)activeDefragAlloc(ptrFromObj(ob)))) defragged++, ob->m_ptr = newd; /* defrag the dict tables */ - defragged += dictDefragTables(ptrFromObj(ob)); + defragged += dictDefragTables((dict*)ptrFromObj(ob)); return defragged; } long defragSet(redisDb *db, dictEntry *kde) { long defragged = 0; - robj *ob = dictGetVal(kde); + robj *ob = (robj*)dictGetVal(kde); dict *d, *newd; serverAssert(ob->type == OBJ_SET && ob->encoding == OBJ_ENCODING_HT); - d = ptrFromObj(ob); + d = (dict*)ptrFromObj(ob); if (dictSize(d) > server.active_defrag_max_scan_fields) defragLater(db, kde); else defragged += activeDefragSdsDict(d, DEFRAG_SDS_DICT_NO_VAL); /* handle the dict struct */ - if ((newd = activeDefragAlloc(ptrFromObj(ob)))) + if ((newd = (dict*)activeDefragAlloc(ptrFromObj(ob)))) defragged++, ob->m_ptr = newd; /* defrag the dict tables */ - defragged += dictDefragTables(ptrFromObj(ob)); + defragged += dictDefragTables((dict*)ptrFromObj(ob)); return defragged; } /* Defrag callback for radix tree iterator, called for each node, * used in order to defrag the nodes allocations. */ int defragRaxNode(raxNode **noderef) { - raxNode *newnode = activeDefragAlloc(*noderef); + raxNode *newnode = (raxNode*)activeDefragAlloc(*noderef); if (newnode) { *noderef = newnode; return 1; @@ -611,7 +611,7 @@ int scanLaterStraemListpacks(robj *ob, unsigned long *cursor, long long endtime, return 0; } - stream *s = ptrFromObj(ob); + stream *s = (stream*)ptrFromObj(ob); raxStart(&ri,s->prax); if (*cursor == 0) { /* if cursor is 0, we start new iteration */ @@ -662,8 +662,8 @@ typedef void *(raxDefragFunction)(raxIterator *ri, void *privdata, long *defragg long defragRadixTree(rax **raxref, int defrag_data, raxDefragFunction *element_cb, void *element_cb_data) { long defragged = 0; raxIterator ri; - rax* rax; - if ((rax = activeDefragAlloc(*raxref))) + ::rax* rax; + if ((rax = (::rax*)activeDefragAlloc(*raxref))) defragged++, *raxref = rax; rax = *raxref; raxStart(&ri,rax); @@ -690,10 +690,10 @@ typedef struct { void* defragStreamConsumerPendingEntry(raxIterator *ri, void *privdata, long *defragged) { UNUSED(defragged); - PendingEntryContext *ctx = privdata; - streamNACK *nack = ri->data, *newnack; + PendingEntryContext *ctx = (PendingEntryContext*)privdata; + streamNACK *nack = (streamNACK*)ri->data, *newnack; nack->consumer = ctx->c; /* update nack pointer to consumer */ - newnack = activeDefragAlloc(nack); + newnack = (streamNACK*)activeDefragAlloc(nack); if (newnack) { /* update consumer group pointer to the nack */ void *prev; @@ -705,12 +705,12 @@ void* defragStreamConsumerPendingEntry(raxIterator *ri, void *privdata, long *de } void* defragStreamConsumer(raxIterator *ri, void *privdata, long *defragged) { - streamConsumer *c = ri->data; - streamCG *cg = privdata; + streamConsumer *c = (streamConsumer*)ri->data; + streamCG *cg = (streamCG*)privdata; void *newc = activeDefragAlloc(c); if (newc) { /* note: we don't increment 'defragged' that's done by the caller */ - c = newc; + c = (streamConsumer*)newc; } sds newsds = activeDefragSds(c->name); if (newsds) @@ -723,7 +723,7 @@ void* defragStreamConsumer(raxIterator *ri, void *privdata, long *defragged) { } void* defragStreamConsumerGroup(raxIterator *ri, void *privdata, long *defragged) { - streamCG *cg = ri->data; + streamCG *cg = (streamCG*)ri->data; UNUSED(privdata); if (cg->consumers) *defragged += defragRadixTree(&cg->consumers, 0, defragStreamConsumer, cg); @@ -734,16 +734,16 @@ void* defragStreamConsumerGroup(raxIterator *ri, void *privdata, long *defragged long defragStream(redisDb *db, dictEntry *kde) { long defragged = 0; - robj *ob = dictGetVal(kde); + robj *ob = (robj*)dictGetVal(kde); serverAssert(ob->type == OBJ_STREAM && ob->encoding == OBJ_ENCODING_STREAM); - stream *s = ptrFromObj(ob), *news; + stream *s = (stream*)ptrFromObj(ob), *news; /* handle the main struct */ - if ((news = activeDefragAlloc(s))) + if ((news = (stream*)activeDefragAlloc(s))) defragged++, ob->m_ptr = s = news; if (raxSize(s->prax) > server.active_defrag_max_scan_fields) { - rax *newrax = activeDefragAlloc(s->prax); + rax *newrax = (rax*)activeDefragAlloc(s->prax); if (newrax) defragged++, s->prax = newrax; defragLater(db, kde); @@ -759,7 +759,7 @@ long defragStream(redisDb *db, dictEntry *kde) { * all the various pointers it has. Returns a stat of how many pointers were * moved. */ long defragKey(redisDb *db, dictEntry *de) { - sds keysds = dictGetKey(de); + sds keysds = (sds)dictGetKey(de); robj *newob, *ob; unsigned char *newzl; long defragged = 0; @@ -778,7 +778,7 @@ long defragKey(redisDb *db, dictEntry *de) { } /* Try to defrag robj and / or string value. */ - ob = dictGetVal(de); + ob = (robj*)dictGetVal(de); if ((newob = activeDefragStringOb(ob, &defragged))) { de->v.val = newob; ob = newob; @@ -790,7 +790,7 @@ long defragKey(redisDb *db, dictEntry *de) { if (ob->encoding == OBJ_ENCODING_QUICKLIST) { defragged += defragQuicklist(db, de); } else if (ob->encoding == OBJ_ENCODING_ZIPLIST) { - if ((newzl = activeDefragAlloc(ptrFromObj(ob)))) + if ((newzl = (unsigned char*)activeDefragAlloc(ptrFromObj(ob)))) defragged++, ob->m_ptr = newzl; } else { serverPanic("Unknown list encoding"); @@ -799,15 +799,15 @@ long defragKey(redisDb *db, dictEntry *de) { if (ob->encoding == OBJ_ENCODING_HT) { defragged += defragSet(db, de); } else if (ob->encoding == OBJ_ENCODING_INTSET) { - intset *newis, *is = ptrFromObj(ob); - if ((newis = activeDefragAlloc(is))) + intset *newis, *is = (intset*)ptrFromObj(ob); + if ((newis = (intset*)activeDefragAlloc(is))) defragged++, ob->m_ptr = newis; } else { serverPanic("Unknown set encoding"); } } else if (ob->type == OBJ_ZSET) { if (ob->encoding == OBJ_ENCODING_ZIPLIST) { - if ((newzl = activeDefragAlloc(ptrFromObj(ob)))) + if ((newzl = (unsigned char*)activeDefragAlloc(ptrFromObj(ob)))) defragged++, ob->m_ptr = newzl; } else if (ob->encoding == OBJ_ENCODING_SKIPLIST) { defragged += defragZsetSkiplist(db, de); @@ -816,7 +816,7 @@ long defragKey(redisDb *db, dictEntry *de) { } } else if (ob->type == OBJ_HASH) { if (ob->encoding == OBJ_ENCODING_ZIPLIST) { - if ((newzl = activeDefragAlloc(ptrFromObj(ob)))) + if ((newzl = (unsigned char*)activeDefragAlloc(ptrFromObj(ob)))) defragged++, ob->m_ptr = newzl; } else if (ob->encoding == OBJ_ENCODING_HT) { defragged += defragHash(db, de); @@ -851,7 +851,7 @@ void defragDictBucketCallback(void *privdata, dictEntry **bucketref) { UNUSED(privdata); /* NOTE: this function is also used by both activeDefragCycle and scanLaterHash, etc. don't use privdata */ while(*bucketref) { dictEntry *de = *bucketref, *newde; - if ((newde = activeDefragAlloc(de))) { + if ((newde = (dictEntry*)activeDefragAlloc(de))) { *bucketref = newde; } bucketref = &(*bucketref)->next; @@ -896,7 +896,7 @@ long defragOtherGlobals() { * and 1 if time is up and more work is needed. */ int defragLaterItem(dictEntry *de, unsigned long *cursor, long long endtime) { if (de) { - robj *ob = dictGetVal(de); + robj *ob = (robj*)dictGetVal(de); if (ob->type == OBJ_LIST) { server.stat_active_defrag_hits += scanLaterList(ob); *cursor = 0; /* list has no scan, we must finish it in one go */ @@ -934,7 +934,7 @@ int defragLaterStep(redisDb *db, long long endtime) { /* Move on to next key */ if (current_key) { serverAssert(current_key == head->value); - sdsfree(head->value); + sdsfree((sds)head->value); listDelNode(db->defrag_later, head); cursor = 0; current_key = NULL; @@ -946,7 +946,7 @@ int defragLaterStep(redisDb *db, long long endtime) { return 0; /* start a new key */ - current_key = head->value; + current_key = (sds)head->value; cursor = 0; } diff --git a/src/dict.h b/src/dict.h index 4befb9b66..03c39c7ff 100644 --- a/src/dict.h +++ b/src/dict.h @@ -39,6 +39,10 @@ extern "C" { #endif +#ifndef __cplusplus +#error "C++ Only" +#endif + #ifndef __DICT_H #define __DICT_H diff --git a/src/evict.c b/src/evict.cpp similarity index 98% rename from src/evict.c rename to src/evict.cpp index f0bb94b7f..1affbe445 100644 --- a/src/evict.c +++ b/src/evict.cpp @@ -140,7 +140,7 @@ void evictionPoolAlloc(void) { struct evictionPoolEntry *ep; int j; - ep = zmalloc(sizeof(*ep)*EVPOOL_SIZE, MALLOC_LOCAL); + ep = (evictionPoolEntry*)zmalloc(sizeof(*ep)*EVPOOL_SIZE, MALLOC_LOCAL); for (j = 0; j < EVPOOL_SIZE; j++) { ep[j].idle = 0; ep[j].key = NULL; @@ -161,7 +161,7 @@ void evictionPoolAlloc(void) { void evictionPoolPopulate(int dbid, dict *sampledict, dict *keydict, struct evictionPoolEntry *pool) { int j, k, count; - dictEntry *samples[server.maxmemory_samples]; + dictEntry **samples = (dictEntry**)alloca(server.maxmemory_samples * sizeof(dictEntry*)); count = dictGetSomeKeys(sampledict,samples,server.maxmemory_samples); for (j = 0; j < count; j++) { @@ -171,14 +171,14 @@ void evictionPoolPopulate(int dbid, dict *sampledict, dict *keydict, struct evic dictEntry *de; de = samples[j]; - key = dictGetKey(de); + key = (sds)dictGetKey(de); /* If the dictionary we are sampling from is not the main * dictionary (but the expires one) we need to lookup the key * again in the key dictionary to obtain the value object. */ if (server.maxmemory_policy != MAXMEMORY_VOLATILE_TTL) { if (sampledict != keydict) de = dictFind(keydict, key); - o = dictGetVal(de); + o = (robj*)dictGetVal(de); } /* Calculate the idle time according to the policy. This is called @@ -360,7 +360,7 @@ size_t freeMemoryGetNotCountedMemory(void) { listRewind(server.slaves,&li); while((ln = listNext(&li))) { - client *slave = listNodeValue(ln); + client *slave = (client*)listNodeValue(ln); overhead += getClientOutputBufferMemoryUsage(slave); } } @@ -521,7 +521,7 @@ int freeMemoryIfNeeded(void) { /* If the key exists, is our pick. Otherwise it is * a ghost and we need to try the next element. */ if (de) { - bestkey = dictGetKey(de); + bestkey = (sds)dictGetKey(de); break; } else { /* Ghost... Iterate again. */ @@ -544,7 +544,7 @@ int freeMemoryIfNeeded(void) { db->pdict : db->expires; if (dictSize(dict) != 0) { de = dictGetRandomKey(dict); - bestkey = dictGetKey(de); + bestkey = (sds)dictGetKey(de); bestdbid = j; break; } diff --git a/src/expire.c b/src/expire.cpp similarity index 99% rename from src/expire.c rename to src/expire.cpp index 780968d54..7f5ab9a17 100644 --- a/src/expire.c +++ b/src/expire.cpp @@ -54,7 +54,7 @@ int activeExpireCycleTryExpire(redisDb *db, dictEntry *de, long long now) { long long t = dictGetSignedIntegerVal(de); if (now > t) { - sds key = dictGetKey(de); + sds key = (sds)dictGetKey(de); robj *keyobj = createStringObject(key,sdslen(key)); propagateExpire(db,keyobj,server.lazyfree_lazy_expire); @@ -290,7 +290,7 @@ void expireSlaveKeys(void) { mstime_t start = mstime(); while(1) { dictEntry *de = dictGetRandomKey(slaveKeysWithExpire); - sds keyname = dictGetKey(de); + sds keyname = (sds)dictGetKey(de); uint64_t dbids = dictGetUnsignedIntegerVal(de); uint64_t new_dbids = 0; @@ -361,7 +361,7 @@ void rememberSlaveKeyWithExpire(redisDb *db, robj *key) { * in sync with the main DB. The keys will be removed by expireSlaveKeys() * as it scans to find keys to remove. */ if (de->key == ptrFromObj(key)) { - de->key = sdsdup(ptrFromObj(key)); + de->key = sdsdup(szFromObj(key)); dictSetUnsignedIntegerVal(de,0); } diff --git a/src/geo.c b/src/geo.cpp similarity index 96% rename from src/geo.c rename to src/geo.cpp index 7fc52d68d..82e6e0101 100644 --- a/src/geo.c +++ b/src/geo.cpp @@ -51,7 +51,7 @@ int zslValueLteMax(double value, zrangespec *spec); /* Create a new array of geoPoints. */ geoArray *geoArrayCreate(void) { - geoArray *ga = zmalloc(sizeof(*ga), MALLOC_SHARED); + geoArray *ga = (geoArray*)zmalloc(sizeof(*ga), MALLOC_SHARED); /* It gets allocated on first geoArrayAppend() call. */ ga->array = NULL; ga->buckets = 0; @@ -64,7 +64,7 @@ geoArray *geoArrayCreate(void) { geoPoint *geoArrayAppend(geoArray *ga) { if (ga->used == ga->buckets) { ga->buckets = (ga->buckets == 0) ? 8 : ga->buckets*2; - ga->array = zrealloc(ga->array,sizeof(geoPoint)*ga->buckets, MALLOC_SHARED); + ga->array = (geoPoint*)zrealloc(ga->array,sizeof(geoPoint)*ga->buckets, MALLOC_SHARED); } geoPoint *gp = ga->array+ga->used; ga->used++; @@ -83,7 +83,7 @@ void geoArrayFree(geoArray *ga) { * Helpers * ==================================================================== */ int decodeGeohash(double bits, double *xy) { - GeoHashBits hash = { .bits = (uint64_t)bits, .step = GEO_STEP_MAX }; + GeoHashBits hash = { (uint64_t)bits, GEO_STEP_MAX }; return geohashDecodeToLongLatWGS84(hash, xy); } @@ -113,7 +113,7 @@ int extractLongLatOrReply(client *c, robj **argv, double *xy) { int longLatFromMember(robj *zobj, robj *member, double *xy) { double score = 0; - if (zsetScore(zobj, ptrFromObj(member), &score) == C_ERR) return C_ERR; + if (zsetScore(zobj, szFromObj(member), &score) == C_ERR) return C_ERR; if (!decodeGeohash(score, xy)) return C_ERR; return C_OK; } @@ -125,7 +125,7 @@ int longLatFromMember(robj *zobj, robj *member, double *xy) { * If the unit is not valid, an error is reported to the client, and a value * less than zero is returned. */ double extractUnitOrReply(client *c, robj *unit) { - char *u = ptrFromObj(unit); + char *u = szFromObj(unit); if (!strcmp(u, "m")) { return 1; @@ -225,12 +225,12 @@ int geoAppendIfWithinRadius(geoArray *ga, double lon, double lat, double radius, int geoGetPointsInRange(robj *zobj, double min, double max, double lon, double lat, double radius, geoArray *ga) { /* minex 0 = include min in range; maxex 1 = exclude max in range */ /* That's: min <= val < max */ - zrangespec range = { .min = min, .max = max, .minex = 0, .maxex = 1 }; + zrangespec range = { min, max, 0, 1 }; size_t origincount = ga->used; sds member; if (zobj->encoding == OBJ_ENCODING_ZIPLIST) { - unsigned char *zl = zobj->m_ptr; + unsigned char *zl = (unsigned char*)zobj->m_ptr; unsigned char *eptr, *sptr; unsigned char *vstr = NULL; unsigned int vlen = 0; @@ -259,7 +259,7 @@ int geoGetPointsInRange(robj *zobj, double min, double max, double lon, double l zzlNext(zl, &eptr, &sptr); } } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zobj->m_ptr; + zset *zs = (zset*)zobj->m_ptr; zskiplist *zsl = zs->zsl; zskiplistNode *ln; @@ -277,7 +277,7 @@ int geoGetPointsInRange(robj *zobj, double min, double max, double lon, double l ele = sdsdup(ele); if (geoAppendIfWithinRadius(ga,lon,lat,radius,ln->score,ele) == C_ERR) sdsfree(ele); - ln = ln->level[0].forward; + ln = ln->level(0)->forward; } } return ga->used - origincount; @@ -382,7 +382,7 @@ int membersOfAllNeighbors(robj *zobj, GeoHashRadius n, double lon, double lat, d /* Sort comparators for qsort() */ static int sort_gp_asc(const void *a, const void *b) { - const struct geoPoint *gpa = a, *gpb = b; + const struct geoPoint *gpa = (geoPoint*)a, *gpb = (geoPoint*)b; /* We can't do adist - bdist because they are doubles and * the comparator returns an int. */ if (gpa->dist > gpb->dist) @@ -413,7 +413,7 @@ void geoaddCommand(client *c) { int elements = (c->argc - 2) / 3; int argc = 2+elements*2; /* ZADD key score ele ... */ - robj **argv = zcalloc(argc*sizeof(robj*), MALLOC_LOCAL); + robj **argv = (robj**)zcalloc(argc*sizeof(robj*), MALLOC_LOCAL); argv[0] = createRawStringObject("zadd",4); argv[1] = c->argv[1]; /* key */ incrRefCount(argv[1]); @@ -504,7 +504,7 @@ void georadiusGeneric(client *c, int flags) { if (c->argc > base_args) { int remaining = c->argc - base_args; for (int i = 0; i < remaining; i++) { - char *arg = ptrFromObj(c->argv[base_args + i]); + char *arg = szFromObj(c->argv[base_args + i]); if (!strcasecmp(arg, "withdist")) { withdist = 1; } else if (!strcasecmp(arg, "withhash")) { @@ -639,7 +639,7 @@ void georadiusGeneric(client *c, int flags) { if (returned_items) { zobj = createZsetObject(); - zs = zobj->m_ptr; + zs = (zset*)zobj->m_ptr; } for (i = 0; i < returned_items; i++) { @@ -697,7 +697,7 @@ void georadiusbymemberroCommand(client *c) { * Returns an array with an 11 characters geohash representation of the * position of the specified elements. */ void geohashCommand(client *c) { - char *geoalphabet= "0123456789bcdefghjkmnpqrstuvwxyz"; + const char *geoalphabet= "0123456789bcdefghjkmnpqrstuvwxyz"; int j; /* Look up the requested zset */ @@ -709,7 +709,7 @@ void geohashCommand(client *c) { addReplyArrayLen(c,c->argc-2); for (j = 2; j < c->argc; j++) { double score; - if (!zobj || zsetScore(zobj, ptrFromObj(c->argv[j]), &score) == C_ERR) { + if (!zobj || zsetScore(zobj, szFromObj(c->argv[j]), &score) == C_ERR) { addReplyNull(c); } else { /* The internal format we use for geocoding is a bit different @@ -762,7 +762,7 @@ void geoposCommand(client *c) { addReplyArrayLen(c,c->argc-2); for (j = 2; j < c->argc; j++) { double score; - if (!zobj || zsetScore(zobj, ptrFromObj(c->argv[j]), &score) == C_ERR) { + if (!zobj || zsetScore(zobj, szFromObj(c->argv[j]), &score) == C_ERR) { addReplyNullArray(c); } else { /* Decode... */ @@ -802,8 +802,8 @@ void geodistCommand(client *c) { /* Get the scores. We need both otherwise NULL is returned. */ double score1, score2, xyxy[4]; - if (zsetScore(zobj, ptrFromObj(c->argv[2]), &score1) == C_ERR || - zsetScore(zobj, ptrFromObj(c->argv[3]), &score2) == C_ERR) + if (zsetScore(zobj, szFromObj(c->argv[2]), &score1) == C_ERR || + zsetScore(zobj, szFromObj(c->argv[3]), &score2) == C_ERR) { addReplyNull(c); return; diff --git a/src/geohash_helper.c b/src/geohash_helper.cpp similarity index 100% rename from src/geohash_helper.c rename to src/geohash_helper.cpp diff --git a/src/gopher.c b/src/gopher.c deleted file mode 100644 index 38e44f754..000000000 --- a/src/gopher.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2019, Salvatore Sanfilippo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "server.h" - -/* Emit an item in Gopher directory listing format: - * - * If descr or selector are NULL, then the "(NULL)" string is used instead. */ -void addReplyGopherItem(client *c, const char *type, const char *descr, - const char *selector, const char *hostname, int port) -{ - sds item = sdscatfmt(sdsempty(),"%s%s\t%s\t%s\t%i\r\n", - type, descr, - selector ? selector : "(NULL)", - hostname ? hostname : "(NULL)", - port); - addReplyProto(c,item,sdslen(item)); - sdsfree(item); -} - -/* This is called by processInputBuffer() when an inline request is processed - * with Gopher mode enabled, and the request happens to have zero or just one - * argument. In such case we get the relevant key and reply using the Gopher - * protocol. */ -void processGopherRequest(client *c) { - robj *keyname = c->argc == 0 ? createStringObject("/",1) : c->argv[0]; - robj *o = lookupKeyRead(c->db,keyname); - - /* If there is no such key, return with a Gopher error. */ - if (o == NULL || o->type != OBJ_STRING) { - char *errstr; - if (o == NULL) - errstr = "Error: no content at the specified key"; - else - errstr = "Error: selected key type is invalid " - "for Gopher output"; - addReplyGopherItem(c,"i",errstr,NULL,NULL,0); - addReplyGopherItem(c,"i","Redis Gopher server",NULL,NULL,0); - } else { - addReply(c,o); - } - - /* Cleanup, also make sure to emit the final ".CRLF" line. Note that - * the connection will be closed immediately after this because the client - * will be flagged with CLIENT_CLOSE_AFTER_REPLY, in accordance with the - * Gopher protocol. */ - if (c->argc == 0) decrRefCount(keyname); - - /* Note that in theory we should terminate the Gopher request with - * "." (called Lastline in the RFC) like that: - * - * addReplyProto(c,".\r\n",3); - * - * However after examining the current clients landscape, it's probably - * going to do more harm than good for several reasons: - * - * 1. Clients should not have any issue with missing . as for - * specification, and in the real world indeed certain servers - * implementations never used to send the terminator. - * - * 2. Redis does not know if it's serving a text file or a binary file: - * at the same time clients will not remove the "." bytes at - * tne end when downloading a binary file from the server, so adding - * the "Lastline" terminator without knowing the content is just - * dangerous. - * - * 3. The utility gopher2redis.rb that we provide for Redis, and any - * other similar tool you may use as Gopher authoring system for - * Redis, can just add the "Lastline" when needed. - */ -} diff --git a/src/hyperloglog.c b/src/hyperloglog.cpp similarity index 95% rename from src/hyperloglog.c rename to src/hyperloglog.cpp index 6d1a05754..c576246cf 100644 --- a/src/hyperloglog.c +++ b/src/hyperloglog.cpp @@ -184,7 +184,9 @@ struct hllhdr { uint8_t encoding; /* HLL_DENSE or HLL_SPARSE. */ uint8_t notused[3]; /* Reserved for future use, must be zero. */ uint8_t card[8]; /* Cached cardinality, little endian. */ - uint8_t registers[]; /* Data bytes. */ + uint8_t *registers() { /* Data bytes. */ + return reinterpret_cast(this+1); + } }; /* The cached cardinality MSB is used to signal validity of the cached value. */ @@ -205,7 +207,7 @@ struct hllhdr { #define HLL_RAW 255 /* Only used internally, never exposed. */ #define HLL_MAX_ENCODING 1 -static char *invalid_hll_err = "-INVALIDOBJ Corrupted HLL object detected\r\n"; +static const char *invalid_hll_err = "-INVALIDOBJ Corrupted HLL object detected\r\n"; /* =========================== Low level bit macros ========================= */ @@ -582,7 +584,7 @@ void hllDenseRegHisto(uint8_t *registers, int* reghisto) { * The function returns C_OK if the sparse representation was valid, * otherwise C_ERR is returned if the representation was corrupted. */ int hllSparseToDense(robj *o) { - sds sparse = ptrFromObj(o), dense; + sds sparse = szFromObj(o), dense; struct hllhdr *hdr, *oldhdr = (struct hllhdr*)sparse; int idx = 0, runlen, regval; uint8_t *p = (uint8_t*)sparse, *end = p+sdslen(sparse); @@ -616,7 +618,7 @@ int hllSparseToDense(robj *o) { regval = HLL_SPARSE_VAL_VALUE(p); if ((runlen + idx) > HLL_REGISTERS) break; /* Overflow. */ while(runlen--) { - HLL_DENSE_SET_REGISTER(hdr->registers,idx,regval); + HLL_DENSE_SET_REGISTER(hdr->registers(),idx,regval); idx++; } p++; @@ -631,7 +633,7 @@ int hllSparseToDense(robj *o) { } /* Free the old representation and set the new one. */ - sdsfree(ptrFromObj(o)); + sdsfree(szFromObj(o)); o->m_ptr = dense; return C_OK; } @@ -656,6 +658,13 @@ int hllSparseSet(robj *o, long index, uint8_t count) { uint8_t oldcount, *sparse, *end, *p, *prev, *next; long first, span; long is_zero = 0, is_xzero = 0, is_val = 0, runlen = 0; + uint8_t seq[5], *n = nullptr; + int last; + int len; + int seqlen = 0; + int oldlen = 0; + int deltalen = 0; + int scanlen = 0; /* If the count is too big to be representable by the sparse representation * switch to dense representation. */ @@ -666,12 +675,12 @@ int hllSparseSet(robj *o, long index, uint8_t count) { * into XZERO-VAL-XZERO). Make sure there is enough space right now * so that the pointers we take during the execution of the function * will be valid all the time. */ - o->m_ptr = sdsMakeRoomFor(ptrFromObj(o),3); + o->m_ptr = sdsMakeRoomFor(szFromObj(o),3); /* Step 1: we need to locate the opcode we need to modify to check * if a value update is actually needed. */ sparse = p = ((uint8_t*)ptrFromObj(o)) + HLL_HDR_SIZE; - end = p + sdslen(ptrFromObj(o)) - HLL_HDR_SIZE; + end = p + sdslen(szFromObj(o)) - HLL_HDR_SIZE; first = 0; prev = NULL; /* Points to previous opcode at the end of the loop. */ @@ -774,9 +783,8 @@ int hllSparseSet(robj *o, long index, uint8_t count) { * with 'newlen' as length. Later the new sequence is inserted in place * of the old one, possibly moving what is on the right a few bytes * if the new sequence is longer than the older one. */ - uint8_t seq[5], *n = seq; - int last = first+span-1; /* Last register covered by the sequence. */ - int len; + n = seq; + last = first+span-1; /* Last register covered by the sequence. */ if (is_zero || is_xzero) { /* Handle splitting of ZERO / XZERO. */ @@ -824,14 +832,14 @@ int hllSparseSet(robj *o, long index, uint8_t count) { * * Note that we already allocated space on the sds string * calling sdsMakeRoomFor(). */ - int seqlen = n-seq; - int oldlen = is_xzero ? 2 : 1; - int deltalen = seqlen-oldlen; + seqlen = n-seq; + oldlen = is_xzero ? 2 : 1; + deltalen = seqlen-oldlen; if (deltalen > 0 && - sdslen(ptrFromObj(o))+deltalen > server.hll_sparse_max_bytes) goto promote; + sdslen(szFromObj(o))+deltalen > server.hll_sparse_max_bytes) goto promote; if (deltalen && next) memmove(next+deltalen,next,end-next); - sdsIncrLen(ptrFromObj(o),deltalen); + sdsIncrLen(szFromObj(o),deltalen); memcpy(p,seq,seqlen); end += deltalen; @@ -842,7 +850,7 @@ updated: * may not be optimal: adjacent VAL opcodes can sometimes be merged into * a single one. */ p = prev ? prev : sparse; - int scanlen = 5; /* Scan up to 5 upcodes starting from prev. */ + scanlen = 5; /* Scan up to 5 upcodes starting from prev. */ while (p < end && scanlen--) { if (HLL_SPARSE_IS_XZERO(p)) { p += 2; @@ -861,7 +869,7 @@ updated: if (len <= HLL_SPARSE_VAL_MAX_LEN) { HLL_SPARSE_VAL_SET(p+1,v1,len); memmove(p,p+1,end-p); - sdsIncrLen(ptrFromObj(o),-1); + sdsIncrLen(szFromObj(o),-1); end--; /* After a merge we reiterate without incrementing 'p' * in order to try to merge the just merged value with @@ -874,13 +882,13 @@ updated: } /* Invalidate the cached cardinality. */ - hdr = ptrFromObj(o); + hdr = (hllhdr*)ptrFromObj(o); HLL_INVALIDATE_CACHE(hdr); return 1; promote: /* Promote to dense representation. */ if (hllSparseToDense(o) == C_ERR) return -1; /* Corrupted HLL. */ - hdr = ptrFromObj(o); + hdr = (hllhdr*)ptrFromObj(o); /* We need to call hllDenseAdd() to perform the operation after the * conversion. However the result must be 1, since if we need to @@ -889,7 +897,7 @@ promote: /* Promote to dense representation. */ * Note that this in turn means that PFADD will make sure the command * is propagated to slaves / AOF, so if there is a sparse -> dense * conversion, it will be performed in all the slaves as well. */ - int dense_retval = hllDenseSet(hdr->registers,index,count); + int dense_retval = hllDenseSet(hdr->registers(),index,count); serverAssert(dense_retval == 1); return dense_retval; } @@ -1007,7 +1015,7 @@ double hllTau(double x) { * pointed by 'invalid' is set to non-zero, otherwise it is left untouched. * * hllCount() supports a special internal-only encoding of HLL_RAW, that - * is, hdr->registers will point to an uint8_t array of HLL_REGISTERS element. + * is, hdr->registers() will point to an uint8_t array of HLL_REGISTERS element. * This is useful in order to speedup PFCOUNT when called against multiple * keys (no need to work with 6-bit integers encoding). */ uint64_t hllCount(struct hllhdr *hdr, int *invalid) { @@ -1023,12 +1031,12 @@ uint64_t hllCount(struct hllhdr *hdr, int *invalid) { /* Compute register histogram */ if (hdr->encoding == HLL_DENSE) { - hllDenseRegHisto(hdr->registers,reghisto); + hllDenseRegHisto(hdr->registers(),reghisto); } else if (hdr->encoding == HLL_SPARSE) { - hllSparseRegHisto(hdr->registers, + hllSparseRegHisto(hdr->registers(), sdslen((sds)hdr)-HLL_HDR_SIZE,invalid,reghisto); } else if (hdr->encoding == HLL_RAW) { - hllRawRegHisto(hdr->registers,reghisto); + hllRawRegHisto(hdr->registers(),reghisto); } else { serverPanic("Unknown HyperLogLog encoding in hllCount()"); } @@ -1049,9 +1057,9 @@ uint64_t hllCount(struct hllhdr *hdr, int *invalid) { /* Call hllDenseAdd() or hllSparseAdd() according to the HLL encoding. */ int hllAdd(robj *o, unsigned char *ele, size_t elesize) { - struct hllhdr *hdr = ptrFromObj(o); + struct hllhdr *hdr = (hllhdr*)ptrFromObj(o); switch(hdr->encoding) { - case HLL_DENSE: return hllDenseAdd(hdr->registers,ele,elesize); + case HLL_DENSE: return hllDenseAdd(hdr->registers(),ele,elesize); case HLL_SPARSE: return hllSparseAdd(o,ele,elesize); default: return -1; /* Invalid representation. */ } @@ -1066,18 +1074,18 @@ int hllAdd(robj *o, unsigned char *ele, size_t elesize) { * If the HyperLogLog is sparse and is found to be invalid, C_ERR * is returned, otherwise the function always succeeds. */ int hllMerge(uint8_t *max, size_t cmax, robj *hll) { - struct hllhdr *hdr = ptrFromObj(hll); + struct hllhdr *hdr = (hllhdr*)ptrFromObj(hll); int i; if (hdr->encoding == HLL_DENSE) { uint8_t val; for (i = 0; i < HLL_REGISTERS; i++) { - HLL_DENSE_GET_REGISTER(val,hdr->registers,i); + HLL_DENSE_GET_REGISTER(val,hdr->registers(),i); if (val > max[i]) max[i] = val; } } else { - uint8_t *p = ptrFromObj(hll), *end = p + sdslen(ptrFromObj(hll)); + uint8_t *p = (uint8_t*)ptrFromObj(hll), *end = p + sdslen(szFromObj(hll)); long runlen, regval; p += HLL_HDR_SIZE; @@ -1139,7 +1147,7 @@ robj *createHLLObject(void) { /* Create the actual object. */ o = createObject(OBJ_STRING,s); - hdr = ptrFromObj(o); + hdr = (hllhdr*)ptrFromObj(o); memcpy(hdr->magic,"HYLL",4); hdr->encoding = HLL_SPARSE; return o; @@ -1157,7 +1165,7 @@ int isHLLObjectOrReply(client *c, robj *o) { if (!sdsEncodedObject(o)) goto invalid; if (stringObjectLen(o) < sizeof(*hdr)) goto invalid; - hdr = ptrFromObj(o); + hdr = (hllhdr*)ptrFromObj(o); /* Magic should be "HYLL". */ if (hdr->magic[0] != 'H' || hdr->magic[1] != 'Y' || @@ -1199,7 +1207,7 @@ void pfaddCommand(client *c) { /* Perform the low level ADD operation for every element. */ for (j = 2; j < c->argc; j++) { int retval = hllAdd(o, (unsigned char*)ptrFromObj(c->argv[j]), - sdslen(ptrFromObj(c->argv[j]))); + sdslen(szFromObj(c->argv[j]))); switch(retval) { case 1: updated++; @@ -1209,7 +1217,7 @@ void pfaddCommand(client *c) { return; } } - hdr = ptrFromObj(o); + hdr = (hllhdr*)ptrFromObj(o); if (updated) { signalModifiedKey(c->db,c->argv[1]); notifyKeyspaceEvent(NOTIFY_STRING,"pfadd",c->argv[1],c->db->id); @@ -1271,7 +1279,7 @@ void pfcountCommand(client *c) { o = dbUnshareStringValue(c->db,c->argv[1],o); /* Check if the cached cardinality is valid. */ - hdr = ptrFromObj(o); + hdr = (hllhdr*)ptrFromObj(o); if (HLL_VALID_CACHE(hdr)) { /* Just return the cached value. */ card = (uint64_t)hdr->card[0]; @@ -1328,7 +1336,7 @@ void pfmergeCommand(client *c) { /* If at least one involved HLL is dense, use the dense representation * as target ASAP to save time and avoid the conversion step. */ - hdr = ptrFromObj(o); + hdr = (hllhdr*)ptrFromObj(o); if (hdr->encoding == HLL_DENSE) use_dense = 1; /* Merge with this HLL with our 'max' HHL by setting max[i] @@ -1365,13 +1373,13 @@ void pfmergeCommand(client *c) { * invalidate the cached value. */ for (j = 0; j < HLL_REGISTERS; j++) { if (max[j] == 0) continue; - hdr = ptrFromObj(o); + hdr = (hllhdr*)ptrFromObj(o); switch(hdr->encoding) { - case HLL_DENSE: hllDenseSet(hdr->registers,j,max[j]); break; + case HLL_DENSE: hllDenseSet(hdr->registers(),j,max[j]); break; case HLL_SPARSE: hllSparseSet(o,j,max[j]); break; } } - hdr = ptrFromObj(o); /* ptrFromObj(o) may be different now, as a side effect of + hdr = (hllhdr*)ptrFromObj(o); /* ptrFromObj(o) may be different now, as a side effect of last hllSparseSet() call. */ HLL_INVALIDATE_CACHE(hdr); @@ -1395,6 +1403,10 @@ void pfselftestCommand(client *c) { struct hllhdr *hdr = (struct hllhdr*) bitcounters, *hdr2; robj *o = NULL; uint8_t bytecounters[HLL_REGISTERS]; + int64_t checkpoint = 1; + uint64_t seed = 0; + uint64_t ele; + double relerr = 0; /* Test 1: access registers. * The test is conceived to test that the different counters of our data @@ -1407,13 +1419,13 @@ void pfselftestCommand(client *c) { unsigned int r = rand() & HLL_REGISTER_MAX; bytecounters[i] = r; - HLL_DENSE_SET_REGISTER(hdr->registers,i,r); + HLL_DENSE_SET_REGISTER(hdr->registers(),i,r); } /* Check that we are able to retrieve the same values. */ for (i = 0; i < HLL_REGISTERS; i++) { unsigned int val; - HLL_DENSE_GET_REGISTER(val,hdr->registers,i); + HLL_DENSE_GET_REGISTER(val,hdr->registers(),i); if (val != bytecounters[i]) { addReplyErrorFormat(c, "TESTFAILED Register %d should be %d but is %d", @@ -1433,21 +1445,20 @@ void pfselftestCommand(client *c) { * * The test is performed with both dense and sparse HLLs at the same * time also verifying that the computed cardinality is the same. */ - memset(hdr->registers,0,HLL_DENSE_SIZE-HLL_HDR_SIZE); + memset(hdr->registers(),0,HLL_DENSE_SIZE-HLL_HDR_SIZE); o = createHLLObject(); - double relerr = 1.04/sqrt(HLL_REGISTERS); - int64_t checkpoint = 1; - uint64_t seed = (uint64_t)rand() | (uint64_t)rand() << 32; - uint64_t ele; + relerr = 1.04/sqrt(HLL_REGISTERS); + checkpoint = 1; + seed = (uint64_t)rand() | (uint64_t)rand() << 32; for (j = 1; j <= 10000000; j++) { ele = j ^ seed; - hllDenseAdd(hdr->registers,(unsigned char*)&ele,sizeof(ele)); + hllDenseAdd(hdr->registers(),(unsigned char*)&ele,sizeof(ele)); hllAdd(o,(unsigned char*)&ele,sizeof(ele)); /* Make sure that for small cardinalities we use sparse * encoding. */ if (j == checkpoint && j < server.hll_sparse_max_bytes/2) { - hdr2 = ptrFromObj(o); + hdr2 = (hllhdr*)ptrFromObj(o); if (hdr2->encoding != HLL_SPARSE) { addReplyError(c, "TESTFAILED sparse encoding not used"); goto cleanup; @@ -1455,7 +1466,7 @@ void pfselftestCommand(client *c) { } /* Check that dense and sparse representations agree. */ - if (j == checkpoint && hllCount(hdr,NULL) != hllCount(ptrFromObj(o),NULL)) { + if (j == checkpoint && hllCount(hdr,NULL) != hllCount((hllhdr*)ptrFromObj(o),NULL)) { addReplyError(c, "TESTFAILED dense/sparse disagree"); goto cleanup; } @@ -1494,7 +1505,7 @@ cleanup: /* PFDEBUG ... args ... * Different debugging related operations about the HLL implementation. */ void pfdebugCommand(client *c) { - char *cmd = ptrFromObj(c->argv[1]); + char *cmd = szFromObj(c->argv[1]); struct hllhdr *hdr; robj *o; int j; @@ -1506,7 +1517,7 @@ void pfdebugCommand(client *c) { } if (isHLLObjectOrReply(c,o) != C_OK) return; o = dbUnshareStringValue(c->db,c->argv[2],o); - hdr = ptrFromObj(o); + hdr = (hllhdr*)ptrFromObj(o); /* PFDEBUG GETREG */ if (!strcasecmp(cmd,"getreg")) { @@ -1520,12 +1531,12 @@ void pfdebugCommand(client *c) { server.dirty++; /* Force propagation on encoding change. */ } - hdr = ptrFromObj(o); + hdr = (hllhdr*)ptrFromObj(o); addReplyArrayLen(c,HLL_REGISTERS); for (j = 0; j < HLL_REGISTERS; j++) { uint8_t val; - HLL_DENSE_GET_REGISTER(val,hdr->registers,j); + HLL_DENSE_GET_REGISTER(val,hdr->registers(),j); addReplyLongLong(c,val); } } @@ -1533,7 +1544,7 @@ void pfdebugCommand(client *c) { else if (!strcasecmp(cmd,"decode")) { if (c->argc != 3) goto arityerr; - uint8_t *p = ptrFromObj(o), *end = p+sdslen(ptrFromObj(o)); + uint8_t *p = (uint8_t*)ptrFromObj(o), *end = p+sdslen(szFromObj(o)); sds decoded = sdsempty(); if (hdr->encoding != HLL_SPARSE) { @@ -1566,7 +1577,7 @@ void pfdebugCommand(client *c) { } /* PFDEBUG ENCODING */ else if (!strcasecmp(cmd,"encoding")) { - char *encodingstr[2] = {"dense","sparse"}; + const char *encodingstr[2] = {"dense","sparse"}; if (c->argc != 3) goto arityerr; addReplyStatus(c,encodingstr[hdr->encoding]); diff --git a/src/latency.c b/src/latency.cpp similarity index 94% rename from src/latency.c rename to src/latency.cpp index f1e920484..cfa0f496d 100644 --- a/src/latency.c +++ b/src/latency.cpp @@ -38,11 +38,11 @@ /* Dictionary type for latency events. */ int dictStringKeyCompare(void *privdata, const void *key1, const void *key2) { UNUSED(privdata); - return strcmp(key1,key2) == 0; + return strcmp((const char*)key1,(const char*)key2) == 0; } uint64_t dictStringHash(const void *key) { - return dictGenHashFunction(key, strlen(key)); + return dictGenHashFunction(key, strlen((const char*)key)); } void dictVanillaFree(void *privdata, void *val); @@ -96,13 +96,13 @@ void latencyMonitorInit(void) { * is a macro that only adds the sample if the latency is higher than * server.latency_monitor_threshold. */ void latencyAddSample(const char *event, mstime_t latency) { - struct latencyTimeSeries *ts = dictFetchValue(server.latency_events,event); + struct latencyTimeSeries *ts = (latencyTimeSeries*)dictFetchValue(server.latency_events,event); time_t now = time(NULL); int prev; /* Create the time series if it does not exist. */ if (ts == NULL) { - ts = zmalloc(sizeof(*ts), MALLOC_SHARED); + ts = (latencyTimeSeries*)zmalloc(sizeof(*ts), MALLOC_SHARED); ts->idx = 0; ts->max = 0; memset(ts->samples,0,sizeof(ts->samples)); @@ -139,7 +139,7 @@ int latencyResetEvent(char *event_to_reset) { di = dictGetSafeIterator(server.latency_events); while((de = dictNext(di)) != NULL) { - char *event = dictGetKey(de); + char *event = (char*)dictGetKey(de); if (event_to_reset == NULL || strcasecmp(event,event_to_reset) == 0) { dictDelete(server.latency_events, event); @@ -158,7 +158,7 @@ int latencyResetEvent(char *event_to_reset) { * If the specified event has no elements the structure is populate with * zero values. */ void analyzeLatencyForEvent(char *event, struct latencyStats *ls) { - struct latencyTimeSeries *ts = dictFetchValue(server.latency_events,event); + struct latencyTimeSeries *ts = (latencyTimeSeries*)dictFetchValue(server.latency_events,event); int j; uint64_t sum; @@ -251,8 +251,8 @@ sds createLatencyReport(void) { di = dictGetSafeIterator(server.latency_events); while((de = dictNext(di)) != NULL) { - char *event = dictGetKey(de); - struct latencyTimeSeries *ts = dictGetVal(de); + char *event = (char*)dictGetKey(de); + struct latencyTimeSeries *ts = (latencyTimeSeries*)dictGetVal(de); struct latencyStats ls; if (ts == NULL) continue; @@ -273,7 +273,7 @@ sds createLatencyReport(void) { /* Fork */ if (!strcasecmp(event,"fork")) { - char *fork_quality; + const char *fork_quality; if (server.stat_fork_rate < 10) { fork_quality = "terrible"; advise_better_vm = 1; @@ -500,8 +500,8 @@ void latencyCommandReplyWithLatestEvents(client *c) { addReplyArrayLen(c,dictSize(server.latency_events)); di = dictGetIterator(server.latency_events); while((de = dictNext(di)) != NULL) { - char *event = dictGetKey(de); - struct latencyTimeSeries *ts = dictGetVal(de); + char *event = (char*)dictGetKey(de); + struct latencyTimeSeries *ts = (latencyTimeSeries*)dictGetVal(de); int last = (ts->idx + LATENCY_TS_LEN - 1) % LATENCY_TS_LEN; addReplyArrayLen(c,4); @@ -579,15 +579,15 @@ NULL }; struct latencyTimeSeries *ts; - if (!strcasecmp(ptrFromObj(c->argv[1]),"history") && c->argc == 3) { + if (!strcasecmp(szFromObj(c->argv[1]),"history") && c->argc == 3) { /* LATENCY HISTORY */ - ts = dictFetchValue(server.latency_events,ptrFromObj(c->argv[2])); + ts = (latencyTimeSeries*)dictFetchValue(server.latency_events,ptrFromObj(c->argv[2])); if (ts == NULL) { addReplyArrayLen(c,0); } else { latencyCommandReplyWithSamples(c,ts); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"graph") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"graph") && c->argc == 3) { /* LATENCY GRAPH */ sds graph; dictEntry *de; @@ -595,22 +595,22 @@ NULL de = dictFind(server.latency_events,ptrFromObj(c->argv[2])); if (de == NULL) goto nodataerr; - ts = dictGetVal(de); - event = dictGetKey(de); + ts = (latencyTimeSeries*)dictGetVal(de); + event = (char*)dictGetKey(de); graph = latencyCommandGenSparkeline(event,ts); addReplyBulkCString(c,graph); sdsfree(graph); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"latest") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"latest") && c->argc == 2) { /* LATENCY LATEST */ latencyCommandReplyWithLatestEvents(c); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"doctor") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"doctor") && c->argc == 2) { /* LATENCY DOCTOR */ sds report = createLatencyReport(); addReplyBulkCBuffer(c,report,sdslen(report)); sdsfree(report); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"reset") && c->argc >= 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"reset") && c->argc >= 2) { /* LATENCY RESET */ if (c->argc == 2) { addReplyLongLong(c,latencyResetEvent(NULL)); @@ -618,10 +618,10 @@ NULL int j, resets = 0; for (j = 2; j < c->argc; j++) - resets += latencyResetEvent(ptrFromObj(c->argv[j])); + resets += latencyResetEvent(szFromObj(c->argv[j])); addReplyLongLong(c,resets); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"help") && c->argc >= 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"help") && c->argc >= 2) { addReplyHelp(c, help); } else { addReplySubcommandSyntaxError(c); diff --git a/src/lazyfree.c b/src/lazyfree.cpp similarity index 96% rename from src/lazyfree.c rename to src/lazyfree.cpp index 6ea21768e..7f6d9220d 100644 --- a/src/lazyfree.c +++ b/src/lazyfree.cpp @@ -30,16 +30,16 @@ size_t lazyfreeGetPendingObjectsCount(void) { * representing the list. */ size_t lazyfreeGetFreeEffort(robj *obj) { if (obj->type == OBJ_LIST) { - quicklist *ql = ptrFromObj(obj); + quicklist *ql = (quicklist*)ptrFromObj(obj); return ql->len; } else if (obj->type == OBJ_SET && obj->encoding == OBJ_ENCODING_HT) { - dict *ht = ptrFromObj(obj); + dict *ht = (dict*)ptrFromObj(obj); return dictSize(ht); } else if (obj->type == OBJ_ZSET && obj->encoding == OBJ_ENCODING_SKIPLIST){ - zset *zs = ptrFromObj(obj); + zset *zs = (zset*)ptrFromObj(obj); return zs->zsl->length; } else if (obj->type == OBJ_HASH && obj->encoding == OBJ_ENCODING_HT) { - dict *ht = ptrFromObj(obj); + dict *ht = (dict*)ptrFromObj(obj); return dictSize(ht); } else { return 1; /* Everything else is a single allocation. */ @@ -61,7 +61,7 @@ int dbAsyncDelete(redisDb *db, robj *key) { * the object synchronously. */ dictEntry *de = dictUnlink(db->pdict,ptrFromObj(key)); if (de) { - robj *val = dictGetVal(de); + robj *val = (robj*)dictGetVal(de); size_t free_effort = lazyfreeGetFreeEffort(val); /* If releasing the object is too much work, do it in the background diff --git a/src/lolwut.c b/src/lolwut.c deleted file mode 100644 index 19cbcf642..000000000 --- a/src/lolwut.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2018, Salvatore Sanfilippo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * ---------------------------------------------------------------------------- - * - * This file implements the LOLWUT command. The command should do something - * fun and interesting, and should be replaced by a new implementation at - * each new version of Redis. - */ - -#include "server.h" - -void lolwut5Command(client *c); - -/* The default target for LOLWUT if no matching version was found. - * This is what unstable versions of Redis will display. */ -void lolwutUnstableCommand(client *c) { - sds rendered = sdsnew("Redis ver. "); - rendered = sdscat(rendered,REDIS_VERSION); - rendered = sdscatlen(rendered,"\n",1); - addReplyBulkSds(c,rendered); -} - -void lolwutCommand(client *c) { - char *v = REDIS_VERSION; - if ((v[0] == '5' && v[1] == '.') || - (v[0] == '4' && v[1] == '.' && v[2] == '9')) - lolwut5Command(c); - else - lolwutUnstableCommand(c); -} diff --git a/src/lolwut5.c b/src/lolwut5.c deleted file mode 100644 index b247cfb13..000000000 --- a/src/lolwut5.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * Copyright (c) 2018, Salvatore Sanfilippo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * ---------------------------------------------------------------------------- - * - * This file implements the LOLWUT command. The command should do something - * fun and interesting, and should be replaced by a new implementation at - * each new version of Redis. - */ - -#include "server.h" -#include - -/* This structure represents our canvas. Drawing functions will take a pointer - * to a canvas to write to it. Later the canvas can be rendered to a string - * suitable to be printed on the screen, using unicode Braille characters. */ -typedef struct lwCanvas { - int width; - int height; - char *pixels; -} lwCanvas; - -/* Translate a group of 8 pixels (2x4 vertical rectangle) to the corresponding - * braille character. The byte should correspond to the pixels arranged as - * follows, where 0 is the least significant bit, and 7 the most significant - * bit: - * - * 0 3 - * 1 4 - * 2 5 - * 6 7 - * - * The corresponding utf8 encoded character is set into the three bytes - * pointed by 'output'. - */ -#include -void lwTranslatePixelsGroup(int byte, char *output) { - int code = 0x2800 + byte; - /* Convert to unicode. This is in the U0800-UFFFF range, so we need to - * emit it like this in three bytes: - * 1110xxxx 10xxxxxx 10xxxxxx. */ - output[0] = 0xE0 | (code >> 12); /* 1110-xxxx */ - output[1] = 0x80 | ((code >> 6) & 0x3F); /* 10-xxxxxx */ - output[2] = 0x80 | (code & 0x3F); /* 10-xxxxxx */ -} - -/* Allocate and return a new canvas of the specified size. */ -lwCanvas *lwCreateCanvas(int width, int height) { - lwCanvas *canvas = zmalloc(sizeof(*canvas), MALLOC_SHARED); - canvas->width = width; - canvas->height = height; - canvas->pixels = zmalloc(width*height, MALLOC_SHARED); - memset(canvas->pixels,0,width*height); - return canvas; -} - -/* Free the canvas created by lwCreateCanvas(). */ -void lwFreeCanvas(lwCanvas *canvas) { - zfree(canvas->pixels); - zfree(canvas); -} - -/* Set a pixel to the specified color. Color is 0 or 1, where zero means no - * dot will be displyed, and 1 means dot will be displayed. - * Coordinates are arranged so that left-top corner is 0,0. You can write - * out of the size of the canvas without issues. */ -void lwDrawPixel(lwCanvas *canvas, int x, int y, int color) { - if (x < 0 || x >= canvas->width || - y < 0 || y >= canvas->height) return; - canvas->pixels[x+y*canvas->width] = color; -} - -/* Return the value of the specified pixel on the canvas. */ -int lwGetPixel(lwCanvas *canvas, int x, int y) { - if (x < 0 || x >= canvas->width || - y < 0 || y >= canvas->height) return 0; - return canvas->pixels[x+y*canvas->width]; -} - -/* Draw a line from x1,y1 to x2,y2 using the Bresenham algorithm. */ -void lwDrawLine(lwCanvas *canvas, int x1, int y1, int x2, int y2, int color) { - int dx = abs(x2-x1); - int dy = abs(y2-y1); - int sx = (x1 < x2) ? 1 : -1; - int sy = (y1 < y2) ? 1 : -1; - int err = dx-dy, e2; - - while(1) { - lwDrawPixel(canvas,x1,y1,color); - if (x1 == x2 && y1 == y2) break; - e2 = err*2; - if (e2 > -dy) { - err -= dy; - x1 += sx; - } - if (e2 < dx) { - err += dx; - y1 += sy; - } - } -} - -/* Draw a square centered at the specified x,y coordinates, with the specified - * rotation angle and size. In order to write a rotated square, we use the - * trivial fact that the parametric equation: - * - * x = sin(k) - * y = cos(k) - * - * Describes a circle for values going from 0 to 2*PI. So basically if we start - * at 45 degrees, that is k = PI/4, with the first point, and then we find - * the other three points incrementing K by PI/2 (90 degrees), we'll have the - * points of the square. In order to rotate the square, we just start with - * k = PI/4 + rotation_angle, and we are done. - * - * Of course the vanilla equations above will describe the square inside a - * circle of radius 1, so in order to draw larger squares we'll have to - * multiply the obtained coordinates, and then translate them. However this - * is much simpler than implementing the abstract concept of 2D shape and then - * performing the rotation/translation transformation, so for LOLWUT it's - * a good approach. */ -void lwDrawSquare(lwCanvas *canvas, int x, int y, float size, float angle) { - int px[4], py[4]; - - /* Adjust the desired size according to the fact that the square inscribed - * into a circle of radius 1 has the side of length SQRT(2). This way - * size becomes a simple multiplication factor we can use with our - * coordinates to magnify them. */ - size /= 1.4142135623; - size = round(size); - - /* Compute the four points. */ - float k = M_PI/4 + angle; - for (int j = 0; j < 4; j++) { - px[j] = round(sin(k) * size + x); - py[j] = round(cos(k) * size + y); - k += M_PI/2; - } - - /* Draw the square. */ - for (int j = 0; j < 4; j++) - lwDrawLine(canvas,px[j],py[j],px[(j+1)%4],py[(j+1)%4],1); -} - -/* Schotter, the output of LOLWUT of Redis 5, is a computer graphic art piece - * generated by Georg Nees in the 60s. It explores the relationship between - * caos and order. - * - * The function creates the canvas itself, depending on the columns available - * in the output display and the number of squares per row and per column - * requested by the caller. */ -lwCanvas *lwDrawSchotter(int console_cols, int squares_per_row, int squares_per_col) { - /* Calculate the canvas size. */ - int canvas_width = console_cols*2; - int padding = canvas_width > 4 ? 2 : 0; - float square_side = (float)(canvas_width-padding*2) / squares_per_row; - int canvas_height = square_side * squares_per_col + padding*2; - lwCanvas *canvas = lwCreateCanvas(canvas_width, canvas_height); - - for (int y = 0; y < squares_per_col; y++) { - for (int x = 0; x < squares_per_row; x++) { - int sx = x * square_side + square_side/2 + padding; - int sy = y * square_side + square_side/2 + padding; - /* Rotate and translate randomly as we go down to lower - * rows. */ - float angle = 0; - if (y > 1) { - float r1 = (float)rand() / RAND_MAX / squares_per_col * y; - float r2 = (float)rand() / RAND_MAX / squares_per_col * y; - float r3 = (float)rand() / RAND_MAX / squares_per_col * y; - if (rand() % 2) r1 = -r1; - if (rand() % 2) r2 = -r2; - if (rand() % 2) r3 = -r3; - angle = r1; - sx += r2*square_side/3; - sy += r3*square_side/3; - } - lwDrawSquare(canvas,sx,sy,square_side,angle); - } - } - - return canvas; -} - -/* Converts the canvas to an SDS string representing the UTF8 characters to - * print to the terminal in order to obtain a graphical representaiton of the - * logical canvas. The actual returned string will require a terminal that is - * width/2 large and height/4 tall in order to hold the whole image without - * overflowing or scrolling, since each Barille character is 2x4. */ -sds lwRenderCanvas(lwCanvas *canvas) { - sds text = sdsempty(); - for (int y = 0; y < canvas->height; y += 4) { - for (int x = 0; x < canvas->width; x += 2) { - /* We need to emit groups of 8 bits according to a specific - * arrangement. See lwTranslatePixelsGroup() for more info. */ - int byte = 0; - if (lwGetPixel(canvas,x,y)) byte |= (1<<0); - if (lwGetPixel(canvas,x,y+1)) byte |= (1<<1); - if (lwGetPixel(canvas,x,y+2)) byte |= (1<<2); - if (lwGetPixel(canvas,x+1,y)) byte |= (1<<3); - if (lwGetPixel(canvas,x+1,y+1)) byte |= (1<<4); - if (lwGetPixel(canvas,x+1,y+2)) byte |= (1<<5); - if (lwGetPixel(canvas,x,y+3)) byte |= (1<<6); - if (lwGetPixel(canvas,x+1,y+3)) byte |= (1<<7); - char unicode[3]; - lwTranslatePixelsGroup(byte,unicode); - text = sdscatlen(text,unicode,3); - } - if (y != canvas->height-1) text = sdscatlen(text,"\n",1); - } - return text; -} - -/* The LOLWUT command: - * - * LOLWUT [terminal columns] [squares-per-row] [squares-per-col] - * - * By default the command uses 66 columns, 8 squares per row, 12 squares - * per column. - */ -void lolwut5Command(client *c) { - long cols = 66; - long squares_per_row = 8; - long squares_per_col = 12; - - /* Parse the optional arguments if any. */ - if (c->argc > 1 && - getLongFromObjectOrReply(c,c->argv[1],&cols,NULL) != C_OK) - return; - - if (c->argc > 2 && - getLongFromObjectOrReply(c,c->argv[2],&squares_per_row,NULL) != C_OK) - return; - - if (c->argc > 3 && - getLongFromObjectOrReply(c,c->argv[3],&squares_per_col,NULL) != C_OK) - return; - - /* Limits. We want LOLWUT to be always reasonably fast and cheap to execute - * so we have maximum number of columns, rows, and output resulution. */ - if (cols < 1) cols = 1; - if (cols > 1000) cols = 1000; - if (squares_per_row < 1) squares_per_row = 1; - if (squares_per_row > 200) squares_per_row = 200; - if (squares_per_col < 1) squares_per_col = 1; - if (squares_per_col > 200) squares_per_col = 200; - - /* Generate some computer art and reply. */ - lwCanvas *canvas = lwDrawSchotter(cols,squares_per_row,squares_per_col); - sds rendered = lwRenderCanvas(canvas); - rendered = sdscat(rendered, - "\nGeorg Nees - schotter, plotter on paper, 1968. Redis ver. "); - rendered = sdscat(rendered,REDIS_VERSION); - rendered = sdscatlen(rendered,"\n",1); - addReplyBulkSds(c,rendered); - lwFreeCanvas(canvas); -} diff --git a/src/lzf.h b/src/lzf.h index 98e038f31..809c6833c 100644 --- a/src/lzf.h +++ b/src/lzf.h @@ -48,6 +48,10 @@ #define LZF_VERSION 0x0105 /* 1.5, API version */ +#ifdef __cplusplus +extern "C" { +#endif + /* * Compress in_len bytes stored at the memory block starting at * in_data and write the result to out_data, up to a maximum length @@ -96,5 +100,9 @@ unsigned int lzf_decompress (const void *const in_data, unsigned int in_len, void *out_data, unsigned int out_len); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/module.c b/src/module.cpp similarity index 95% rename from src/module.c rename to src/module.cpp index 6fda14374..3a109c1d5 100644 --- a/src/module.c +++ b/src/module.cpp @@ -48,7 +48,7 @@ struct RedisModule { int apiver; /* Module API version as requested during initialization.*/ list *types; /* Module data types. */ list *usedby; /* List of modules using APIs from this one. */ - list *using; /* List of modules we use some APIs of. */ + list *usingMods; /* List of modules we use some APIs of. */ list *filters; /* List of filters the module has registered. */ int in_call; /* RM_Call() nesting level */ }; @@ -100,7 +100,9 @@ typedef struct RedisModulePoolAllocBlock { uint32_t size; uint32_t used; struct RedisModulePoolAllocBlock *next; - char memory[]; + char *memory() { + return reinterpret_cast(this+1); + }; } RedisModulePoolAllocBlock; /* This structure represents the context in which Redis modules operate. @@ -116,7 +118,7 @@ struct RedisModuleBlockedClient; struct RedisModuleCtx { void *getapifuncptr; /* NOTE: Must be the first field. */ struct RedisModule *module; /* Module reference. */ - client *client; /* Client calling a command. */ + ::client *client; /* Client calling a command. */ struct RedisModuleBlockedClient *blocked_client; /* Blocked client for thread safe context. */ struct AutoMemEntry *amqueue; /* Auto memory queue of objects to free. */ @@ -213,7 +215,7 @@ typedef struct RedisModuleCallReply { /* Structure representing a blocked client. We get a pointer to such * an object when blocking from modules. */ typedef struct RedisModuleBlockedClient { - client *client; /* Pointer to the blocked client. or NULL if the client + ::client *client; /* Pointer to the blocked client. or NULL if the client was destroyed during the life of this object. */ RedisModule *module; /* Module blocking the client. */ RedisModuleCmdFunc reply_callback; /* Reply callback on normal completion.*/ @@ -223,7 +225,7 @@ typedef struct RedisModuleBlockedClient { void *privdata; /* Module private data that may be used by the reply or timeout callback. It is set via the RedisModule_UnblockClient() API. */ - client *reply_client; /* Fake client used to accumulate replies + ::client *reply_client; /* Fake client used to accumulate replies in thread safe contexts. */ int dbid; /* Database number selected by the original client. */ } RedisModuleBlockedClient; @@ -264,7 +266,7 @@ static client *moduleFreeContextReusedClient; /* Data structures related to the exported dictionary data structure. */ typedef struct RedisModuleDict { - rax *rax; /* The radix tree. */ + ::rax *rax; /* The radix tree. */ } RedisModuleDict; typedef struct RedisModuleDictIter { @@ -387,14 +389,14 @@ void *RM_PoolAlloc(RedisModuleCtx *ctx, size_t bytes) { if (left < bytes) { size_t blocksize = REDISMODULE_POOL_ALLOC_MIN_SIZE; if (blocksize < bytes) blocksize = bytes; - b = zmalloc(sizeof(*b) + blocksize, MALLOC_LOCAL); + b = (RedisModulePoolAllocBlock*)zmalloc(sizeof(*b) + blocksize, MALLOC_LOCAL); b->size = blocksize; b->used = 0; b->next = ctx->pa_head; ctx->pa_head = b; } - char *retval = b->memory + b->used; + char *retval = b->memory() + b->used; b->used += bytes; return retval; } @@ -425,7 +427,7 @@ int moduleCreateEmptyKey(RedisModuleKey *key, int type) { switch(type) { case REDISMODULE_KEYTYPE_LIST: obj = createQuicklistObject(); - quicklistSetOptions(obj->m_ptr, server.list_max_ziplist_size, + quicklistSetOptions((quicklist*)obj->m_ptr, server.list_max_ziplist_size, server.list_compress_depth); break; case REDISMODULE_KEYTYPE_ZSET: @@ -535,7 +537,7 @@ void moduleHandlePropagationAfterCommandCallback(RedisModuleCtx *ctx) { /* This Redis command binds the normal Redis command invocation with commands * exported by modules. */ void RedisModuleCommandDispatcher(client *c) { - RedisModuleCommandProxy *cp = (void*)(unsigned long)c->cmd->getkeys_proc; + RedisModuleCommandProxy *cp = (RedisModuleCommandProxy*)(unsigned long)c->cmd->getkeys_proc; RedisModuleCtx ctx = REDISMODULE_CTX_INIT; ctx.module = cp->module; @@ -571,7 +573,7 @@ void RedisModuleCommandDispatcher(client *c) { * the context in a way that the command can recognize this is a special * "get keys" call by calling RedisModule_IsKeysPositionRequest(ctx). */ int *moduleGetCommandKeysViaAPI(struct redisCommand *cmd, robj **argv, int argc, int *numkeys) { - RedisModuleCommandProxy *cp = (void*)(unsigned long)cmd->getkeys_proc; + RedisModuleCommandProxy *cp = (RedisModuleCommandProxy*)(unsigned long)cmd->getkeys_proc; RedisModuleCtx ctx = REDISMODULE_CTX_INIT; ctx.module = cp->module; @@ -608,7 +610,7 @@ int RM_IsKeysPositionRequest(RedisModuleCtx *ctx) { void RM_KeyAtPos(RedisModuleCtx *ctx, int pos) { if (!(ctx->flags & REDISMODULE_CTX_KEYS_POS_REQUEST)) return; if (pos <= 0) return; - ctx->keys_pos = zrealloc(ctx->keys_pos,sizeof(int)*(ctx->keys_count+1), MALLOC_LOCAL); + ctx->keys_pos = (int*)zrealloc(ctx->keys_pos,sizeof(int)*(ctx->keys_count+1), MALLOC_LOCAL); ctx->keys_pos[ctx->keys_count++] = pos; } @@ -718,10 +720,10 @@ int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc c * * Note that we use the Redis command table 'getkeys_proc' in order to * pass a reference to the command proxy structure. */ - cp = zmalloc(sizeof(*cp), MALLOC_LOCAL); + cp = (RedisModuleCommandProxy*)zmalloc(sizeof(*cp), MALLOC_LOCAL); cp->module = ctx->module; cp->func = cmdfunc; - cp->rediscmd = zmalloc(sizeof(*rediscmd), MALLOC_LOCAL); + cp->rediscmd = (redisCommand*)zmalloc(sizeof(*rediscmd), MALLOC_LOCAL); cp->rediscmd->name = cmdname; cp->rediscmd->proc = RedisModuleCommandDispatcher; cp->rediscmd->arity = -1; @@ -746,13 +748,13 @@ void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int api RedisModule *module; if (ctx->module != NULL) return; - module = zmalloc(sizeof(*module), MALLOC_LOCAL); + module = (RedisModule*)zmalloc(sizeof(*module), MALLOC_LOCAL); module->name = sdsnew((char*)name); module->ver = ver; module->apiver = apiver; module->types = listCreate(); module->usedby = listCreate(); - module->using = listCreate(); + module->usingMods = listCreate(); module->filters = listCreate(); ctx->module = module; } @@ -789,7 +791,7 @@ void autoMemoryAdd(RedisModuleCtx *ctx, int type, void *ptr) { if (ctx->amqueue_used == ctx->amqueue_len) { ctx->amqueue_len *= 2; if (ctx->amqueue_len < 16) ctx->amqueue_len = 16; - ctx->amqueue = zrealloc(ctx->amqueue,sizeof(struct AutoMemEntry)*ctx->amqueue_len, MALLOC_LOCAL); + ctx->amqueue = (AutoMemEntry*)zrealloc(ctx->amqueue,sizeof(struct AutoMemEntry)*ctx->amqueue_len, MALLOC_LOCAL); } ctx->amqueue[ctx->amqueue_used].type = type; ctx->amqueue[ctx->amqueue_used].ptr = ptr; @@ -840,12 +842,12 @@ void autoMemoryCollect(RedisModuleCtx *ctx) { ctx->flags &= ~REDISMODULE_CTX_AUTO_MEMORY; int j; for (j = 0; j < ctx->amqueue_used; j++) { - void *ptr = ctx->amqueue[j].ptr; + void *ptr = (robj*)ctx->amqueue[j].ptr; switch(ctx->amqueue[j].type) { - case REDISMODULE_AM_STRING: decrRefCount(ptr); break; - case REDISMODULE_AM_REPLY: RM_FreeCallReply(ptr); break; - case REDISMODULE_AM_KEY: RM_CloseKey(ptr); break; - case REDISMODULE_AM_DICT: RM_FreeDict(NULL,ptr); break; + case REDISMODULE_AM_STRING: decrRefCount((robj*)ptr); break; + case REDISMODULE_AM_REPLY: RM_FreeCallReply((RedisModuleCallReply*)ptr); break; + case REDISMODULE_AM_KEY: RM_CloseKey((RedisModuleKey*)ptr); break; + case REDISMODULE_AM_DICT: RM_FreeDict(NULL,(RedisModuleDict*)ptr); break; } } ctx->flags |= REDISMODULE_CTX_AUTO_MEMORY; @@ -991,8 +993,8 @@ const char *RM_StringPtrLen(const RedisModuleString *str, size_t *len) { if (len) *len = strlen(errmsg); return errmsg; } - if (len) *len = sdslen(ptrFromObj(str)); - return ptrFromObj(str); + if (len) *len = sdslen(szFromObj(str)); + return szFromObj(str); } /* -------------------------------------------------------------------------- @@ -1004,7 +1006,7 @@ const char *RM_StringPtrLen(const RedisModuleString *str, size_t *len) { * as a valid, strict long long (no spaces before/after), REDISMODULE_ERR * is returned. */ int RM_StringToLongLong(const RedisModuleString *str, long long *ll) { - return string2ll(ptrFromObj(str),sdslen(ptrFromObj(str)),ll) ? REDISMODULE_OK : + return string2ll(szFromObj(str),sdslen(szFromObj(str)),ll) ? REDISMODULE_OK : REDISMODULE_ERR; } @@ -1036,7 +1038,7 @@ RedisModuleString *moduleAssertUnsharedString(RedisModuleString *str) { if (str->encoding == OBJ_ENCODING_EMBSTR) { /* Note: here we "leak" the additional allocation that was * used in order to store the embedded string in the object. */ - str->m_ptr = sdsnewlen(ptrFromObj(str),sdslen(ptrFromObj(str))); + str->m_ptr = sdsnewlen(szFromObj(str),sdslen(szFromObj(str))); str->encoding = OBJ_ENCODING_RAW; } else if (str->encoding == OBJ_ENCODING_INT) { /* Convert the string from integer to raw encoding. */ @@ -1053,7 +1055,7 @@ int RM_StringAppendBuffer(RedisModuleCtx *ctx, RedisModuleString *str, const cha UNUSED(ctx); str = moduleAssertUnsharedString(str); if (str == NULL) return REDISMODULE_ERR; - str->m_ptr = sdscatlen(str->m_ptr,buf,len); + str->m_ptr = sdscatlen((sds)str->m_ptr,buf,len); return REDISMODULE_OK; } @@ -1122,7 +1124,7 @@ int RM_ReplyWithLongLong(RedisModuleCtx *ctx, long long ll) { /* Reply with an error or simple string (status message). Used to implement * ReplyWithSimpleString() and ReplyWithError(). * The function always returns REDISMODULE_OK. */ -int replyWithStatus(RedisModuleCtx *ctx, const char *msg, char *prefix) { +int replyWithStatus(RedisModuleCtx *ctx, const char *msg, const char *prefix) { client *c = moduleGetReplyClient(ctx); if (c == NULL) return REDISMODULE_OK; sds strmsg = sdsnewlen(prefix,1); @@ -1174,7 +1176,7 @@ int RM_ReplyWithArray(RedisModuleCtx *ctx, long len) { client *c = moduleGetReplyClient(ctx); if (c == NULL) return REDISMODULE_OK; if (len == REDISMODULE_POSTPONED_ARRAY_LEN) { - ctx->postponed_arrays = zrealloc(ctx->postponed_arrays,sizeof(void*)* + ctx->postponed_arrays = (void**)zrealloc(ctx->postponed_arrays,sizeof(void*)* (ctx->postponed_arrays_count+1), MALLOC_LOCAL); ctx->postponed_arrays[ctx->postponed_arrays_count] = addReplyDeferredLen(c); @@ -1530,7 +1532,7 @@ void *RM_OpenKey(RedisModuleCtx *ctx, robj *keyname, int mode) { } /* Setup the key handle. */ - kp = zmalloc(sizeof(*kp), MALLOC_LOCAL); + kp = (RedisModuleKey*)zmalloc(sizeof(*kp), MALLOC_LOCAL); kp->ctx = ctx; kp->db = ctx->client->db; kp->key = keyname; @@ -1691,12 +1693,12 @@ int RM_StringSet(RedisModuleKey *key, RedisModuleString *str) { * so a RM_StringTruncate() call should be used if there is to enlarge * the string, and later call StringDMA() again to get the pointer. */ -char *RM_StringDMA(RedisModuleKey *key, size_t *len, int mode) { +const char *RM_StringDMA(RedisModuleKey *key, size_t *len, int mode) { /* We need to return *some* pointer for empty keys, we just return * a string literal pointer, that is the advantage to be mapped into * a read only memory page, so the module will segfault if a write * attempt is performed. */ - char *emptystring = ""; + const char *emptystring = ""; if (key->value == NULL) { *len = 0; return emptystring; @@ -1709,8 +1711,8 @@ char *RM_StringDMA(RedisModuleKey *key, size_t *len, int mode) { if ((mode & REDISMODULE_WRITE) || key->value->encoding != OBJ_ENCODING_RAW) key->value = dbUnshareStringValue(key->db, key->key, key->value); - *len = sdslen(ptrFromObj(key->value)); - return ptrFromObj(key->value); + *len = sdslen(szFromObj(key->value)); + return szFromObj(key->value); } /* If the string is open for writing and is of string type, resize it, padding @@ -1743,14 +1745,14 @@ int RM_StringTruncate(RedisModuleKey *key, size_t newlen) { } else { /* Unshare and resize. */ key->value = dbUnshareStringValue(key->db, key->key, key->value); - size_t curlen = sdslen(ptrFromObj(key->value)); + size_t curlen = sdslen(szFromObj(key->value)); if (newlen > curlen) { - key->value->m_ptr = sdsgrowzero(ptrFromObj(key->value),newlen); + key->value->m_ptr = sdsgrowzero(szFromObj(key->value),newlen); } else if (newlen < curlen) { - sdsrange(ptrFromObj(key->value),0,newlen-1); + sdsrange(szFromObj(key->value),0,newlen-1); /* If the string is too wasteful, reallocate it. */ - if (sdslen(ptrFromObj(key->value)) < sdsavail(ptrFromObj(key->value))) - key->value->m_ptr = sdsRemoveFreeSpace(ptrFromObj(key->value)); + if (sdslen(szFromObj(key->value)) < sdsavail(szFromObj(key->value))) + key->value->m_ptr = sdsRemoveFreeSpace(szFromObj(key->value)); } } return REDISMODULE_OK; @@ -1849,7 +1851,7 @@ int RM_ZsetAdd(RedisModuleKey *key, double score, RedisModuleString *ele, int *f if (key->value && key->value->type != OBJ_ZSET) return REDISMODULE_ERR; if (key->value == NULL) moduleCreateEmptyKey(key,REDISMODULE_KEYTYPE_ZSET); if (flagsptr) flags = RM_ZsetAddFlagsToCoreFlags(*flagsptr); - if (zsetAdd(key->value,score,ptrFromObj(ele),&flags,NULL) == 0) { + if (zsetAdd(key->value,score,szFromObj(ele),&flags,NULL) == 0) { if (flagsptr) *flagsptr = 0; return REDISMODULE_ERR; } @@ -1877,7 +1879,7 @@ int RM_ZsetIncrby(RedisModuleKey *key, double score, RedisModuleString *ele, int if (key->value == NULL) moduleCreateEmptyKey(key,REDISMODULE_KEYTYPE_ZSET); if (flagsptr) flags = RM_ZsetAddFlagsToCoreFlags(*flagsptr); flags |= ZADD_INCR; - if (zsetAdd(key->value,score,ptrFromObj(ele),&flags,newscore) == 0) { + if (zsetAdd(key->value,score,szFromObj(ele),&flags,newscore) == 0) { if (flagsptr) *flagsptr = 0; return REDISMODULE_ERR; } @@ -1911,7 +1913,7 @@ int RM_ZsetIncrby(RedisModuleKey *key, double score, RedisModuleString *ele, int int RM_ZsetRem(RedisModuleKey *key, RedisModuleString *ele, int *deleted) { if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR; if (key->value && key->value->type != OBJ_ZSET) return REDISMODULE_ERR; - if (key->value != NULL && zsetDel(key->value,ptrFromObj(ele))) { + if (key->value != NULL && zsetDel(key->value,szFromObj(ele))) { if (deleted) *deleted = 1; } else { if (deleted) *deleted = 0; @@ -1930,7 +1932,7 @@ int RM_ZsetRem(RedisModuleKey *key, RedisModuleString *ele, int *deleted) { int RM_ZsetScore(RedisModuleKey *key, RedisModuleString *ele, double *score) { if (key->value == NULL) return REDISMODULE_ERR; if (key->value->type != OBJ_ZSET) return REDISMODULE_ERR; - if (zsetScore(key->value,ptrFromObj(ele),score) == C_ERR) return REDISMODULE_ERR; + if (zsetScore(key->value,szFromObj(ele),score) == C_ERR) return REDISMODULE_ERR; return REDISMODULE_OK; } @@ -1982,10 +1984,10 @@ int zsetInitScoreRange(RedisModuleKey *key, double min, double max, int minex, i zrs->maxex = maxex; if (key->value->encoding == OBJ_ENCODING_ZIPLIST) { - key->zcurrent = first ? zzlFirstInRange(ptrFromObj(key->value),zrs) : - zzlLastInRange(ptrFromObj(key->value),zrs); + key->zcurrent = first ? zzlFirstInRange((unsigned char*)ptrFromObj(key->value),zrs) : + zzlLastInRange((unsigned char*)ptrFromObj(key->value),zrs); } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = ptrFromObj(key->value); + zset *zs = (zset*)ptrFromObj(key->value); zskiplist *zsl = zs->zsl; key->zcurrent = first ? zslFirstInRange(zsl,zrs) : zslLastInRange(zsl,zrs); @@ -2046,10 +2048,10 @@ int zsetInitLexRange(RedisModuleKey *key, RedisModuleString *min, RedisModuleStr key->ztype = REDISMODULE_ZSET_RANGE_LEX; if (key->value->encoding == OBJ_ENCODING_ZIPLIST) { - key->zcurrent = first ? zzlFirstInLexRange(ptrFromObj(key->value),zlrs) : - zzlLastInLexRange(ptrFromObj(key->value),zlrs); + key->zcurrent = first ? zzlFirstInLexRange((unsigned char*)ptrFromObj(key->value),zlrs) : + zzlLastInLexRange((unsigned char*)ptrFromObj(key->value),zlrs); } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = ptrFromObj(key->value); + zset *zs = (zset*)ptrFromObj(key->value); zskiplist *zsl = zs->zsl; key->zcurrent = first ? zslFirstInLexRange(zsl,zlrs) : zslLastInLexRange(zsl,zlrs); @@ -2092,15 +2094,15 @@ RedisModuleString *RM_ZsetRangeCurrentElement(RedisModuleKey *key, double *score if (key->zcurrent == NULL) return NULL; if (key->value->encoding == OBJ_ENCODING_ZIPLIST) { unsigned char *eptr, *sptr; - eptr = key->zcurrent; + eptr = (unsigned char*)key->zcurrent; sds ele = ziplistGetObject(eptr); if (score) { - sptr = ziplistNext(ptrFromObj(key->value),eptr); + sptr = ziplistNext((unsigned char*)ptrFromObj(key->value),eptr); *score = zzlGetScore(sptr); } str = createObject(OBJ_STRING,ele); } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) { - zskiplistNode *ln = key->zcurrent; + zskiplistNode *ln = (zskiplistNode*)key->zcurrent; if (score) *score = ln->score; str = createStringObject(ln->ele,sdslen(ln->ele)); } else { @@ -2117,8 +2119,8 @@ int RM_ZsetRangeNext(RedisModuleKey *key) { if (!key->ztype || !key->zcurrent) return 0; /* No active iterator. */ if (key->value->encoding == OBJ_ENCODING_ZIPLIST) { - unsigned char *zl = ptrFromObj(key->value); - unsigned char *eptr = key->zcurrent; + unsigned char *zl = (unsigned char*)ptrFromObj(key->value); + unsigned char *eptr = (unsigned char*)key->zcurrent; unsigned char *next; next = ziplistNext(zl,eptr); /* Skip element. */ if (next) next = ziplistNext(zl,next); /* Skip score. */ @@ -2148,7 +2150,7 @@ int RM_ZsetRangeNext(RedisModuleKey *key) { return 1; } } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) { - zskiplistNode *ln = key->zcurrent, *next = ln->level[0].forward; + zskiplistNode *ln = (zskiplistNode*)key->zcurrent, *next = (zskiplistNode*)ln->level(0)->forward; if (next == NULL) { key->zer = 1; return 0; @@ -2180,8 +2182,8 @@ int RM_ZsetRangePrev(RedisModuleKey *key) { if (!key->ztype || !key->zcurrent) return 0; /* No active iterator. */ if (key->value->encoding == OBJ_ENCODING_ZIPLIST) { - unsigned char *zl = ptrFromObj(key->value); - unsigned char *eptr = key->zcurrent; + unsigned char *zl = (unsigned char*)ptrFromObj(key->value); + unsigned char *eptr = (unsigned char*)key->zcurrent; unsigned char *prev; prev = ziplistPrev(zl,eptr); /* Go back to previous score. */ if (prev) prev = ziplistPrev(zl,prev); /* Back to previous ele. */ @@ -2211,7 +2213,7 @@ int RM_ZsetRangePrev(RedisModuleKey *key) { return 1; } } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) { - zskiplistNode *ln = key->zcurrent, *prev = ln->backward; + zskiplistNode *ln = (zskiplistNode*)key->zcurrent, *prev = ln->backward; if (prev == NULL) { key->zer = 1; return 0; @@ -2315,7 +2317,7 @@ int RM_HashSet(RedisModuleKey *key, int flags, ...) { /* Handle XX and NX */ if (flags & (REDISMODULE_HASH_XX|REDISMODULE_HASH_NX)) { - int exists = hashTypeExists(key->value, ptrFromObj(field)); + int exists = hashTypeExists(key->value, szFromObj(field)); if (((flags & REDISMODULE_HASH_XX) && !exists) || ((flags & REDISMODULE_HASH_NX) && exists)) { @@ -2326,7 +2328,7 @@ int RM_HashSet(RedisModuleKey *key, int flags, ...) { /* Handle deletion if value is REDISMODULE_HASH_DELETE. */ if (value == REDISMODULE_HASH_DELETE) { - updated += hashTypeDelete(key->value, ptrFromObj(field)); + updated += hashTypeDelete(key->value, szFromObj(field)); if (flags & REDISMODULE_HASH_CFIELDS) decrRefCount(field); continue; } @@ -2340,7 +2342,7 @@ int RM_HashSet(RedisModuleKey *key, int flags, ...) { robj *argv[2] = {field,value}; hashTypeTryConversion(key->value,argv,0,1); - updated += hashTypeSet(key->value, ptrFromObj(field), ptrFromObj(value), low_flags); + updated += hashTypeSet(key->value, szFromObj(field), szFromObj(value), low_flags); /* If CFIELDS is active, SDS string ownership is now of hashTypeSet(), * however we still have to release the 'field' object shell. */ @@ -2417,13 +2419,13 @@ int RM_HashGet(RedisModuleKey *key, int flags, ...) { if (flags & REDISMODULE_HASH_EXISTS) { existsptr = va_arg(ap,int*); if (key->value) - *existsptr = hashTypeExists(key->value,ptrFromObj(field)); + *existsptr = hashTypeExists(key->value,szFromObj(field)); else *existsptr = 0; } else { valueptr = va_arg(ap,RedisModuleString**); if (key->value) { - *valueptr = hashTypeGetValueObject(key->value,ptrFromObj(field)); + *valueptr = hashTypeGetValueObject(key->value,szFromObj(field)); if (*valueptr) { robj *decoded = getDecodedObject(*valueptr); decrRefCount(*valueptr); @@ -2452,7 +2454,7 @@ int RM_HashGet(RedisModuleKey *key, int flags, ...) { * is processed as needed. Initially we just make sure to set the right * reply type, which is extremely cheap to do. */ RedisModuleCallReply *moduleCreateCallReplyFromProto(RedisModuleCtx *ctx, sds proto) { - RedisModuleCallReply *reply = zmalloc(sizeof(*reply), MALLOC_LOCAL); + RedisModuleCallReply *reply = (RedisModuleCallReply*)zmalloc(sizeof(*reply), MALLOC_LOCAL); reply->ctx = ctx; reply->proto = proto; reply->protolen = sdslen(proto); @@ -2542,7 +2544,7 @@ void moduleParseCallReply_Array(RedisModuleCallReply *reply) { return; } - reply->val.array = zmalloc(sizeof(RedisModuleCallReply)*arraylen, MALLOC_LOCAL); + reply->val.array = (RedisModuleCallReply*)zmalloc(sizeof(RedisModuleCallReply)*arraylen, MALLOC_LOCAL); reply->len = arraylen; for (j = 0; j < arraylen; j++) { RedisModuleCallReply *ele = reply->val.array+j; @@ -2676,7 +2678,7 @@ robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int /* As a first guess to avoid useless reallocations, size argv to * hold one argument for each char specifier in 'fmt'. */ argv_size = strlen(fmt)+1; /* +1 because of the command name. */ - argv = zrealloc(argv,sizeof(robj*)*argv_size, MALLOC_LOCAL); + argv = (robj**)zrealloc(argv,sizeof(robj*)*argv_size, MALLOC_LOCAL); /* Build the arguments vector based on the format specifier. */ argv[0] = createStringObject(cmdname,strlen(cmdname)); @@ -2689,7 +2691,7 @@ robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int char *cstr = va_arg(ap,char*); argv[argc++] = createStringObject(cstr,strlen(cstr)); } else if (*p == 's') { - robj *obj = va_arg(ap,void*); + robj *obj = (robj*)va_arg(ap,void*); argv[argc++] = obj; incrRefCount(obj); } else if (*p == 'b') { @@ -2701,14 +2703,14 @@ robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int argv[argc++] = createObject(OBJ_STRING,sdsfromlonglong(ll)); } else if (*p == 'v') { /* A vector of strings */ - robj **v = va_arg(ap, void*); + robj **v = (robj**)va_arg(ap, void*); size_t vlen = va_arg(ap, size_t); /* We need to grow argv to hold the vector's elements. * We resize by vector_len-1 elements, because we held * one element in argv for the vector already */ argv_size += vlen-1; - argv = zrealloc(argv,sizeof(robj*)*argv_size, MALLOC_LOCAL); + argv = (robj**)zrealloc(argv,sizeof(robj*)*argv_size, MALLOC_LOCAL); size_t i = 0; for (i = 0; i < vlen; i++) { @@ -2746,6 +2748,8 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch va_list ap; RedisModuleCallReply *reply = NULL; int replicate = 0; /* Replicate this command? */ + int call_flags; + sds proto = nullptr; /* Create the client and dispatch the command. */ va_start(ap, fmt); @@ -2772,7 +2776,7 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch /* Lookup command now, after filters had a chance to make modifications * if necessary. */ - cmd = lookupCommand(ptrFromObj(c->argv[0])); + cmd = lookupCommand(szFromObj(c->argv[0])); if (!cmd) { errno = EINVAL; goto cleanup; @@ -2806,7 +2810,7 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch if (replicate) moduleReplicateMultiIfNeeded(ctx); /* Run the command */ - int call_flags = CMD_CALL_SLOWLOG | CMD_CALL_STATS; + call_flags = CMD_CALL_SLOWLOG | CMD_CALL_STATS; if (replicate) { call_flags |= CMD_CALL_PROPAGATE_AOF; call_flags |= CMD_CALL_PROPAGATE_REPL; @@ -2816,12 +2820,12 @@ RedisModuleCallReply *RM_Call(RedisModuleCtx *ctx, const char *cmdname, const ch /* Convert the result of the Redis command into a suitable Lua type. * The first thing we need is to create a single string from the client * output buffers. */ - sds proto = sdsnewlen(c->buf,c->bufpos); + proto = sdsnewlen(c->buf,c->bufpos); c->bufpos = 0; while(listLength(c->reply)) { - clientReplyBlock *o = listNodeValue(listFirst(c->reply)); + clientReplyBlock *o = (clientReplyBlock*)listNodeValue(listFirst(c->reply)); - proto = sdscatlen(proto,o->buf,o->used); + proto = sdscatlen(proto,o->buf(),o->used); listDelNode(c->reply,listFirst(c->reply)); } reply = moduleCreateCallReplyFromProto(ctx,proto); @@ -2887,7 +2891,7 @@ uint64_t moduleTypeEncodeId(const char *name, int encver) { uint64_t id = 0; for (int j = 0; j < 9; j++) { - char *p = strchr(cset,name[j]); + const char *p = strchr(cset,name[j]); if (!p) return 0; unsigned long pos = p-cset; id = (id << 6) | pos; @@ -2904,13 +2908,13 @@ moduleType *moduleTypeLookupModuleByName(const char *name) { dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct RedisModule *module = dictGetVal(de); + struct RedisModule *module = (RedisModule*)dictGetVal(de); listIter li; listNode *ln; listRewind(module->types,&li); while((ln = listNext(&li))) { - moduleType *mt = ln->value; + moduleType *mt = (moduleType*)ln->value; if (memcmp(name,mt->name,sizeof(mt->name)) == 0) { dictReleaseIterator(di); return mt; @@ -2943,13 +2947,13 @@ moduleType *moduleTypeLookupModuleByID(uint64_t id) { dictEntry *de; while ((de = dictNext(di)) != NULL && mt == NULL) { - struct RedisModule *module = dictGetVal(de); + struct RedisModule *module = (RedisModule*)dictGetVal(de); listIter li; listNode *ln; listRewind(module->types,&li); while((ln = listNext(&li))) { - moduleType *this_mt = ln->value; + moduleType *this_mt = (moduleType*)ln->value; /* Compare only the 54 bit module identifier and not the * encoding version. */ if (this_mt->id >> 10 == id >> 10) { @@ -3066,7 +3070,7 @@ moduleType *RM_CreateDataType(RedisModuleCtx *ctx, const char *name, int encver, moduleTypeFreeFunc free; } *tms = (struct typemethods*) typemethods_ptr; - moduleType *mt = zcalloc(sizeof(*mt), MALLOC_LOCAL); + moduleType *mt = (moduleType*)zcalloc(sizeof(*mt), MALLOC_LOCAL); mt->id = id; mt->module = ctx->module; mt->rdb_load = tms->rdb_load; @@ -3103,7 +3107,7 @@ moduleType *RM_ModuleTypeGetType(RedisModuleKey *key) { if (key == NULL || key->value == NULL || RM_KeyType(key) != REDISMODULE_KEYTYPE_MODULE) return NULL; - moduleValue *mv = ptrFromObj(key->value); + moduleValue *mv = (moduleValue*)ptrFromObj(key->value); return mv->type; } @@ -3117,7 +3121,7 @@ void *RM_ModuleTypeGetValue(RedisModuleKey *key) { if (key == NULL || key->value == NULL || RM_KeyType(key) != REDISMODULE_KEYTYPE_MODULE) return NULL; - moduleValue *mv = ptrFromObj(key->value); + moduleValue *mv = (moduleValue*)ptrFromObj(key->value); return mv->value; } @@ -3161,12 +3165,13 @@ saveerr: * be called in the context of the rdb_load method of modules implementing * new data types. */ uint64_t RM_LoadUnsigned(RedisModuleIO *io) { + int retval; if (io->ver == 2) { uint64_t opcode = rdbLoadLen(io->prio,NULL); if (opcode != RDB_MODULE_OPCODE_UINT) goto loaderr; } uint64_t value; - int retval = rdbLoadLenByRef(io->prio, NULL, &value); + retval = rdbLoadLenByRef(io->prio, NULL, &value); if (retval == -1) goto loaderr; return value; @@ -3231,11 +3236,12 @@ saveerr: /* Implements RM_LoadString() and RM_LoadStringBuffer() */ void *moduleLoadString(RedisModuleIO *io, int plain, size_t *lenptr) { + void *s = nullptr; if (io->ver == 2) { uint64_t opcode = rdbLoadLen(io->prio,NULL); if (opcode != RDB_MODULE_OPCODE_STRING) goto loaderr; } - void *s = rdbGenericLoadStringObject(io->prio, + s = rdbGenericLoadStringObject(io->prio, plain ? RDB_LOAD_PLAIN : RDB_LOAD_NONE, lenptr); if (s == NULL) goto loaderr; return s; @@ -3255,7 +3261,7 @@ loaderr: * If the data structure does not store strings as RedisModuleString objects, * the similar function RedisModule_LoadStringBuffer() could be used instead. */ RedisModuleString *RM_LoadString(RedisModuleIO *io) { - return moduleLoadString(io,0,NULL); + return (RedisModuleString*)moduleLoadString(io,0,NULL); } /* Like RedisModule_LoadString() but returns an heap allocated string that @@ -3266,7 +3272,7 @@ RedisModuleString *RM_LoadString(RedisModuleIO *io) { * The returned string is not automatically NULL termianted, it is loaded * exactly as it was stored inisde the RDB file. */ char *RM_LoadStringBuffer(RedisModuleIO *io, size_t *lenptr) { - return moduleLoadString(io,1,lenptr); + return (char*)moduleLoadString(io,1,lenptr); } /* In the context of the rdb_save method of a module data type, saves a double @@ -3291,12 +3297,13 @@ saveerr: /* In the context of the rdb_save method of a module data type, loads back the * double value saved by RedisModule_SaveDouble(). */ double RM_LoadDouble(RedisModuleIO *io) { + int retval; if (io->ver == 2) { uint64_t opcode = rdbLoadLen(io->prio,NULL); if (opcode != RDB_MODULE_OPCODE_DOUBLE) goto loaderr; } double value; - int retval = rdbLoadBinaryDoubleValue(io->prio, &value); + retval = rdbLoadBinaryDoubleValue(io->prio, &value); if (retval == -1) goto loaderr; return value; @@ -3327,12 +3334,13 @@ saveerr: /* In the context of the rdb_save method of a module data type, loads back the * float value saved by RedisModule_SaveFloat(). */ float RM_LoadFloat(RedisModuleIO *io) { + int retval = C_ERR; if (io->ver == 2) { uint64_t opcode = rdbLoadLen(io->prio,NULL); if (opcode != RDB_MODULE_OPCODE_FLOAT) goto loaderr; } float value; - int retval = rdbLoadBinaryFloatValue(io->prio, &value); + retval = rdbLoadBinaryFloatValue(io->prio, &value); if (retval == -1) goto loaderr; return value; @@ -3463,7 +3471,7 @@ void RM_EmitAOF(RedisModuleIO *io, const char *cmdname, const char *fmt, ...) { RedisModuleCtx *RM_GetContextFromIO(RedisModuleIO *io) { if (io->ctx) return io->ctx; /* Can't have more than one... */ RedisModuleCtx ctxtemplate = REDISMODULE_CTX_INIT; - io->ctx = zmalloc(sizeof(RedisModuleCtx), MALLOC_LOCAL); + io->ctx = (RedisModuleCtx*)zmalloc(sizeof(RedisModuleCtx), MALLOC_LOCAL); *(io->ctx) = ctxtemplate; io->ctx->module = io->type->module; io->ctx->client = NULL; @@ -3569,7 +3577,7 @@ void moduleBlockedClientPipeReadable(aeEventLoop *el, int fd, void *privdata, in * The structure RedisModuleBlockedClient will be always deallocated when * running the list of clients blocked by a module that need to be unblocked. */ void unblockClientFromModule(client *c) { - RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle; + RedisModuleBlockedClient *bc = (RedisModuleBlockedClient*)c->bpop.module_blocked_handle; /* Call the disconnection callback if any. */ if (bc->disconnect_callback) { @@ -3611,7 +3619,7 @@ RedisModuleBlockedClient *RM_BlockClient(RedisModuleCtx *ctx, RedisModuleCmdFunc int ismulti = c->flags & CLIENT_MULTI; c->bpop.module_blocked_handle = zmalloc(sizeof(RedisModuleBlockedClient), MALLOC_LOCAL); - RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle; + RedisModuleBlockedClient *bc = (RedisModuleBlockedClient*)c->bpop.module_blocked_handle; /* We need to handle the invalid operation of calling modules blocking * commands from Lua or MULTI. We actually create an already aborted @@ -3710,7 +3718,7 @@ void moduleHandleBlockedClients(void) { while (read(server.module_blocked_pipe[0],buf,1) == 1); while (listLength(moduleUnblockedClients)) { ln = listFirst(moduleUnblockedClients); - bc = ln->value; + bc = (RedisModuleBlockedClient*)ln->value; client *c = bc->client; serverAssert(c->iel == IDX_EVENT_LOOP_MAIN); listDelNode(moduleUnblockedClients,ln); @@ -3803,7 +3811,7 @@ void moduleHandleBlockedClients(void) { * does not need to do any cleanup. Eventually the module will call the * API to unblock the client and the memory will be released. */ void moduleBlockedClientTimedOut(client *c) { - RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle; + RedisModuleBlockedClient *bc = (RedisModuleBlockedClient*)c->bpop.module_blocked_handle; RedisModuleCtx ctx = REDISMODULE_CTX_INIT; ctx.flags |= REDISMODULE_CTX_BLOCKED_TIMEOUT; ctx.module = bc->module; @@ -3873,7 +3881,7 @@ int RM_BlockedClientDisconnected(RedisModuleCtx *ctx) { * TODO: thread safe contexts do not inherit the blocked client * selected database. */ RedisModuleCtx *RM_GetThreadSafeContext(RedisModuleBlockedClient *bc) { - RedisModuleCtx *ctx = zmalloc(sizeof(*ctx), MALLOC_LOCAL); + RedisModuleCtx *ctx = (RedisModuleCtx*)zmalloc(sizeof(*ctx), MALLOC_LOCAL); RedisModuleCtx empty = REDISMODULE_CTX_INIT; memcpy(ctx,&empty,sizeof(empty)); if (bc) { @@ -3989,7 +3997,7 @@ int moduleGILAcquiredByModule(void) { * See https://redis.io/topics/notifications for more information. */ int RM_SubscribeToKeyspaceEvents(RedisModuleCtx *ctx, int types, RedisModuleNotificationFunc callback) { - RedisModuleKeyspaceSubscriber *sub = zmalloc(sizeof(*sub), MALLOC_LOCAL); + RedisModuleKeyspaceSubscriber *sub = (RedisModuleKeyspaceSubscriber*)zmalloc(sizeof(*sub), MALLOC_LOCAL); sub->module = ctx->module; sub->event_mask = types; sub->notify_callback = callback; @@ -4014,7 +4022,7 @@ void moduleNotifyKeyspaceEvent(int type, const char *event, robj *key, int dbid) type &= ~(NOTIFY_KEYEVENT | NOTIFY_KEYSPACE); while((ln = listNext(&li))) { - RedisModuleKeyspaceSubscriber *sub = ln->value; + RedisModuleKeyspaceSubscriber *sub = (RedisModuleKeyspaceSubscriber*)ln->value; /* Only notify subscribers on events matching they registration, * and avoid subscribers triggering themselves */ if ((sub->event_mask & type) && sub->active == 0) { @@ -4040,7 +4048,7 @@ void moduleUnsubscribeNotifications(RedisModule *module) { listNode *ln; listRewind(moduleKeyspaceSubscribers,&li); while((ln = listNext(&li))) { - RedisModuleKeyspaceSubscriber *sub = ln->value; + RedisModuleKeyspaceSubscriber *sub = (RedisModuleKeyspaceSubscriber*)ln->value; if (sub->module == module) { listDelNode(moduleKeyspaceSubscribers, ln); zfree(sub); @@ -4126,7 +4134,7 @@ void RM_RegisterClusterMessageReceiver(RedisModuleCtx *ctx, uint8_t type, RedisM /* Not found, let's add it. */ if (callback) { - r = zmalloc(sizeof(*r), MALLOC_LOCAL); + r = (moduleClusterReceiver*)zmalloc(sizeof(*r), MALLOC_LOCAL); r->module_id = module_id; r->module = ctx->module; r->callback = callback; @@ -4178,14 +4186,14 @@ char **RM_GetClusterNodesList(RedisModuleCtx *ctx, size_t *numnodes) { if (!server.cluster_enabled) return NULL; size_t count = dictSize(server.cluster->nodes); - char **ids = zmalloc((count+1)*REDISMODULE_NODE_ID_LEN, MALLOC_LOCAL); + char **ids = (char**)zmalloc((count+1)*REDISMODULE_NODE_ID_LEN, MALLOC_LOCAL); dictIterator *di = dictGetIterator(server.cluster->nodes); dictEntry *de; int j = 0; while((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = (clusterNode*)dictGetVal(de); if (node->flags & (CLUSTER_NODE_NOADDR|CLUSTER_NODE_HANDSHAKE)) continue; - ids[j] = zmalloc(REDISMODULE_NODE_ID_LEN, MALLOC_LOCAL); + ids[j] = (char*)zmalloc(REDISMODULE_NODE_ID_LEN, MALLOC_LOCAL); memcpy(ids[j],node->name,REDISMODULE_NODE_ID_LEN); j++; } @@ -4352,7 +4360,7 @@ int moduleTimerHandler(struct aeEventLoop *eventLoop, long long id, void *client memcpy(&expiretime,ri.key,sizeof(expiretime)); expiretime = ntohu64(expiretime); if (now >= expiretime) { - RedisModuleTimer *timer = ri.data; + RedisModuleTimer *timer = (RedisModuleTimer*)ri.data; RedisModuleCtx ctx = REDISMODULE_CTX_INIT; ctx.module = timer->module; @@ -4378,7 +4386,7 @@ int moduleTimerHandler(struct aeEventLoop *eventLoop, long long id, void *client * the specified function using `data` as argument. The returned timer ID can be * used to get information from the timer or to stop it before it fires. */ RedisModuleTimerID RM_CreateTimer(RedisModuleCtx *ctx, mstime_t period, RedisModuleTimerProc callback, void *data) { - RedisModuleTimer *timer = zmalloc(sizeof(*timer), MALLOC_LOCAL); + RedisModuleTimer *timer = (RedisModuleTimer*)zmalloc(sizeof(*timer), MALLOC_LOCAL); timer->module = ctx->module; timer->callback = callback; timer->data = data; @@ -4426,7 +4434,7 @@ RedisModuleTimerID RM_CreateTimer(RedisModuleCtx *ctx, mstime_t period, RedisMod * If not NULL, the data pointer is set to the value of the data argument when * the timer was created. */ int RM_StopTimer(RedisModuleCtx *ctx, RedisModuleTimerID id, void **data) { - RedisModuleTimer *timer = raxFind(Timers,(unsigned char*)&id,sizeof(id)); + RedisModuleTimer *timer = (RedisModuleTimer*)raxFind(Timers,(unsigned char*)&id,sizeof(id)); if (timer == raxNotFound || timer->module != ctx->module) return REDISMODULE_ERR; if (data) *data = timer->data; @@ -4442,7 +4450,7 @@ int RM_StopTimer(RedisModuleCtx *ctx, RedisModuleTimerID id, void **data) { * REDISMODULE_OK is returned. The arguments remaining or data can be NULL if * the caller does not need certain information. */ int RM_GetTimerInfo(RedisModuleCtx *ctx, RedisModuleTimerID id, uint64_t *remaining, void **data) { - RedisModuleTimer *timer = raxFind(Timers,(unsigned char*)&id,sizeof(id)); + RedisModuleTimer *timer = (RedisModuleTimer*)raxFind(Timers,(unsigned char*)&id,sizeof(id)); if (timer == raxNotFound || timer->module != ctx->module) return REDISMODULE_ERR; if (remaining) { @@ -4476,7 +4484,7 @@ int RM_GetTimerInfo(RedisModuleCtx *ctx, RedisModuleTimerID id, uint64_t *remain * Next / Prev dictionary iterator calls. */ RedisModuleDict *RM_CreateDict(RedisModuleCtx *ctx) { - struct RedisModuleDict *d = zmalloc(sizeof(*d), MALLOC_LOCAL); + struct RedisModuleDict *d = (RedisModuleDict*)zmalloc(sizeof(*d), MALLOC_LOCAL); d->rax = raxNew(); if (ctx != NULL) autoMemoryAdd(ctx,REDISMODULE_AM_DICT,d); return d; @@ -4501,25 +4509,25 @@ uint64_t RM_DictSize(RedisModuleDict *d) { * already exist, REDISMODULE_OK is returned. Otherwise if the key already * exists the function returns REDISMODULE_ERR. */ int RM_DictSetC(RedisModuleDict *d, void *key, size_t keylen, void *ptr) { - int retval = raxTryInsert(d->rax,key,keylen,ptr,NULL); + int retval = raxTryInsert(d->rax,(unsigned char*)key,keylen,ptr,NULL); return (retval == 1) ? REDISMODULE_OK : REDISMODULE_ERR; } /* Like RedisModule_DictSetC() but will replace the key with the new * value if the key already exists. */ int RM_DictReplaceC(RedisModuleDict *d, void *key, size_t keylen, void *ptr) { - int retval = raxInsert(d->rax,key,keylen,ptr,NULL); + int retval = raxInsert(d->rax,(unsigned char*)key,keylen,ptr,NULL); return (retval == 1) ? REDISMODULE_OK : REDISMODULE_ERR; } /* Like RedisModule_DictSetC() but takes the key as a RedisModuleString. */ int RM_DictSet(RedisModuleDict *d, RedisModuleString *key, void *ptr) { - return RM_DictSetC(d,ptrFromObj(key),sdslen(ptrFromObj(key)),ptr); + return RM_DictSetC(d,ptrFromObj(key),sdslen(szFromObj(key)),ptr); } /* Like RedisModule_DictReplaceC() but takes the key as a RedisModuleString. */ int RM_DictReplace(RedisModuleDict *d, RedisModuleString *key, void *ptr) { - return RM_DictReplaceC(d,ptrFromObj(key),sdslen(ptrFromObj(key)),ptr); + return RM_DictReplaceC(d,ptrFromObj(key),sdslen(szFromObj(key)),ptr); } /* Return the value stored at the specified key. The function returns NULL @@ -4528,14 +4536,14 @@ int RM_DictReplace(RedisModuleDict *d, RedisModuleString *key, void *ptr) { * be set by reference to 1 if the key does not exist, or to 0 if the key * exists. */ void *RM_DictGetC(RedisModuleDict *d, void *key, size_t keylen, int *nokey) { - void *res = raxFind(d->rax,key,keylen); + void *res = raxFind(d->rax,(unsigned char*)key,keylen); if (nokey) *nokey = (res == raxNotFound); return (res == raxNotFound) ? NULL : res; } /* Like RedisModule_DictGetC() but takes the key as a RedisModuleString. */ void *RM_DictGet(RedisModuleDict *d, RedisModuleString *key, int *nokey) { - return RM_DictGetC(d,ptrFromObj(key),sdslen(ptrFromObj(key)),nokey); + return RM_DictGetC(d,ptrFromObj(key),sdslen(szFromObj(key)),nokey); } /* Remove the specified key from the dictionary, returning REDISMODULE_OK if @@ -4546,13 +4554,13 @@ void *RM_DictGet(RedisModuleDict *d, RedisModuleString *key, int *nokey) { * a pointer to the value (for instance in order to release it), without * having to call RedisModule_DictGet() before deleting the key. */ int RM_DictDelC(RedisModuleDict *d, void *key, size_t keylen, void *oldval) { - int retval = raxRemove(d->rax,key,keylen,oldval); + int retval = raxRemove(d->rax,(unsigned char*)key,keylen,(void**)oldval); return retval ? REDISMODULE_OK : REDISMODULE_ERR; } /* Like RedisModule_DictDelC() but gets the key as a RedisModuleString. */ int RM_DictDel(RedisModuleDict *d, RedisModuleString *key, void *oldval) { - return RM_DictDelC(d,ptrFromObj(key),sdslen(ptrFromObj(key)),oldval); + return RM_DictDelC(d,ptrFromObj(key),sdslen(szFromObj(key)),oldval); } /* Return an interator, setup in order to start iterating from the specified @@ -4576,17 +4584,17 @@ int RM_DictDel(RedisModuleDict *d, RedisModuleString *key, void *oldval) { * REDISMODULE_ERR at the first call, otherwise they'll produce elements. */ RedisModuleDictIter *RM_DictIteratorStartC(RedisModuleDict *d, const char *op, void *key, size_t keylen) { - RedisModuleDictIter *di = zmalloc(sizeof(*di), MALLOC_LOCAL); + RedisModuleDictIter *di = (RedisModuleDictIter*)zmalloc(sizeof(*di), MALLOC_LOCAL); di->dict = d; raxStart(&di->ri,d->rax); - raxSeek(&di->ri,op,key,keylen); + raxSeek(&di->ri,op,(unsigned char*)key,keylen); return di; } /* Exactly like RedisModule_DictIteratorStartC, but the key is passed as a * RedisModuleString. */ RedisModuleDictIter *RM_DictIteratorStart(RedisModuleDict *d, const char *op, RedisModuleString *key) { - return RM_DictIteratorStartC(d,op,ptrFromObj(key),sdslen(ptrFromObj(key))); + return RM_DictIteratorStartC(d,op,ptrFromObj(key),sdslen(szFromObj(key))); } /* Release the iterator created with RedisModule_DictIteratorStart(). This call @@ -4604,13 +4612,13 @@ void RM_DictIteratorStop(RedisModuleDictIter *di) { * or REDISMODULE_ERR in case it was not possible to seek the specified * element. It is possible to reseek an iterator as many times as you want. */ int RM_DictIteratorReseekC(RedisModuleDictIter *di, const char *op, void *key, size_t keylen) { - return raxSeek(&di->ri,op,key,keylen); + return raxSeek(&di->ri,op,(unsigned char*)key,keylen); } /* Like RedisModule_DictIteratorReseekC() but takes the key as as a * RedisModuleString. */ int RM_DictIteratorReseek(RedisModuleDictIter *di, const char *op, RedisModuleString *key) { - return RM_DictIteratorReseekC(di,op,ptrFromObj(key),sdslen(ptrFromObj(key))); + return RM_DictIteratorReseekC(di,op,ptrFromObj(key),sdslen(szFromObj(key))); } /* Return the current item of the dictionary iterator 'di' and steps to the @@ -4666,7 +4674,7 @@ RedisModuleString *RM_DictNext(RedisModuleCtx *ctx, RedisModuleDictIter *di, voi size_t keylen; void *key = RM_DictNextC(di,&keylen,dataptr); if (key == NULL) return NULL; - return RM_CreateString(ctx,key,keylen); + return RM_CreateString(ctx,(const char*)key,keylen); } /* Like RedisModule_DictNext() but after returning the currently selected @@ -4676,7 +4684,7 @@ RedisModuleString *RM_DictPrev(RedisModuleCtx *ctx, RedisModuleDictIter *di, voi size_t keylen; void *key = RM_DictPrevC(di,&keylen,dataptr); if (key == NULL) return NULL; - return RM_CreateString(ctx,key,keylen); + return RM_CreateString(ctx,(const char*)key,keylen); } /* Compare the element currently pointed by the iterator to the specified @@ -4693,7 +4701,7 @@ RedisModuleString *RM_DictPrev(RedisModuleCtx *ctx, RedisModuleDictIter *di, voi * end of elements condition as well. */ int RM_DictCompareC(RedisModuleDictIter *di, const char *op, void *key, size_t keylen) { if (raxEOF(&di->ri)) return REDISMODULE_ERR; - int res = raxCompare(&di->ri,op,key,keylen); + int res = raxCompare(&di->ri,op,(unsigned char*)key,keylen); return res ? REDISMODULE_OK : REDISMODULE_ERR; } @@ -4701,7 +4709,7 @@ int RM_DictCompareC(RedisModuleDictIter *di, const char *op, void *key, size_t k * iterator key as a RedisModuleString. */ int RM_DictCompare(RedisModuleDictIter *di, const char *op, RedisModuleString *key) { if (raxEOF(&di->ri)) return REDISMODULE_ERR; - int res = raxCompare(&di->ri,op,ptrFromObj(key),sdslen(ptrFromObj(key))); + int res = raxCompare(&di->ri,op,(unsigned char*)szFromObj(key),sdslen(szFromObj(key))); return res ? REDISMODULE_OK : REDISMODULE_ERR; } @@ -4741,7 +4749,7 @@ void RM_GetRandomHexChars(char *dst, size_t len) { * lifetime. The API relies on the fact that it will always be valid in * the future. */ int RM_ExportSharedAPI(RedisModuleCtx *ctx, const char *apiname, void *func) { - RedisModuleSharedAPI *sapi = zmalloc(sizeof(*sapi), MALLOC_LOCAL); + RedisModuleSharedAPI *sapi = (RedisModuleSharedAPI*)zmalloc(sizeof(*sapi), MALLOC_LOCAL); sapi->module = ctx->module; sapi->func = func; if (dictAdd(server.sharedapi, (char*)apiname, sapi) != DICT_OK) { @@ -4787,10 +4795,10 @@ int RM_ExportSharedAPI(RedisModuleCtx *ctx, const char *apiname, void *func) { void *RM_GetSharedAPI(RedisModuleCtx *ctx, const char *apiname) { dictEntry *de = dictFind(server.sharedapi, apiname); if (de == NULL) return NULL; - RedisModuleSharedAPI *sapi = dictGetVal(de); + RedisModuleSharedAPI *sapi = (RedisModuleSharedAPI*)dictGetVal(de); if (listSearchKey(sapi->module->usedby,ctx->module) == NULL) { listAddNodeTail(sapi->module->usedby,ctx->module); - listAddNodeTail(ctx->module->using,sapi->module); + listAddNodeTail(ctx->module->usingMods,sapi->module); } return sapi->func; } @@ -4806,8 +4814,8 @@ int moduleUnregisterSharedAPI(RedisModule *module) { dictIterator *di = dictGetSafeIterator(server.sharedapi); dictEntry *de; while ((de = dictNext(di)) != NULL) { - const char *apiname = dictGetKey(de); - RedisModuleSharedAPI *sapi = dictGetVal(de); + const char *apiname = (const char*)dictGetKey(de); + RedisModuleSharedAPI *sapi = (RedisModuleSharedAPI*)dictGetVal(de); if (sapi->module == module) { dictDelete(server.sharedapi,apiname); zfree(sapi); @@ -4827,12 +4835,12 @@ int moduleUnregisterUsedAPI(RedisModule *module) { listNode *ln; int count = 0; - listRewind(module->using,&li); + listRewind(module->usingMods,&li); while((ln = listNext(&li))) { - RedisModule *used = ln->value; + RedisModule *used = (RedisModule*)ln->value; listNode *ln = listSearchKey(used->usedby,module); if (ln) { - listDelNode(module->using,ln); + listDelNode(module->usingMods,ln); count++; } } @@ -4850,7 +4858,7 @@ int moduleUnregisterFilters(RedisModule *module) { listRewind(module->filters,&li); while((ln = listNext(&li))) { - RedisModuleCommandFilter *filter = ln->value; + RedisModuleCommandFilter *filter = (RedisModuleCommandFilter*)ln->value; listNode *ln = listSearchKey(moduleCommandFilters,filter); if (ln) { listDelNode(moduleCommandFilters,ln); @@ -4918,7 +4926,7 @@ int moduleUnregisterFilters(RedisModule *module) { */ RedisModuleCommandFilter *RM_RegisterCommandFilter(RedisModuleCtx *ctx, RedisModuleCommandFilterFunc callback, int flags) { - RedisModuleCommandFilter *filter = zmalloc(sizeof(*filter), MALLOC_LOCAL); + RedisModuleCommandFilter *filter = (RedisModuleCommandFilter*)zmalloc(sizeof(*filter), MALLOC_LOCAL); filter->module = ctx->module; filter->callback = callback; filter->flags = flags; @@ -4954,13 +4962,10 @@ void moduleCallCommandFilters(client *c) { listNode *ln; listRewind(moduleCommandFilters,&li); - RedisModuleCommandFilterCtx filter = { - .argv = c->argv, - .argc = c->argc - }; + RedisModuleCommandFilterCtx filter = { c->argv, c->argc }; while((ln = listNext(&li))) { - RedisModuleCommandFilter *f = ln->value; + RedisModuleCommandFilter *f = (RedisModuleCommandFilter*)ln->value; /* Skip filter if REDISMODULE_CMDFILTER_NOSELF is set and module is * currently processing a command. @@ -5004,7 +5009,7 @@ int RM_CommandFilterArgInsert(RedisModuleCommandFilterCtx *fctx, int pos, RedisM if (pos < 0 || pos > fctx->argc) return REDISMODULE_ERR; - fctx->argv = zrealloc(fctx->argv, (fctx->argc+1)*sizeof(RedisModuleString *), MALLOC_LOCAL); + fctx->argv = (robj**)zrealloc(fctx->argv, (fctx->argc+1)*sizeof(RedisModuleString *), MALLOC_LOCAL); for (i = fctx->argc; i > pos; i--) { fctx->argv[i] = fctx->argv[i-1]; } @@ -5060,7 +5065,7 @@ uint64_t dictCStringKeyHash(const void *key) { int dictCStringKeyCompare(void *privdata, const void *key1, const void *key2) { UNUSED(privdata); - return strcmp(key1,key2) == 0; + return strcmp((char*)key1,(char*)key2) == 0; } dictType moduleAPIDictType = { @@ -5132,7 +5137,7 @@ void moduleLoadFromQueue(void) { listRewind(server.loadmodule_queue,&li); while((ln = listNext(&li))) { - struct moduleLoadQueueEntry *loadmod = ln->value; + struct moduleLoadQueueEntry *loadmod = (moduleLoadQueueEntry*)ln->value; if (moduleLoad(loadmod->path,(void **)loadmod->argv,loadmod->argc) == C_ERR) { @@ -5156,10 +5161,10 @@ void moduleUnregisterCommands(struct RedisModule *module) { dictIterator *di = dictGetSafeIterator(server.commands); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct redisCommand *cmd = dictGetVal(de); + struct redisCommand *cmd = (redisCommand*)dictGetVal(de); if (cmd->proc == RedisModuleCommandDispatcher) { RedisModuleCommandProxy *cp = - (void*)(unsigned long)cmd->getkeys_proc; + (RedisModuleCommandProxy*)(unsigned long)cmd->getkeys_proc; sds cmdname = (sds)cp->rediscmd->name; if (cp->module == module) { dictDelete(server.commands,cmdname); @@ -5222,7 +5227,7 @@ int moduleLoad(const char *path, void **module_argv, int module_argc) { * * ENONET: No such module having the specified name. * * EBUSY: The module exports a new data type and can only be reloaded. */ int moduleUnload(sds name) { - struct RedisModule *module = dictFetchValue(modules,name); + struct RedisModule *module = (RedisModule*)dictFetchValue(modules,name); if (module == NULL) { errno = ENOENT; @@ -5247,7 +5252,7 @@ int moduleUnload(sds name) { /* Unload the dynamic library. */ if (dlclose(module->handle) == -1) { - char *error = dlerror(); + const char *error = dlerror(); if (error == NULL) error = "Unknown error"; serverLog(LL_WARNING,"Error when trying to close the %s module: %s", module->name, error); @@ -5270,8 +5275,8 @@ void addReplyLoadedModules(client *c) { addReplyArrayLen(c,dictSize(modules)); while ((de = dictNext(di)) != NULL) { - sds name = dictGetKey(de); - struct RedisModule *module = dictGetVal(de); + sds name = (sds)dictGetKey(de); + struct RedisModule *module = (RedisModule*)dictGetVal(de); addReplyMapLen(c,2); addReplyBulkCString(c,"name"); addReplyBulkCBuffer(c,name,sdslen(name)); @@ -5285,7 +5290,7 @@ void addReplyLoadedModules(client *c) { * * MODULE LOAD [args...] */ void moduleCommand(client *c) { - char *subcmd = ptrFromObj(c->argv[1]); + char *subcmd = szFromObj(c->argv[1]); if (c->argc == 2 && !strcasecmp(subcmd,"help")) { const char *help[] = { "LIST -- Return a list of loaded modules.", @@ -5304,16 +5309,16 @@ NULL argv = &c->argv[3]; } - if (moduleLoad(ptrFromObj(c->argv[2]),(void **)argv,argc) == C_OK) + if (moduleLoad(szFromObj(c->argv[2]),(void **)argv,argc) == C_OK) addReply(c,shared.ok); else addReplyError(c, "Error loading the extension. Please check the server logs."); } else if (!strcasecmp(subcmd,"unload") && c->argc == 3) { - if (moduleUnload(ptrFromObj(c->argv[2])) == C_OK) + if (moduleUnload(szFromObj(c->argv[2])) == C_OK) addReply(c,shared.ok); else { - char *errmsg; + const char *errmsg; switch(errno) { case ENOENT: errmsg = "no such module with that name"; diff --git a/src/multi.c b/src/multi.cpp similarity index 94% rename from src/multi.c rename to src/multi.cpp index 65a400614..caf8555b2 100644 --- a/src/multi.c +++ b/src/multi.cpp @@ -58,12 +58,12 @@ void queueMultiCommand(client *c) { multiCmd *mc; int j; - c->mstate.commands = zrealloc(c->mstate.commands, + c->mstate.commands = (multiCmd*)zrealloc(c->mstate.commands, sizeof(multiCmd)*(c->mstate.count+1), MALLOC_LOCAL); mc = c->mstate.commands+c->mstate.count; mc->cmd = c->cmd; mc->argc = c->argc; - mc->argv = zmalloc(sizeof(robj*)*c->argc, MALLOC_LOCAL); + mc->argv = (robj**)zmalloc(sizeof(robj*)*c->argc, MALLOC_LOCAL); memcpy(mc->argv,c->argv,sizeof(robj*)*c->argc); for (j = 0; j < c->argc; j++) incrRefCount(mc->argv[j]); @@ -201,7 +201,7 @@ void execCommand(client *c) { * rest was not. We need to make sure to at least terminate the * backlog with the final EXEC. */ if (server.repl_backlog && was_master && !is_master) { - char *execcmd = "*1\r\n$4\r\nEXEC\r\n"; + const char *execcmd = "*1\r\n$4\r\nEXEC\r\n"; feedReplicationBacklog(execcmd,strlen(execcmd)); } } @@ -243,12 +243,12 @@ void watchForKey(client *c, robj *key) { /* Check if we are already watching for this key */ listRewind(c->watched_keys,&li); while((ln = listNext(&li))) { - wk = listNodeValue(ln); + wk = (watchedKey*)listNodeValue(ln); if (wk->db == c->db && equalStringObjects(key,wk->key)) return; /* Key already watched */ } /* This key is not already watched in this DB. Let's add it */ - clients = dictFetchValue(c->db->watched_keys,key); + clients = (decltype(clients)) dictFetchValue(c->db->watched_keys,key); if (!clients) { clients = listCreate(); dictAdd(c->db->watched_keys,key,clients); @@ -256,7 +256,7 @@ void watchForKey(client *c, robj *key) { } listAddNodeTail(clients,c); /* Add the new key to the list of keys watched by this client */ - wk = zmalloc(sizeof(*wk), MALLOC_SHARED); + wk = (watchedKey*)zmalloc(sizeof(*wk), MALLOC_SHARED); wk->key = key; wk->db = c->db; incrRefCount(key); @@ -277,8 +277,8 @@ void unwatchAllKeys(client *c) { /* Lookup the watched key -> clients list and remove the client * from the list */ - wk = listNodeValue(ln); - clients = dictFetchValue(wk->db->watched_keys, wk->key); + wk = (watchedKey*)listNodeValue(ln); + clients = (decltype(clients))dictFetchValue(wk->db->watched_keys, wk->key); serverAssertWithInfo(c,NULL,clients != NULL); listDelNode(clients,listSearchKey(clients,c)); /* Kill the entry at all if this was the only client */ @@ -300,14 +300,14 @@ void touchWatchedKey(redisDb *db, robj *key) { listNode *ln; if (dictSize(db->watched_keys) == 0) return; - clients = dictFetchValue(db->watched_keys, key); + clients = (list*)dictFetchValue(db->watched_keys, key); if (!clients) return; /* Mark all the clients watching this key as CLIENT_DIRTY_CAS */ /* Check if we are already watching for this key */ listRewind(clients,&li); while((ln = listNext(&li))) { - client *c = listNodeValue(ln); + client *c = (client*)listNodeValue(ln); c->flags |= CLIENT_DIRTY_CAS; } @@ -325,10 +325,10 @@ void touchWatchedKeysOnFlush(int dbid) { /* For every client, check all the waited keys */ listRewind(server.clients,&li1); while((ln = listNext(&li1))) { - client *c = listNodeValue(ln); + client *c = (client*)listNodeValue(ln); listRewind(c->watched_keys,&li2); while((ln = listNext(&li2))) { - watchedKey *wk = listNodeValue(ln); + watchedKey *wk = (watchedKey*)listNodeValue(ln); /* For every watched key matching the specified DB, if the * key exists, mark the client as dirty, as the key will be diff --git a/src/networking.cpp b/src/networking.cpp index ed750c0ae..5ba82b588 100644 --- a/src/networking.cpp +++ b/src/networking.cpp @@ -1991,17 +1991,6 @@ void processInputBuffer(client *c, int callFlags) { if (c->reqtype == PROTO_REQ_INLINE) { if (processInlineBuffer(c) != C_OK) break; - /* If the Gopher mode and we got zero or one argument, process - * the request in Gopher mode. */ - if (server.gopher_enabled && - ((c->argc == 1 && ((char*)(ptrFromObj(c->argv[0])))[0] == '/') || - c->argc == 0)) - { - processGopherRequest(c); - resetClient(c); - c->flags |= CLIENT_CLOSE_AFTER_REPLY; - break; - } } else if (c->reqtype == PROTO_REQ_MULTIBULK) { if (processMultibulkBuffer(c) != C_OK) break; } else { diff --git a/src/notify.c b/src/notify.cpp similarity index 98% rename from src/notify.c rename to src/notify.cpp index e2726be40..da7b53407 100644 --- a/src/notify.c +++ b/src/notify.cpp @@ -119,7 +119,7 @@ void notifyKeyspaceEvent(int type, const char *event, robj *key, int dbid) { len = ll2string(buf,sizeof(buf),dbid); chan = sdscatlen(chan, buf, len); chan = sdscatlen(chan, "__:", 3); - chan = sdscatsds(chan, ptrFromObj(key)); + chan = sdscatsds(chan, szFromObj(key)); chanobj = createObject(OBJ_STRING, chan); pubsubPublishMessage(chanobj, eventobj); decrRefCount(chanobj); @@ -131,7 +131,7 @@ void notifyKeyspaceEvent(int type, const char *event, robj *key, int dbid) { if (len == -1) len = ll2string(buf,sizeof(buf),dbid); chan = sdscatlen(chan, buf, len); chan = sdscatlen(chan, "__:", 3); - chan = sdscatsds(chan, ptrFromObj(eventobj)); + chan = sdscatsds(chan, szFromObj(eventobj)); chanobj = createObject(OBJ_STRING, chan); pubsubPublishMessage(chanobj, key); decrRefCount(chanobj); diff --git a/src/object.c b/src/object.cpp similarity index 92% rename from src/object.c rename to src/object.cpp index 7112e0593..2799537e1 100644 --- a/src/object.c +++ b/src/object.cpp @@ -39,7 +39,7 @@ /* ===================== Creation and parsing of objects ==================== */ robj *createObject(int type, void *ptr) { - robj *o = zmalloc(sizeof(*o), MALLOC_SHARED); + robj *o = (robj*)zmalloc(sizeof(*o), MALLOC_SHARED); o->type = type; o->encoding = OBJ_ENCODING_RAW; o->m_ptr = ptr; @@ -85,8 +85,8 @@ robj *createEmbeddedStringObject(const char *ptr, size_t len) { size_t allocsize = sizeof(struct sdshdr8)+len+1; if (allocsize < sizeof(void*)) allocsize = sizeof(void*); - robj *o = zmalloc(sizeof(robj)+allocsize-sizeof(o->m_ptr), MALLOC_SHARED); - struct sdshdr8 *sh = (void*)(&o->m_ptr); + robj *o = (robj*)zmalloc(sizeof(robj)+allocsize-sizeof(o->m_ptr), MALLOC_SHARED); + struct sdshdr8 *sh = (sdshdr8*)(&o->m_ptr); o->type = OBJ_STRING; o->encoding = OBJ_ENCODING_EMBSTR; @@ -101,12 +101,12 @@ robj *createEmbeddedStringObject(const char *ptr, size_t len) { sh->alloc = len; sh->flags = SDS_TYPE_8; if (ptr == SDS_NOINIT) - sh->buf[len] = '\0'; + sh->buf()[len] = '\0'; else if (ptr) { - memcpy(sh->buf,ptr,len); - sh->buf[len] = '\0'; + memcpy(sh->buf(),ptr,len); + sh->buf()[len] = '\0'; } else { - memset(sh->buf,0,len+1); + memset(sh->buf(),0,len+1); } return o; } @@ -199,9 +199,9 @@ robj *dupStringObject(const robj *o) { switch(o->encoding) { case OBJ_ENCODING_RAW: - return createRawStringObject(ptrFromObj(o),sdslen(ptrFromObj(o))); + return createRawStringObject(szFromObj(o),sdslen(szFromObj(o))); case OBJ_ENCODING_EMBSTR: - return createEmbeddedStringObject(ptrFromObj(o),sdslen(ptrFromObj(o))); + return createEmbeddedStringObject(szFromObj(o),sdslen(szFromObj(o))); case OBJ_ENCODING_INT: d = createObject(OBJ_STRING, NULL); d->encoding = OBJ_ENCODING_INT; @@ -249,7 +249,7 @@ robj *createHashObject(void) { } robj *createZsetObject(void) { - zset *zs = zmalloc(sizeof(*zs), MALLOC_SHARED); + zset *zs = (zset*)zmalloc(sizeof(*zs), MALLOC_SHARED); robj *o; zs->pdict = dictCreate(&zsetDictType,NULL); @@ -274,7 +274,7 @@ robj *createStreamObject(void) { } robj *createModuleObject(moduleType *mt, void *value) { - moduleValue *mv = zmalloc(sizeof(*mv), MALLOC_SHARED); + moduleValue *mv = (moduleValue*)zmalloc(sizeof(*mv), MALLOC_SHARED); mv->type = mt; mv->value = value; return createObject(OBJ_MODULE,mv); @@ -282,13 +282,13 @@ robj *createModuleObject(moduleType *mt, void *value) { void freeStringObject(robj *o) { if (o->encoding == OBJ_ENCODING_RAW) { - sdsfree(ptrFromObj(o)); + sdsfree(szFromObj(o)); } } void freeListObject(robj *o) { if (o->encoding == OBJ_ENCODING_QUICKLIST) { - quicklistRelease(ptrFromObj(o)); + quicklistRelease((quicklist*)ptrFromObj(o)); } else { serverPanic("Unknown list encoding type"); } @@ -311,7 +311,7 @@ void freeZsetObject(robj *o) { zset *zs; switch (o->encoding) { case OBJ_ENCODING_SKIPLIST: - zs = ptrFromObj(o); + zs = (zset*)ptrFromObj(o); dictRelease(zs->pdict); zslFree(zs->zsl); zfree(zs); @@ -339,13 +339,13 @@ void freeHashObject(robj *o) { } void freeModuleObject(robj *o) { - moduleValue *mv = ptrFromObj(o); + moduleValue *mv = (moduleValue*)ptrFromObj(o); mv->type->free(mv->value); zfree(mv); } void freeStreamObject(robj *o) { - freeStream(ptrFromObj(o)); + freeStream((stream*)ptrFromObj(o)); } void incrRefCount(robj *o) { @@ -375,7 +375,7 @@ void decrRefCount(robj *o) { * as free method in data structures that expect a 'void free_object(void*)' * prototype for the free method. */ void decrRefCountVoid(void *o) { - decrRefCount(o); + decrRefCount((robj*)o); } /* This function set the ref count to zero without freeing the object. @@ -413,7 +413,7 @@ int isObjectRepresentableAsLongLong(robj *o, long long *llval) { if (llval) *llval = (long) ptrFromObj(o); return C_OK; } else { - return isSdsRepresentableAsLongLong(ptrFromObj(o),llval); + return isSdsRepresentableAsLongLong(szFromObj(o),llval); } } @@ -423,16 +423,16 @@ int isObjectRepresentableAsLongLong(robj *o, long long *llval) { * wasting too much time in allocations when appending to the string. */ void trimStringObjectIfNeeded(robj *o) { if (o->encoding == OBJ_ENCODING_RAW && - sdsavail(ptrFromObj(o)) > sdslen(ptrFromObj(o))/10) + sdsavail(szFromObj(o)) > sdslen(szFromObj(o))/10) { - o->m_ptr = sdsRemoveFreeSpace(ptrFromObj(o)); + o->m_ptr = sdsRemoveFreeSpace(szFromObj(o)); } } /* Try to encode a string object in order to save space */ robj *tryObjectEncoding(robj *o) { long value; - sds s = ptrFromObj(o); + sds s = szFromObj(o); size_t len; /* Make sure this is a string object, the only type we encode @@ -469,7 +469,7 @@ robj *tryObjectEncoding(robj *o) { incrRefCount(shared.integers[value]); return shared.integers[value]; } else { - if (o->encoding == OBJ_ENCODING_RAW) sdsfree(ptrFromObj(o)); + if (o->encoding == OBJ_ENCODING_RAW) sdsfree(szFromObj(o)); o->encoding = OBJ_ENCODING_INT; o->m_ptr = (void*) value; return o; @@ -542,14 +542,14 @@ int compareStringObjectsWithFlags(robj *a, robj *b, int flags) { if (a == b) return 0; if (sdsEncodedObject(a)) { - astr = ptrFromObj(a); + astr = szFromObj(a); alen = sdslen(astr); } else { alen = ll2string(bufa,sizeof(bufa),(long) ptrFromObj(a)); astr = bufa; } if (sdsEncodedObject(b)) { - bstr = ptrFromObj(b); + bstr = szFromObj(b); blen = sdslen(bstr); } else { blen = ll2string(bufb,sizeof(bufb),(long) ptrFromObj(b)); @@ -595,7 +595,7 @@ int equalStringObjects(robj *a, robj *b) { size_t stringObjectLen(robj *o) { serverAssertWithInfo(NULL,o,o->type == OBJ_STRING); if (sdsEncodedObject(o)) { - return sdslen(ptrFromObj(o)); + return sdslen(szFromObj(o)); } else { return sdigits10((long)ptrFromObj(o)); } @@ -611,10 +611,10 @@ int getDoubleFromObject(const robj *o, double *target) { serverAssertWithInfo(NULL,o,o->type == OBJ_STRING); if (sdsEncodedObject(o)) { errno = 0; - value = strtod(ptrFromObj(o), &eptr); - if (sdslen(ptrFromObj(o)) == 0 || - isspace(((const char*)ptrFromObj(o))[0]) || - (size_t)(eptr-(char*)ptrFromObj(o)) != sdslen(ptrFromObj(o)) || + value = strtod(szFromObj(o), &eptr); + if (sdslen(szFromObj(o)) == 0 || + isspace(((const char*)szFromObj(o))[0]) || + (size_t)(eptr-(char*)szFromObj(o)) != sdslen(szFromObj(o)) || (errno == ERANGE && (value == HUGE_VAL || value == -HUGE_VAL || value == 0)) || isnan(value)) @@ -653,16 +653,16 @@ int getLongDoubleFromObject(robj *o, long double *target) { serverAssertWithInfo(NULL,o,o->type == OBJ_STRING); if (sdsEncodedObject(o)) { errno = 0; - value = strtold(ptrFromObj(o), &eptr); - if (sdslen(ptrFromObj(o)) == 0 || - isspace(((const char*)ptrFromObj(o))[0]) || - (size_t)(eptr-(char*)ptrFromObj(o)) != sdslen(ptrFromObj(o)) || + value = strtold(szFromObj(o), &eptr); + if (sdslen(szFromObj(o)) == 0 || + isspace(((const char*)szFromObj(o))[0]) || + (size_t)(eptr-(char*)szFromObj(o)) != sdslen(szFromObj(o)) || (errno == ERANGE && (value == HUGE_VAL || value == -HUGE_VAL || value == 0)) || isnan(value)) return C_ERR; } else if (o->encoding == OBJ_ENCODING_INT) { - value = (long)ptrFromObj(o); + value = (long)szFromObj(o); } else { serverPanic("Unknown string encoding"); } @@ -693,7 +693,7 @@ int getLongLongFromObject(robj *o, long long *target) { } else { serverAssertWithInfo(NULL,o,o->type == OBJ_STRING); if (sdsEncodedObject(o)) { - if (string2ll(ptrFromObj(o),sdslen(ptrFromObj(o)),&value) == 0) return C_ERR; + if (string2ll(szFromObj(o),sdslen(szFromObj(o)),&value) == 0) return C_ERR; } else if (o->encoding == OBJ_ENCODING_INT) { value = (long)ptrFromObj(o); } else { @@ -734,7 +734,7 @@ int getLongFromObjectOrReply(client *c, robj *o, long *target, const char *msg) return C_OK; } -char *strEncoding(int encoding) { +const char *strEncoding(int encoding) { switch(encoding) { case OBJ_ENCODING_RAW: return "raw"; case OBJ_ENCODING_INT: return "int"; @@ -790,15 +790,15 @@ size_t objectComputeSize(robj *o, size_t sample_size) { if(o->encoding == OBJ_ENCODING_INT) { asize = sizeof(*o); } else if(o->encoding == OBJ_ENCODING_RAW) { - asize = sdsAllocSize(ptrFromObj(o))+sizeof(*o); + asize = sdsAllocSize(szFromObj(o))+sizeof(*o); } else if(o->encoding == OBJ_ENCODING_EMBSTR) { - asize = sdslen(ptrFromObj(o))+2+sizeof(*o); + asize = sdslen(szFromObj(o))+2+sizeof(*o); } else { serverPanic("Unknown string encoding"); } } else if (o->type == OBJ_LIST) { if (o->encoding == OBJ_ENCODING_QUICKLIST) { - quicklist *ql = ptrFromObj(o); + quicklist *ql = (quicklist*)ptrFromObj(o); quicklistNode *node = ql->head; asize = sizeof(*o)+sizeof(quicklist); do { @@ -807,41 +807,41 @@ size_t objectComputeSize(robj *o, size_t sample_size) { } while ((node = node->next) && samples < sample_size); asize += (double)elesize/samples*ql->len; } else if (o->encoding == OBJ_ENCODING_ZIPLIST) { - asize = sizeof(*o)+ziplistBlobLen(ptrFromObj(o)); + asize = sizeof(*o)+ziplistBlobLen((unsigned char*)ptrFromObj(o)); } else { serverPanic("Unknown list encoding"); } } else if (o->type == OBJ_SET) { if (o->encoding == OBJ_ENCODING_HT) { - d = ptrFromObj(o); + d = (dict*)ptrFromObj(o); di = dictGetIterator(d); asize = sizeof(*o)+sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d)); while((de = dictNext(di)) != NULL && samples < sample_size) { - ele = dictGetKey(de); + ele = (sds)dictGetKey(de); elesize += sizeof(struct dictEntry) + sdsAllocSize(ele); samples++; } dictReleaseIterator(di); if (samples) asize += (double)elesize/samples*dictSize(d); } else if (o->encoding == OBJ_ENCODING_INTSET) { - intset *is = ptrFromObj(o); + intset *is = (intset*)ptrFromObj(o); asize = sizeof(*o)+sizeof(*is)+is->encoding*is->length; } else { serverPanic("Unknown set encoding"); } } else if (o->type == OBJ_ZSET) { if (o->encoding == OBJ_ENCODING_ZIPLIST) { - asize = sizeof(*o)+(ziplistBlobLen(ptrFromObj(o))); + asize = sizeof(*o)+(ziplistBlobLen((unsigned char*)ptrFromObj(o))); } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { d = ((zset*)ptrFromObj(o))->pdict; zskiplist *zsl = ((zset*)ptrFromObj(o))->zsl; - zskiplistNode *znode = zsl->header->level[0].forward; + zskiplistNode *znode = zsl->header->level(0)->forward; asize = sizeof(*o)+sizeof(zset)+(sizeof(struct dictEntry*)*dictSlots(d)); while(znode != NULL && samples < sample_size) { elesize += sdsAllocSize(znode->ele); elesize += sizeof(struct dictEntry) + zmalloc_size(znode); samples++; - znode = znode->level[0].forward; + znode = znode->level(0)->forward; } if (samples) asize += (double)elesize/samples*dictSize(d); } else { @@ -849,14 +849,14 @@ size_t objectComputeSize(robj *o, size_t sample_size) { } } else if (o->type == OBJ_HASH) { if (o->encoding == OBJ_ENCODING_ZIPLIST) { - asize = sizeof(*o)+(ziplistBlobLen(ptrFromObj(o))); + asize = sizeof(*o)+(ziplistBlobLen((unsigned char*)ptrFromObj(o))); } else if (o->encoding == OBJ_ENCODING_HT) { - d = ptrFromObj(o); + d = (dict*)ptrFromObj(o); di = dictGetIterator(d); asize = sizeof(*o)+sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d)); while((de = dictNext(di)) != NULL && samples < sample_size) { - ele = dictGetKey(de); - ele2 = dictGetVal(de); + ele = (sds)dictGetKey(de); + ele2 = (sds)dictGetVal(de); elesize += sdsAllocSize(ele) + sdsAllocSize(ele2); elesize += sizeof(struct dictEntry); samples++; @@ -867,7 +867,7 @@ size_t objectComputeSize(robj *o, size_t sample_size) { serverPanic("Unknown hash encoding"); } } else if (o->type == OBJ_STREAM) { - stream *s = ptrFromObj(o); + stream *s = (stream*)ptrFromObj(o); asize = sizeof(*o); asize += streamRadixTreeMemoryUsage(s->prax); @@ -880,7 +880,7 @@ size_t objectComputeSize(robj *o, size_t sample_size) { raxSeek(&ri,"^",NULL,0); size_t lpsize = 0, samples = 0; while(samples < sample_size && raxNext(&ri)) { - unsigned char *lp = ri.data; + unsigned char *lp = (unsigned char*)ri.data; lpsize += lpBytes(lp); samples++; } @@ -893,7 +893,7 @@ size_t objectComputeSize(robj *o, size_t sample_size) { * if there are a few elements in the radix tree. */ raxSeek(&ri,"$",NULL,0); raxNext(&ri); - asize += lpBytes(ri.data); + asize += lpBytes((unsigned char*)ri.data); } raxStop(&ri); @@ -905,7 +905,7 @@ size_t objectComputeSize(robj *o, size_t sample_size) { raxStart(&ri,s->cgroups); raxSeek(&ri,"^",NULL,0); while(raxNext(&ri)) { - streamCG *cg = ri.data; + streamCG *cg = (streamCG*)ri.data; asize += sizeof(*cg); asize += streamRadixTreeMemoryUsage(cg->pel); asize += sizeof(streamNACK)*raxSize(cg->pel); @@ -916,7 +916,7 @@ size_t objectComputeSize(robj *o, size_t sample_size) { raxStart(&cri,cg->consumers); raxSeek(&cri,"^",NULL,0); while(raxNext(&cri)) { - streamConsumer *consumer = cri.data; + streamConsumer *consumer = (streamConsumer*)cri.data; asize += sizeof(*consumer); asize += sdslen(consumer->name); asize += streamRadixTreeMemoryUsage(consumer->pel); @@ -928,7 +928,7 @@ size_t objectComputeSize(robj *o, size_t sample_size) { raxStop(&ri); } } else if (o->type == OBJ_MODULE) { - moduleValue *mv = ptrFromObj(o); + moduleValue *mv = (moduleValue*)ptrFromObj(o); moduleType *mt = mv->type; if (mt->mem_usage != NULL) { asize = mt->mem_usage(mv->value); @@ -956,7 +956,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) { size_t mem_total = 0; size_t mem = 0; size_t zmalloc_used = zmalloc_used_memory(); - struct redisMemOverhead *mh = zcalloc(sizeof(*mh), MALLOC_LOCAL); + struct redisMemOverhead *mh = (redisMemOverhead*)zcalloc(sizeof(*mh), MALLOC_LOCAL); mh->total_allocated = zmalloc_used; mh->startup_allocated = server.initial_memory_usage; @@ -993,7 +993,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) { listRewind(server.slaves,&li); while((ln = listNext(&li))) { - client *c = listNodeValue(ln); + client *c = (client*)listNodeValue(ln); if (c->flags & CLIENT_CLOSE_ASAP) continue; mem += getClientOutputBufferMemoryUsage(c); @@ -1011,7 +1011,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) { listRewind(server.clients,&li); while((ln = listNext(&li))) { - client *c = listNodeValue(ln); + client *c = (client*)listNodeValue(ln); if (c->flags & CLIENT_SLAVE && !(c->flags & CLIENT_MONITOR)) continue; mem += getClientOutputBufferMemoryUsage(c); @@ -1037,7 +1037,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) { dictSlots(server.repl_scriptcache_dict) * sizeof(dictEntry*); if (listLength(server.repl_scriptcache_fifo) > 0) { mem += listLength(server.repl_scriptcache_fifo) * (sizeof(listNode) + - sdsZmallocSize(listNodeValue(listFirst(server.repl_scriptcache_fifo)))); + sdsZmallocSize((sds)listNodeValue(listFirst(server.repl_scriptcache_fifo)))); } mh->lua_caches = mem; mem_total+=mem; @@ -1048,7 +1048,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) { if (keyscount==0) continue; mh->total_keys += keyscount; - mh->db = zrealloc(mh->db,sizeof(mh->db[0])*(mh->num_dbs+1), MALLOC_LOCAL); + mh->db = (decltype(mh->db))zrealloc(mh->db,sizeof(mh->db[0])*(mh->num_dbs+1), MALLOC_LOCAL); mh->db[mh->num_dbs].dbid = j; mem = dictSize(db->pdict) * sizeof(dictEntry) + @@ -1256,7 +1256,7 @@ robj *objectCommandLookupOrReply(client *c, robj *key, robj *reply) { void objectCommand(client *c) { robj *o; - if (c->argc == 2 && !strcasecmp(ptrFromObj(c->argv[1]),"help")) { + if (c->argc == 2 && !strcasecmp(szFromObj(c->argv[1]),"help")) { const char *help[] = { "ENCODING -- Return the kind of internal representation used in order to store the value associated with a key.", "FREQ -- Return the access frequency index of the key. The returned integer is proportional to the logarithm of the recent access frequency of the key.", @@ -1265,15 +1265,15 @@ void objectCommand(client *c) { NULL }; addReplyHelp(c, help); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"refcount") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"refcount") && c->argc == 3) { if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.null[c->resp])) == NULL) return; addReplyLongLong(c,o->refcount); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"encoding") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"encoding") && c->argc == 3) { if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.null[c->resp])) == NULL) return; addReplyBulkCString(c,strEncoding(o->encoding)); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"idletime") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"idletime") && c->argc == 3) { if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.null[c->resp])) == NULL) return; if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) { @@ -1281,7 +1281,7 @@ NULL return; } addReplyLongLong(c,estimateObjectIdleTime(o)/1000); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"freq") && c->argc == 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"freq") && c->argc == 3) { if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.null[c->resp])) == NULL) return; if (!(server.maxmemory_policy & MAXMEMORY_FLAG_LFU)) { @@ -1303,7 +1303,7 @@ NULL * * Usage: MEMORY usage */ void memoryCommand(client *c) { - if (!strcasecmp(ptrFromObj(c->argv[1]),"help") && c->argc == 2) { + if (!strcasecmp(szFromObj(c->argv[1]),"help") && c->argc == 2) { const char *help[] = { "DOCTOR - Return memory problems reports.", "MALLOC-STATS -- Return internal statistics report from the memory allocator.", @@ -1313,11 +1313,11 @@ void memoryCommand(client *c) { NULL }; addReplyHelp(c, help); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"usage") && c->argc >= 3) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"usage") && c->argc >= 3) { dictEntry *de; long long samples = OBJ_COMPUTE_SIZE_DEF_SAMPLES; for (int j = 3; j < c->argc; j++) { - if (!strcasecmp(ptrFromObj(c->argv[j]),"samples") && + if (!strcasecmp(szFromObj(c->argv[j]),"samples") && j+1 < c->argc) { if (getLongLongFromObjectOrReply(c,c->argv[j+1],&samples,NULL) @@ -1337,11 +1337,11 @@ NULL addReplyNull(c); return; } - size_t usage = objectComputeSize(dictGetVal(de),samples); - usage += sdsAllocSize(dictGetKey(de)); + size_t usage = objectComputeSize((robj*)dictGetVal(de),samples); + usage += sdsAllocSize((sds)dictGetKey(de)); usage += sizeof(dictEntry); addReplyLongLong(c,usage); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"stats") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"stats") && c->argc == 2) { struct redisMemOverhead *mh = getMemoryOverheadData(); addReplyMapLen(c,25+mh->num_dbs); @@ -1435,7 +1435,7 @@ NULL addReplyLongLong(c,mh->total_frag_bytes); freeMemoryOverheadData(mh); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"malloc-stats") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"malloc-stats") && c->argc == 2) { #if defined(USE_JEMALLOC) sds info = sdsempty(); je_malloc_stats_print(inputCatSds, &info, NULL); @@ -1443,10 +1443,10 @@ NULL #else addReplyBulkCString(c,"Stats not supported for the current allocator"); #endif - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"doctor") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"doctor") && c->argc == 2) { sds report = getMemoryDoctorReport(); addReplyBulkSds(c,report); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"purge") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"purge") && c->argc == 2) { #if defined(USE_JEMALLOC) char tmp[32]; unsigned narenas = 0; diff --git a/src/pubsub.c b/src/pubsub.cpp similarity index 92% rename from src/pubsub.c rename to src/pubsub.cpp index e7815a2e8..e79073e02 100644 --- a/src/pubsub.c +++ b/src/pubsub.cpp @@ -121,14 +121,14 @@ void addReplyPubsubPatUnsubscribed(client *c, robj *pattern) { *----------------------------------------------------------------------------*/ void freePubsubPattern(void *p) { - pubsubPattern *pat = p; + pubsubPattern *pat = (pubsubPattern *)p; decrRefCount(pat->pattern); zfree(pat); } int listMatchPubsubPattern(void *a, void *b) { - pubsubPattern *pa = a, *pb = b; + pubsubPattern *pa = (pubsubPattern*)a, *pb = (pubsubPattern*)b; return (pa->pclient == pb->pclient) && (equalStringObjects(pa->pattern,pb->pattern)); @@ -158,7 +158,7 @@ int pubsubSubscribeChannel(client *c, robj *channel) { dictAdd(server.pubsub_channels,channel,clients); incrRefCount(channel); } else { - clients = dictGetVal(de); + clients = (list*)dictGetVal(de); } listAddNodeTail(clients,c); } @@ -183,7 +183,7 @@ int pubsubUnsubscribeChannel(client *c, robj *channel, int notify) { /* Remove the client from the channel -> clients list hash table */ de = dictFind(server.pubsub_channels,channel); serverAssertWithInfo(c,NULL,de != NULL); - clients = dictGetVal(de); + clients = (list*)dictGetVal(de); ln = listSearchKey(clients,c); serverAssertWithInfo(c,NULL,ln != NULL); listDelNode(clients,ln); @@ -209,7 +209,7 @@ int pubsubSubscribePattern(client *c, robj *pattern) { pubsubPattern *pat; listAddNodeTail(c->pubsub_patterns,pattern); incrRefCount(pattern); - pat = zmalloc(sizeof(*pat), MALLOC_LOCAL); + pat = (pubsubPattern*)zmalloc(sizeof(*pat), MALLOC_LOCAL); pat->pattern = getDecodedObject(pattern); pat->pclient = c; listAddNodeTail(server.pubsub_patterns,pat); @@ -249,7 +249,7 @@ int pubsubUnsubscribeAllChannels(client *c, int notify) { int count = 0; while((de = dictNext(di)) != NULL) { - robj *channel = dictGetKey(de); + robj *channel = (robj*)dictGetKey(de); count += pubsubUnsubscribeChannel(c,channel,notify); } @@ -268,7 +268,7 @@ int pubsubUnsubscribeAllPatterns(client *c, int notify) { listRewind(c->pubsub_patterns,&li); while ((ln = listNext(&li)) != NULL) { - robj *pattern = ln->value; + robj *pattern = (robj*)ln->value; count += pubsubUnsubscribePattern(c,pattern,notify); } @@ -286,13 +286,13 @@ int pubsubPublishMessage(robj *channel, robj *message) { /* Send to clients listening for that channel */ de = dictFind(server.pubsub_channels,channel); if (de) { - list *list = dictGetVal(de); + list *list = reinterpret_cast<::list*>(dictGetVal(de)); listNode *ln; listIter li; listRewind(list,&li); while ((ln = listNext(&li)) != NULL) { - client *c = ln->value; + client *c = reinterpret_cast(ln->value); fastlock_lock(&c->lock); addReplyPubsubMessage(c,channel,message); fastlock_unlock(&c->lock); @@ -304,12 +304,12 @@ int pubsubPublishMessage(robj *channel, robj *message) { listRewind(server.pubsub_patterns,&li); channel = getDecodedObject(channel); while ((ln = listNext(&li)) != NULL) { - pubsubPattern *pat = ln->value; + pubsubPattern *pat = (pubsubPattern*)ln->value; if (stringmatchlen((char*)ptrFromObj(pat->pattern), - sdslen(ptrFromObj(pat->pattern)), + sdslen(szFromObj(pat->pattern)), (char*)ptrFromObj(channel), - sdslen(ptrFromObj(channel)),0)) + sdslen(szFromObj(channel)),0)) { fastlock_lock(&pat->pclient->lock); addReplyPubsubPatMessage(pat->pclient, @@ -380,7 +380,7 @@ void publishCommand(client *c) { /* PUBSUB command for Pub/Sub introspection. */ void pubsubCommand(client *c) { - if (c->argc == 2 && !strcasecmp(ptrFromObj(c->argv[1]),"help")) { + if (c->argc == 2 && !strcasecmp(szFromObj(c->argv[1]),"help")) { const char *help[] = { "CHANNELS [] -- Return the currently active channels matching a pattern (default: all).", "NUMPAT -- Return number of subscriptions to patterns.", @@ -388,11 +388,11 @@ void pubsubCommand(client *c) { NULL }; addReplyHelp(c, help); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"channels") && + } else if (!strcasecmp(szFromObj(c->argv[1]),"channels") && (c->argc == 2 || c->argc == 3)) { /* PUBSUB CHANNELS [] */ - sds pat = (c->argc == 2) ? NULL : ptrFromObj(c->argv[2]); + sds pat = (c->argc == 2) ? NULL : szFromObj(c->argv[2]); dictIterator *di = dictGetIterator(server.pubsub_channels); dictEntry *de; long mblen = 0; @@ -400,8 +400,8 @@ NULL replylen = addReplyDeferredLen(c); while((de = dictNext(di)) != NULL) { - robj *cobj = dictGetKey(de); - sds channel = ptrFromObj(cobj); + robj *cobj = (robj*)dictGetKey(de); + sds channel = szFromObj(cobj); if (!pat || stringmatchlen(pat, sdslen(pat), channel, sdslen(channel),0)) @@ -412,18 +412,18 @@ NULL } dictReleaseIterator(di); setDeferredArrayLen(c,replylen,mblen); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"numsub") && c->argc >= 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"numsub") && c->argc >= 2) { /* PUBSUB NUMSUB [Channel_1 ... Channel_N] */ int j; addReplyArrayLen(c,(c->argc-2)*2); for (j = 2; j < c->argc; j++) { - list *l = dictFetchValue(server.pubsub_channels,c->argv[j]); + list *l = (list*)dictFetchValue(server.pubsub_channels,c->argv[j]); addReplyBulk(c,c->argv[j]); addReplyLongLong(c,l ? listLength(l) : 0); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"numpat") && c->argc == 2) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"numpat") && c->argc == 2) { /* PUBSUB NUMPAT */ addReplyLongLong(c,listLength(server.pubsub_patterns)); } else { diff --git a/src/rdb.c b/src/rdb.cpp similarity index 93% rename from src/rdb.c rename to src/rdb.cpp index dbf314021..ab03f45a9 100644 --- a/src/rdb.c +++ b/src/rdb.cpp @@ -49,7 +49,7 @@ extern int rdbCheckMode; void rdbCheckError(const char *fmt, ...); void rdbCheckSetError(const char *fmt, ...); -void rdbCheckThenExit(int linenum, char *reason, ...) { +void rdbCheckThenExit(int linenum, const char *reason, ...) { va_list ap; char msg[1024]; int len; @@ -62,7 +62,7 @@ void rdbCheckThenExit(int linenum, char *reason, ...) { if (!rdbCheckMode) { serverLog(LL_WARNING, "%s", msg); - char *argv[2] = {"",server.rdb_filename}; + const char * argv[2] = {"",server.rdb_filename}; redis_check_rdb_main(2,argv,NULL); } else { rdbCheckError("%s",msg); @@ -285,7 +285,7 @@ void *rdbLoadIntegerObject(rio *rdb, int enctype, int flags, size_t *lenptr) { char buf[LONG_STR_SIZE], *p; int len = ll2string(buf,sizeof(buf),val); if (lenptr) *lenptr = len; - p = plain ? zmalloc(len, MALLOC_SHARED) : sdsnewlen(SDS_NOINIT,len); + p = (char*)(plain ? zmalloc(len, MALLOC_SHARED) : sdsnewlen(SDS_NOINIT,len)); memcpy(p,buf,len); return p; } else if (encode) { @@ -339,7 +339,7 @@ writeerr: return -1; } -ssize_t rdbSaveLzfStringObject(rio *rdb, unsigned char *s, size_t len) { +ssize_t rdbSaveLzfStringObject(rio *rdb, const unsigned char *s, size_t len) { size_t comprlen, outlen; void *out; @@ -369,11 +369,11 @@ void *rdbLoadLzfStringObject(rio *rdb, int flags, size_t *lenptr) { if ((clen = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL; if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL; - if ((c = zmalloc(clen, MALLOC_SHARED)) == NULL) goto err; + if ((c = (unsigned char*)zmalloc(clen, MALLOC_SHARED)) == NULL) goto err; /* Allocate our target according to the uncompressed size. */ if (plain) { - val = zmalloc(len, MALLOC_SHARED); + val = (char*)zmalloc(len, MALLOC_SHARED); } else { val = sdsnewlen(SDS_NOINIT,len); } @@ -403,7 +403,7 @@ err: /* Save a string object as [len][data] on disk. If the object is a string * representation of an integer value we try to save it in a special form */ -ssize_t rdbSaveRawString(rio *rdb, unsigned char *s, size_t len) { +ssize_t rdbSaveRawString(rio *rdb, const unsigned char *s, size_t len) { int enclen; ssize_t n, nwritten = 0; @@ -419,7 +419,7 @@ ssize_t rdbSaveRawString(rio *rdb, unsigned char *s, size_t len) { /* Try LZF compression - under 20 bytes it's unable to compress even * aaaaaaaaaaaaaaaaaa so skip it */ if (server.rdb_compression && len > 20) { - n = rdbSaveLzfStringObject(rdb,s,len); + n = rdbSaveLzfStringObject(rdb,(const unsigned char*)s,len); if (n == -1) return -1; if (n > 0) return n; /* Return value of 0 means data can't be compressed, save the old way */ @@ -429,7 +429,7 @@ ssize_t rdbSaveRawString(rio *rdb, unsigned char *s, size_t len) { if ((n = rdbSaveLen(rdb,len)) == -1) return -1; nwritten += n; if (len > 0) { - if (rdbWriteRaw(rdb,s,len) == -1) return -1; + if (rdbWriteRaw(rdb,(unsigned char*)s,len) == -1) return -1; nwritten += len; } return nwritten; @@ -462,7 +462,7 @@ ssize_t rdbSaveStringObject(rio *rdb, robj *obj) { return rdbSaveLongLongAsStringObject(rdb,(long)ptrFromObj(obj)); } else { serverAssertWithInfo(NULL,obj,sdsEncodedObject(obj)); - return rdbSaveRawString(rdb,ptrFromObj(obj),sdslen(ptrFromObj(obj))); + return rdbSaveRawString(rdb,(unsigned char*)szFromObj(obj),sdslen(szFromObj(obj))); } } @@ -508,7 +508,7 @@ void *rdbGenericLoadStringObject(rio *rdb, int flags, size_t *lenptr) { if (plain) zfree(buf); else - sdsfree(buf); + sdsfree((char*)buf); return NULL; } return buf; @@ -524,11 +524,11 @@ void *rdbGenericLoadStringObject(rio *rdb, int flags, size_t *lenptr) { } robj *rdbLoadStringObject(rio *rdb) { - return rdbGenericLoadStringObject(rdb,RDB_LOAD_NONE,NULL); + return (robj*)rdbGenericLoadStringObject(rdb,RDB_LOAD_NONE,NULL); } robj *rdbLoadEncodedStringObject(rio *rdb) { - return rdbGenericLoadStringObject(rdb,RDB_LOAD_ENC,NULL); + return (robj*)rdbGenericLoadStringObject(rdb,RDB_LOAD_ENC,NULL); } /* Save a double value. Doubles are saved as strings prefixed by an unsigned @@ -697,7 +697,7 @@ ssize_t rdbSaveStreamPEL(rio *rdb, rax *pel, int nacks) { nwritten += n; if (nacks) { - streamNACK *nack = ri.data; + streamNACK *nack = (streamNACK*)ri.data; if ((n = rdbSaveMillisecondTime(rdb,nack->delivery_time)) == -1) return -1; nwritten += n; @@ -727,7 +727,7 @@ size_t rdbSaveStreamConsumers(rio *rdb, streamCG *cg) { raxStart(&ri,cg->consumers); raxSeek(&ri,"^",NULL,0); while(raxNext(&ri)) { - streamConsumer *consumer = ri.data; + streamConsumer *consumer = (streamConsumer*)ri.data; /* Consumer name. */ if ((n = rdbSaveRawString(rdb,ri.key,ri.key_len)) == -1) return -1; @@ -762,7 +762,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) { } else if (o->type == OBJ_LIST) { /* Save a list value */ if (o->encoding == OBJ_ENCODING_QUICKLIST) { - quicklist *ql = ptrFromObj(o); + quicklist *ql = (quicklist*)ptrFromObj(o); quicklistNode *node = ql->head; if ((n = rdbSaveLen(rdb,ql->len)) == -1) return -1; @@ -786,7 +786,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) { } else if (o->type == OBJ_SET) { /* Save a set value */ if (o->encoding == OBJ_ENCODING_HT) { - dict *set = ptrFromObj(o); + dict *set = (dict*)ptrFromObj(o); dictIterator *di = dictGetIterator(set); dictEntry *de; @@ -797,7 +797,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) { nwritten += n; while((de = dictNext(di)) != NULL) { - sds ele = dictGetKey(de); + sds ele = (sds)dictGetKey(de); if ((n = rdbSaveRawString(rdb,(unsigned char*)ele,sdslen(ele))) == -1) { @@ -810,7 +810,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) { } else if (o->encoding == OBJ_ENCODING_INTSET) { size_t l = intsetBlobLen((intset*)ptrFromObj(o)); - if ((n = rdbSaveRawString(rdb,ptrFromObj(o),l)) == -1) return -1; + if ((n = rdbSaveRawString(rdb,(unsigned char*)szFromObj(o),l)) == -1) return -1; nwritten += n; } else { serverPanic("Unknown set encoding"); @@ -820,10 +820,10 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) { if (o->encoding == OBJ_ENCODING_ZIPLIST) { size_t l = ziplistBlobLen((unsigned char*)ptrFromObj(o)); - if ((n = rdbSaveRawString(rdb,ptrFromObj(o),l)) == -1) return -1; + if ((n = rdbSaveRawString(rdb,(unsigned char*)ptrFromObj(o),l)) == -1) return -1; nwritten += n; } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = ptrFromObj(o); + zset *zs = (zset*)ptrFromObj(o); zskiplist *zsl = zs->zsl; if ((n = rdbSaveLen(rdb,zsl->length)) == -1) return -1; @@ -856,11 +856,11 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) { if (o->encoding == OBJ_ENCODING_ZIPLIST) { size_t l = ziplistBlobLen((unsigned char*)ptrFromObj(o)); - if ((n = rdbSaveRawString(rdb,ptrFromObj(o),l)) == -1) return -1; + if ((n = rdbSaveRawString(rdb,(unsigned char*)ptrFromObj(o),l)) == -1) return -1; nwritten += n; } else if (o->encoding == OBJ_ENCODING_HT) { - dictIterator *di = dictGetIterator(ptrFromObj(o)); + dictIterator *di = dictGetIterator((dict*)ptrFromObj(o)); dictEntry *de; if ((n = rdbSaveLen(rdb,dictSize((dict*)ptrFromObj(o)))) == -1) { @@ -870,8 +870,8 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) { nwritten += n; while((de = dictNext(di)) != NULL) { - sds field = dictGetKey(de); - sds value = dictGetVal(de); + sds field = (sds)dictGetKey(de); + sds value = (sds)dictGetVal(de); if ((n = rdbSaveRawString(rdb,(unsigned char*)field, sdslen(field))) == -1) @@ -894,7 +894,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) { } } else if (o->type == OBJ_STREAM) { /* Store how many listpacks we have inside the radix tree. */ - stream *s = ptrFromObj(o); + stream *s = (stream*)ptrFromObj(o); rax *rax = s->prax; if ((n = rdbSaveLen(rdb,raxSize(rax))) == -1) return -1; nwritten += n; @@ -906,7 +906,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) { raxStart(&ri,rax); raxSeek(&ri,"^",NULL,0); while (raxNext(&ri)) { - unsigned char *lp = ri.data; + unsigned char *lp = (unsigned char*)ri.data; size_t lp_bytes = lpBytes(lp); if ((n = rdbSaveRawString(rdb,ri.key,ri.key_len)) == -1) return -1; nwritten += n; @@ -939,7 +939,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) { raxStart(&ri,s->cgroups); raxSeek(&ri,"^",NULL,0); while(raxNext(&ri)) { - streamCG *cg = ri.data; + streamCG *cg = (streamCG*)ri.data; /* Save the group name. */ if ((n = rdbSaveRawString(rdb,ri.key,ri.key_len)) == -1) @@ -965,7 +965,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) { } else if (o->type == OBJ_MODULE) { /* Save a module-specific value. */ RedisModuleIO io; - moduleValue *mv = ptrFromObj(o); + moduleValue *mv = (moduleValue*)ptrFromObj(o); moduleType *mt = mv->type; moduleInitIOContext(io,mt,rdb,key); @@ -1044,25 +1044,25 @@ int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, long long expiretime) { } /* Save an AUX field. */ -ssize_t rdbSaveAuxField(rio *rdb, void *key, size_t keylen, void *val, size_t vallen) { +ssize_t rdbSaveAuxField(rio *rdb, const void *key, size_t keylen, const void *val, size_t vallen) { ssize_t ret, len = 0; if ((ret = rdbSaveType(rdb,RDB_OPCODE_AUX)) == -1) return -1; len += ret; - if ((ret = rdbSaveRawString(rdb,key,keylen)) == -1) return -1; + if ((ret = rdbSaveRawString(rdb,(const unsigned char*)key,keylen)) == -1) return -1; len += ret; - if ((ret = rdbSaveRawString(rdb,val,vallen)) == -1) return -1; + if ((ret = rdbSaveRawString(rdb,(const unsigned char*)val,vallen)) == -1) return -1; len += ret; return len; } /* Wrapper for rdbSaveAuxField() used when key/val length can be obtained * with strlen(). */ -ssize_t rdbSaveAuxFieldStrStr(rio *rdb, char *key, char *val) { +ssize_t rdbSaveAuxFieldStrStr(rio *rdb, const char *key, const char *val) { return rdbSaveAuxField(rdb,key,strlen(key),val,strlen(val)); } /* Wrapper for strlen(key) + integer type (up to long long range). */ -ssize_t rdbSaveAuxFieldStrInt(rio *rdb, char *key, long long val) { +ssize_t rdbSaveAuxFieldStrInt(rio *rdb, const char *key, long long val) { char buf[LONG_STR_SIZE]; int vlen = ll2string(buf,sizeof(buf),val); return rdbSaveAuxField(rdb,key,strlen(key),buf,vlen); @@ -1137,8 +1137,8 @@ int rdbSaveRio(rio *rdb, int *error, int flags, rdbSaveInfo *rsi) { /* Iterate this DB writing every entry */ while((de = dictNext(di)) != NULL) { - sds keystr = dictGetKey(de); - robj key, *o = dictGetVal(de); + sds keystr = (sds)dictGetKey(de); + robj key, *o = (robj*)dictGetVal(de); long long expire; initStaticStringObject(key,keystr); @@ -1166,8 +1166,8 @@ int rdbSaveRio(rio *rdb, int *error, int flags, rdbSaveInfo *rsi) { if (rsi && dictSize(server.lua_scripts)) { di = dictGetIterator(server.lua_scripts); while((de = dictNext(di)) != NULL) { - robj *body = dictGetVal(de); - if (rdbSaveAuxField(rdb,"lua",3,ptrFromObj(body),sdslen(ptrFromObj(body))) == -1) + robj *body = (robj*)dictGetVal(de); + if (rdbSaveAuxField(rdb,"lua",3,szFromObj(body),sdslen(szFromObj(body))) == -1) goto werr; } dictReleaseIterator(di); @@ -1376,7 +1376,7 @@ robj *rdbLoadCheckModuleValue(rio *rdb, char *modulename) { "Error reading integer from module %s value", modulename); } } else if (opcode == RDB_MODULE_OPCODE_STRING) { - robj *o = rdbGenericLoadStringObject(rdb,RDB_LOAD_NONE,NULL); + robj *o = (robj*)rdbGenericLoadStringObject(rdb,RDB_LOAD_NONE,NULL); if (o == NULL) { rdbExitReportCorruptRDB( "Error reading string from module %s value", modulename); @@ -1415,15 +1415,15 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL; o = createQuicklistObject(); - quicklistSetOptions(ptrFromObj(o), server.list_max_ziplist_size, + quicklistSetOptions((quicklist*)ptrFromObj(o), server.list_max_ziplist_size, server.list_compress_depth); /* Load every single element of the list */ while(len--) { if ((ele = rdbLoadEncodedStringObject(rdb)) == NULL) return NULL; dec = getDecodedObject(ele); - size_t len = sdslen(ptrFromObj(dec)); - quicklistPushTail(ptrFromObj(o), ptrFromObj(dec), len); + size_t len = sdslen(szFromObj(dec)); + quicklistPushTail((quicklist*)ptrFromObj(o), ptrFromObj(dec), len); decrRefCount(dec); decrRefCount(ele); } @@ -1437,7 +1437,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { /* It's faster to expand the dict to the right size asap in order * to avoid rehashing */ if (len > DICT_HT_INITIAL_SIZE) - dictExpand(ptrFromObj(o),len); + dictExpand((dict*)ptrFromObj(o),len); } else { o = createIntsetObject(); } @@ -1447,16 +1447,16 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { long long llval; sds sdsele; - if ((sdsele = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) + if ((sdsele = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) == NULL) return NULL; if (o->encoding == OBJ_ENCODING_INTSET) { /* Fetch integer value from element. */ if (isSdsRepresentableAsLongLong(sdsele,&llval) == C_OK) { - o->m_ptr = intsetAdd(ptrFromObj(o),llval,NULL); + o->m_ptr = intsetAdd((intset*)ptrFromObj(o),llval,NULL); } else { setTypeConvert(o,OBJ_ENCODING_HT); - dictExpand(ptrFromObj(o),len); + dictExpand((dict*)ptrFromObj(o),len); } } @@ -1476,7 +1476,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { if ((zsetlen = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL; o = createZsetObject(); - zs = ptrFromObj(o); + zs = (zset*)ptrFromObj(o); if (zsetlen > DICT_HT_INITIAL_SIZE) dictExpand(zs->pdict,zsetlen); @@ -1487,7 +1487,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { double score; zskiplistNode *znode; - if ((sdsele = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) + if ((sdsele = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) == NULL) return NULL; if (rdbtype == RDB_TYPE_ZSET_2) { @@ -1525,15 +1525,15 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { while (o->encoding == OBJ_ENCODING_ZIPLIST && len > 0) { len--; /* Load raw strings */ - if ((field = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) + if ((field = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) == NULL) return NULL; - if ((value = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) + if ((value = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) == NULL) return NULL; /* Add pair to ziplist */ - o->m_ptr = ziplistPush(ptrFromObj(o), (unsigned char*)field, + o->m_ptr = ziplistPush((unsigned char*)ptrFromObj(o), (unsigned char*)field, sdslen(field), ZIPLIST_TAIL); - o->m_ptr = ziplistPush(ptrFromObj(o), (unsigned char*)value, + o->m_ptr = ziplistPush((unsigned char*)ptrFromObj(o), (unsigned char*)value, sdslen(value), ZIPLIST_TAIL); /* Convert to hash table if size threshold is exceeded */ @@ -1550,15 +1550,15 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { } if (o->encoding == OBJ_ENCODING_HT && len > DICT_HT_INITIAL_SIZE) - dictExpand(ptrFromObj(o),len); + dictExpand((dict*)ptrFromObj(o),len); /* Load remaining fields and values into the hash table */ while (o->encoding == OBJ_ENCODING_HT && len > 0) { len--; /* Load encoded strings */ - if ((field = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) + if ((field = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) == NULL) return NULL; - if ((value = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) + if ((value = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) == NULL) return NULL; /* Add pair to hash table */ @@ -1573,14 +1573,14 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { } else if (rdbtype == RDB_TYPE_LIST_QUICKLIST) { if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL; o = createQuicklistObject(); - quicklistSetOptions(ptrFromObj(o), server.list_max_ziplist_size, + quicklistSetOptions((quicklist*)ptrFromObj(o), server.list_max_ziplist_size, server.list_compress_depth); while (len--) { - unsigned char *zl = + unsigned char *zl = (unsigned char*) rdbGenericLoadStringObject(rdb,RDB_LOAD_PLAIN,NULL); if (zl == NULL) return NULL; - quicklistAppendZiplist(ptrFromObj(o), zl); + quicklistAppendZiplist((quicklist*)ptrFromObj(o), zl); } } else if (rdbtype == RDB_TYPE_HASH_ZIPMAP || rdbtype == RDB_TYPE_LIST_ZIPLIST || @@ -1588,7 +1588,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { rdbtype == RDB_TYPE_ZSET_ZIPLIST || rdbtype == RDB_TYPE_HASH_ZIPLIST) { - unsigned char *encoded = + unsigned char *encoded = (unsigned char*) rdbGenericLoadStringObject(rdb,RDB_LOAD_PLAIN,NULL); if (encoded == NULL) return NULL; o = createObject(OBJ_STRING,encoded); /* Obj type fixed below. */ @@ -1605,7 +1605,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { * when loading dumps created by Redis 2.4 gets deprecated. */ { unsigned char *zl = ziplistNew(); - unsigned char *zi = zipmapRewind(ptrFromObj(o)); + unsigned char *zi = zipmapRewind((unsigned char*)ptrFromObj(o)); unsigned char *fstr, *vstr; unsigned int flen, vlen; unsigned int maxlen = 0; @@ -1637,7 +1637,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { case RDB_TYPE_SET_INTSET: o->type = OBJ_SET; o->encoding = OBJ_ENCODING_INTSET; - if (intsetLen(ptrFromObj(o)) > server.set_max_intset_entries) + if (intsetLen((intset*)ptrFromObj(o)) > server.set_max_intset_entries) setTypeConvert(o,OBJ_ENCODING_HT); break; case RDB_TYPE_ZSET_ZIPLIST: @@ -1658,14 +1658,14 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { } } else if (rdbtype == RDB_TYPE_STREAM_LISTPACKS) { o = createStreamObject(); - stream *s = ptrFromObj(o); + stream *s = (stream*)ptrFromObj(o); uint64_t listpacks = rdbLoadLen(rdb,NULL); while(listpacks--) { /* Get the master ID, the one we'll use as key of the radix tree * node: the entries inside the listpack itself are delta-encoded * relatively to this ID. */ - sds nodekey = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL); + sds nodekey = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL); if (nodekey == NULL) { rdbExitReportCorruptRDB("Stream master ID loading failed: invalid encoding or I/O error."); } @@ -1675,7 +1675,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { } /* Load the listpack. */ - unsigned char *lp = + unsigned char *lp = (unsigned char*) rdbGenericLoadStringObject(rdb,RDB_LOAD_PLAIN,NULL); if (lp == NULL) return NULL; unsigned char *first = lpFirst(lp); @@ -1706,7 +1706,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { * consumer group ASAP and populate its structure as * we read more data. */ streamID cg_id; - sds cgname = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL); + sds cgname = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL); if (cgname == NULL) { rdbExitReportCorruptRDB( "Error reading the consumer group name from Stream"); @@ -1740,7 +1740,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { * consumers and their local PELs. */ size_t consumers_num = rdbLoadLen(rdb,NULL); while(consumers_num--) { - sds cname = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL); + sds cname = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL); if (cname == NULL) { rdbExitReportCorruptRDB( "Error reading the consumer name from Stream group"); @@ -1756,7 +1756,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) { while(pel_size--) { unsigned char rawid[sizeof(streamID)]; rdbLoadRaw(rdb,rawid,sizeof(rawid)); - streamNACK *nack = raxFind(cgroup->pel,rawid,sizeof(rawid)); + streamNACK *nack = (streamNACK*)raxFind(cgroup->pel,rawid,sizeof(rawid)); if (nack == raxNotFound) rdbExitReportCorruptRDB("Consumer entry not found in " "group global PEL"); @@ -1880,6 +1880,9 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi, int loading_aof) { int type, rdbver; redisDb *db = server.db+0; char buf[1024]; + /* Key-specific attributes, set by opcodes before the key type. */ + long long lru_idle = -1, lfu_freq = -1, expiretime = -1, now = mstime(); + long long lru_clock = LRU_CLOCK(); rdb->update_cksum = rdbLoadProgressCallback; rdb->max_processing_chunk = server.loading_process_events_interval_bytes; @@ -1897,9 +1900,8 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi, int loading_aof) { return C_ERR; } - /* Key-specific attributes, set by opcodes before the key type. */ - long long lru_idle = -1, lfu_freq = -1, expiretime = -1, now = mstime(); - long long lru_clock = LRU_CLOCK(); + now = mstime(); + lru_clock = LRU_CLOCK(); while(1) { robj *key, *val; @@ -1975,38 +1977,38 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi, int loading_aof) { serverLog(LL_NOTICE,"RDB '%s': %s", (char*)ptrFromObj(auxkey), (char*)ptrFromObj(auxval)); - } else if (!strcasecmp(ptrFromObj(auxkey),"repl-stream-db")) { - if (rsi) rsi->repl_stream_db = atoi(ptrFromObj(auxval)); - } else if (!strcasecmp(ptrFromObj(auxkey),"repl-id")) { - if (rsi && sdslen(ptrFromObj(auxval)) == CONFIG_RUN_ID_SIZE) { + } else if (!strcasecmp(szFromObj(auxkey),"repl-stream-db")) { + if (rsi) rsi->repl_stream_db = atoi(szFromObj(auxval)); + } else if (!strcasecmp(szFromObj(auxkey),"repl-id")) { + if (rsi && sdslen(szFromObj(auxval)) == CONFIG_RUN_ID_SIZE) { memcpy(rsi->repl_id,ptrFromObj(auxval),CONFIG_RUN_ID_SIZE+1); rsi->repl_id_is_set = 1; } - } else if (!strcasecmp(ptrFromObj(auxkey),"repl-offset")) { - if (rsi) rsi->repl_offset = strtoll(ptrFromObj(auxval),NULL,10); - } else if (!strcasecmp(ptrFromObj(auxkey),"lua")) { + } else if (!strcasecmp(szFromObj(auxkey),"repl-offset")) { + if (rsi) rsi->repl_offset = strtoll(szFromObj(auxval),NULL,10); + } else if (!strcasecmp(szFromObj(auxkey),"lua")) { /* Load the script back in memory. */ if (luaCreateFunction(NULL,server.lua,auxval) == NULL) { rdbExitReportCorruptRDB( "Can't load Lua script from RDB file! " "BODY: %s", ptrFromObj(auxval)); } - } else if (!strcasecmp(ptrFromObj(auxkey),"redis-ver")) { + } else if (!strcasecmp(szFromObj(auxkey),"redis-ver")) { serverLog(LL_NOTICE,"Loading RDB produced by version %s", (const char*)ptrFromObj(auxval)); - } else if (!strcasecmp(ptrFromObj(auxkey),"ctime")) { - time_t age = time(NULL)-strtol(ptrFromObj(auxval),NULL,10); + } else if (!strcasecmp(szFromObj(auxkey),"ctime")) { + time_t age = time(NULL)-strtol(szFromObj(auxval),NULL,10); if (age < 0) age = 0; serverLog(LL_NOTICE,"RDB age %ld seconds", (unsigned long) age); - } else if (!strcasecmp(ptrFromObj(auxkey),"used-mem")) { - long long usedmem = strtoll(ptrFromObj(auxval),NULL,10); + } else if (!strcasecmp(szFromObj(auxkey),"used-mem")) { + long long usedmem = strtoll(szFromObj(auxval),NULL,10); serverLog(LL_NOTICE,"RDB memory usage when created %.2f Mb", (double) usedmem / (1024*1024)); - } else if (!strcasecmp(ptrFromObj(auxkey),"aof-preamble")) { - long long haspreamble = strtoll(ptrFromObj(auxval),NULL,10); + } else if (!strcasecmp(szFromObj(auxkey),"aof-preamble")) { + long long haspreamble = strtoll(szFromObj(auxval),NULL,10); if (haspreamble) serverLog(LL_NOTICE,"RDB has an AOF tail"); - } else if (!strcasecmp(ptrFromObj(auxkey),"redis-bits")) { + } else if (!strcasecmp(szFromObj(auxkey),"redis-bits")) { /* Just ignored. */ } else { /* We ignore fields we don't understand, as by AUX field @@ -2208,7 +2210,7 @@ void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal) { * If the process returned an error, consider the list of slaves that * can continue to be empty, so that it's just a special case of the * normal code path. */ - ok_slaves = zmalloc(sizeof(uint64_t), MALLOC_LOCAL); /* Make space for the count. */ + ok_slaves = (uint64_t*)zmalloc(sizeof(uint64_t), MALLOC_LOCAL); /* Make space for the count. */ ok_slaves[0] = 0; if (!bysignal && exitcode == 0) { int readlen = sizeof(uint64_t); @@ -2220,7 +2222,7 @@ void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal) { /* Make space for enough elements as specified by the first * uint64_t element in the array. */ - ok_slaves = zrealloc(ok_slaves,sizeof(uint64_t)+readlen, MALLOC_LOCAL); + ok_slaves = (uint64_t*)zrealloc(ok_slaves,sizeof(uint64_t)+readlen, MALLOC_LOCAL); if (readlen && read(server.rdb_pipe_read_result_from_child, ok_slaves+1, readlen) != readlen) @@ -2240,7 +2242,7 @@ void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal) { listRewind(server.slaves,&li); while((ln = listNext(&li))) { - client *slave = ln->value; + client *slave = (client*)ln->value; if (slave->replstate == SLAVE_STATE_WAIT_BGSAVE_END) { uint64_t j; @@ -2326,16 +2328,16 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) { /* Collect the file descriptors of the slaves we want to transfer * the RDB to, which are i WAIT_BGSAVE_START state. */ - fds = zmalloc(sizeof(int)*listLength(server.slaves), MALLOC_LOCAL); + fds = (int*)zmalloc(sizeof(int)*listLength(server.slaves), MALLOC_LOCAL); /* We also allocate an array of corresponding client IDs. This will * be useful for the child process in order to build the report * (sent via unix pipe) that will be sent to the parent. */ - clientids = zmalloc(sizeof(uint64_t)*listLength(server.slaves), MALLOC_LOCAL); + clientids = (uint64_t*)zmalloc(sizeof(uint64_t)*listLength(server.slaves), MALLOC_LOCAL); numfds = 0; listRewind(server.slaves,&li); while((ln = listNext(&li))) { - client *slave = ln->value; + client *slave = (client*)ln->value; if (slave->replstate == SLAVE_STATE_WAIT_BGSAVE_START) { clientids[numfds] = slave->id; @@ -2395,7 +2397,7 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) { * set to 0 if the replication process terminated with a success * or the error code if an error occurred. */ void *msg = zmalloc(sizeof(uint64_t)*(1+2*numfds), MALLOC_LOCAL); - uint64_t *len = msg; + uint64_t *len = (uint64_t*)msg; uint64_t *ids = len+1; int j, msglen; @@ -2432,7 +2434,7 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) { * replicationSetupSlaveForFullResync() turned it into BGSAVE_END */ listRewind(server.slaves,&li); while((ln = listNext(&li))) { - client *slave = ln->value; + client *slave = (client*)ln->value; int j; for (j = 0; j < numfds; j++) { @@ -2485,7 +2487,7 @@ void bgsaveCommand(client *c) { /* The SCHEDULE option changes the behavior of BGSAVE when an AOF rewrite * is in progress. Instead of returning an error a BGSAVE gets scheduled. */ if (c->argc > 1) { - if (c->argc == 2 && !strcasecmp(ptrFromObj(c->argv[1]),"schedule")) { + if (c->argc == 2 && !strcasecmp(szFromObj(c->argv[1]),"schedule")) { schedule = 1; } else { addReply(c,shared.syntaxerr); @@ -2550,7 +2552,7 @@ rdbSaveInfo *rdbPopulateSaveInfo(rdbSaveInfo *rsi) { // BUGBUG, warn user about this incomplete implementation serverLog(LL_WARNING, "Warning: Only backing up first master's information in RDB"); } - struct redisMaster *miFirst = listLength(server.masters) ? listNodeValue(listFirst(server.masters)) : NULL; + struct redisMaster *miFirst = (redisMaster*)(listLength(server.masters) ? listNodeValue(listFirst(server.masters)) : NULL); /* If the instance is a slave we need a connected master * in order to fetch the currently selected DB. */ diff --git a/src/rdb.h b/src/rdb.h index 7d95ba562..f43b2f4f7 100644 --- a/src/rdb.h +++ b/src/rdb.h @@ -151,7 +151,7 @@ void backgroundSaveDoneHandler(int exitcode, int bysignal); int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, long long expiretime); robj *rdbLoadStringObject(rio *rdb); ssize_t rdbSaveStringObject(rio *rdb, robj *obj); -ssize_t rdbSaveRawString(rio *rdb, unsigned char *s, size_t len); +ssize_t rdbSaveRawString(rio *rdb, const unsigned char *s, size_t len); void *rdbGenericLoadStringObject(rio *rdb, int flags, size_t *lenptr); int rdbSaveBinaryDoubleValue(rio *rdb, double val); int rdbLoadBinaryDoubleValue(rio *rdb, double *val); diff --git a/src/redis-benchmark.c b/src/redis-benchmark.cpp similarity index 96% rename from src/redis-benchmark.c rename to src/redis-benchmark.cpp index 6bb3533bf..8d50303ee 100644 --- a/src/redis-benchmark.c +++ b/src/redis-benchmark.cpp @@ -41,10 +41,11 @@ #include #include #include - +extern "C" { #include /* Use hiredis sds. */ -#include "ae.h" #include "hiredis.h" +} +#include "ae.h" #include "adlist.h" #include "dict.h" #include "zmalloc.h" @@ -231,7 +232,7 @@ static int dictSdsKeyCompare(void *privdata, const void *key1, } /* _serverAssert is needed by dict */ -void _serverAssert(const char *estr, const char *file, int line) { +extern "C" void _serverAssert(const char *estr, const char *file, int line) { fprintf(stderr, "=== ASSERTION FAILED ==="); fprintf(stderr, "==> %s:%d '%s' is not true",file,line,estr); *((char*)-1) = 'x'; @@ -240,7 +241,9 @@ void _serverAssert(const char *estr, const char *file, int line) { static redisConfig *getRedisConfig(const char *ip, int port, const char *hostsocket) { - redisConfig *cfg = zcalloc(sizeof(*cfg), MALLOC_LOCAL); + redisConfig *cfg = (redisConfig*)zcalloc(sizeof(*cfg), MALLOC_LOCAL); + int i = 0; + void *r = NULL; if (!cfg) return NULL; redisContext *c = NULL; redisReply *reply = NULL, *sub_reply = NULL; @@ -250,15 +253,14 @@ static redisConfig *getRedisConfig(const char *ip, int port, c = redisConnectUnix(hostsocket); if (c == NULL || c->err) { fprintf(stderr,"Could not connect to Redis at "); - char *err = (c != NULL ? c->errstr : ""); + const char *err = (c != NULL ? c->errstr : ""); if (hostsocket == NULL) fprintf(stderr,"%s:%d: %s\n",ip,port,err); else fprintf(stderr,"%s: %s\n",hostsocket,err); goto fail; } redisAppendCommand(c, "CONFIG GET %s", "save"); redisAppendCommand(c, "CONFIG GET %s", "appendonly"); - int i = 0; - void *r = NULL; + for (; i < 2; i++) { int res = redisGetReply(c, &r); if (reply) freeReplyObject(reply); @@ -270,7 +272,7 @@ static redisConfig *getRedisConfig(const char *ip, int port, } if (reply->type != REDIS_REPLY_ARRAY || reply->elements < 2) goto fail; sub_reply = reply->element[1]; - char *value = sub_reply->str; + const char *value = sub_reply->str; if (!value) value = ""; switch (i) { case 0: cfg->save = sdsnew(value); break; @@ -325,7 +327,7 @@ static void freeAllClients(void) { while(ln) { next = ln->next; - freeClient(ln->value); + freeClient((client)ln->value); ln = next; } } @@ -405,7 +407,7 @@ static void clientDone(client c) { } static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) { - client c = privdata; + client c = (client)privdata; void *reply = NULL; UNUSED(el); UNUSED(fd); @@ -430,7 +432,7 @@ static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) { fprintf(stderr,"Unexpected error reply, exiting...\n"); exit(1); } - redisReply *r = reply; + redisReply *r = (redisReply*)reply; int is_err = (r->type == REDIS_REPLY_ERROR); if (is_err && config.showerrors) { @@ -505,7 +507,7 @@ static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) { } static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask) { - client c = privdata; + client c = (client)privdata; UNUSED(el); UNUSED(fd); UNUSED(mask); @@ -565,10 +567,10 @@ static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask) { * for arguments randomization. * * Even when cloning another client, prefix commands are applied if needed.*/ -static client createClient(char *cmd, size_t len, client from, int thread_id) { +static client createClient(const char *cmd, size_t len, client from, int thread_id) { int j; int is_cluster_client = (config.cluster_mode && thread_id >= 0); - client c = zmalloc(sizeof(struct _client), MALLOC_LOCAL); + client c = (client)zmalloc(sizeof(struct _client), MALLOC_LOCAL); const char *ip = NULL; int port = 0; @@ -653,7 +655,7 @@ static client createClient(char *cmd, size_t len, client from, int thread_id) { if (from) { c->randlen = from->randlen; c->randfree = 0; - c->randptr = zmalloc(sizeof(char*)*c->randlen, MALLOC_LOCAL); + c->randptr = (char**)zmalloc(sizeof(char*)*c->randlen, MALLOC_LOCAL); /* copy the offsets. */ for (j = 0; j < (int)c->randlen; j++) { c->randptr[j] = c->obuf + (from->randptr[j]-from->obuf); @@ -665,10 +667,10 @@ static client createClient(char *cmd, size_t len, client from, int thread_id) { c->randlen = 0; c->randfree = RANDPTR_INITIAL_SIZE; - c->randptr = zmalloc(sizeof(char*)*c->randfree, MALLOC_LOCAL); + c->randptr = (char**)zmalloc(sizeof(char*)*c->randfree, MALLOC_LOCAL); while ((p = strstr(p,"__rand_int__")) != NULL) { if (c->randfree == 0) { - c->randptr = zrealloc(c->randptr,sizeof(char*)*c->randlen*2, MALLOC_LOCAL); + c->randptr = (char**)zrealloc(c->randptr,sizeof(char*)*c->randlen*2, MALLOC_LOCAL); c->randfree += c->randlen; } c->randptr[c->randlen++] = p; @@ -682,7 +684,7 @@ static client createClient(char *cmd, size_t len, client from, int thread_id) { if (from) { c->staglen = from->staglen; c->stagfree = 0; - c->stagptr = zmalloc(sizeof(char*)*c->staglen, MALLOC_LOCAL); + c->stagptr = (char**)zmalloc(sizeof(char*)*c->staglen, MALLOC_LOCAL); /* copy the offsets. */ for (j = 0; j < (int)c->staglen; j++) { c->stagptr[j] = c->obuf + (from->stagptr[j]-from->obuf); @@ -694,10 +696,10 @@ static client createClient(char *cmd, size_t len, client from, int thread_id) { c->staglen = 0; c->stagfree = RANDPTR_INITIAL_SIZE; - c->stagptr = zmalloc(sizeof(char*)*c->stagfree, MALLOC_LOCAL); + c->stagptr = (char**)zmalloc(sizeof(char*)*c->stagfree, MALLOC_LOCAL); while ((p = strstr(p,"{tag}")) != NULL) { if (c->stagfree == 0) { - c->stagptr = zrealloc(c->stagptr, + c->stagptr = (char**)zrealloc(c->stagptr, sizeof(char*) * c->staglen*2, MALLOC_LOCAL); c->stagfree += c->staglen; } @@ -821,7 +823,7 @@ static void showLatencyReport(void) { static void initBenchmarkThreads() { int i; if (config.threads) freeBenchmarkThreads(); - config.threads = zmalloc(config.num_threads * sizeof(benchmarkThread*), MALLOC_LOCAL); + config.threads = (benchmarkThread**)zmalloc(config.num_threads * sizeof(benchmarkThread*), MALLOC_LOCAL); for (i = 0; i < config.num_threads; i++) { benchmarkThread *thread = createBenchmarkThread(i); config.threads[i] = thread; @@ -841,7 +843,7 @@ static void startBenchmarkThreads() { pthread_join(config.threads[i]->thread, NULL); } -static void benchmark(char *title, char *cmd, int len) { +static void benchmark(const char *title, const char *cmd, int len) { client c; config.title = title; @@ -867,7 +869,7 @@ static void benchmark(char *title, char *cmd, int len) { /* Thread functions. */ static benchmarkThread *createBenchmarkThread(int index) { - benchmarkThread *thread = zmalloc(sizeof(*thread), MALLOC_LOCAL); + benchmarkThread *thread = (benchmarkThread*)zmalloc(sizeof(*thread), MALLOC_LOCAL); if (thread == NULL) return NULL; thread->index = index; thread->el = aeCreateEventLoop(1024*10); @@ -899,7 +901,7 @@ static void *execBenchmarkThread(void *ptr) { /* Cluster helper functions. */ static clusterNode *createClusterNode(char *ip, int port) { - clusterNode *node = zmalloc(sizeof(*node), MALLOC_LOCAL); + clusterNode *node = (clusterNode*)zmalloc(sizeof(*node), MALLOC_LOCAL); if (!node) return NULL; node->ip = ip; node->port = port; @@ -907,7 +909,7 @@ static clusterNode *createClusterNode(char *ip, int port) { node->flags = 0; node->replicate = NULL; node->replicas_count = 0; - node->slots = zmalloc(CLUSTER_SLOTS * sizeof(int), MALLOC_LOCAL); + node->slots = (int*)zmalloc(CLUSTER_SLOTS * sizeof(int), MALLOC_LOCAL); node->slots_count = 0; node->current_slot_index = 0; node->updated_slots = NULL; @@ -953,7 +955,7 @@ static void freeClusterNodes() { static clusterNode **addClusterNode(clusterNode *node) { int count = config.cluster_node_count + 1; - config.cluster_nodes = zrealloc(config.cluster_nodes, + config.cluster_nodes = (clusterNode**)zrealloc(config.cluster_nodes, count * sizeof(*node), MALLOC_LOCAL); if (!config.cluster_nodes) return NULL; config.cluster_nodes[config.cluster_node_count++] = node; @@ -964,6 +966,7 @@ static int fetchClusterConfiguration() { int success = 1; redisContext *ctx = NULL; redisReply *reply = NULL; + char *lines = reply->str, *p, *line; if (config.hostsocket == NULL) ctx = redisConnect(config.hostip,config.hostport); else @@ -979,7 +982,7 @@ static int fetchClusterConfiguration() { clusterNode *firstNode = createClusterNode((char *) config.hostip, config.hostport); if (!firstNode) {success = 0; goto cleanup;} - reply = redisCommand(ctx, "CLUSTER NODES"); + reply = (redisReply*)redisCommand(ctx, "CLUSTER NODES"); success = (reply != NULL); if (!success) goto cleanup; success = (reply->type != REDIS_REPLY_ERROR); @@ -993,7 +996,7 @@ static int fetchClusterConfiguration() { } goto cleanup; } - char *lines = reply->str, *p, *line; + lines = reply->str; while ((p = strstr(lines, "\n")) != NULL) { *p = '\0'; line = lines; @@ -1077,7 +1080,7 @@ static int fetchClusterConfiguration() { sds dst = sdsnew(p); node->migrating_count += 2; node->migrating = - zrealloc(node->migrating, + (char**)zrealloc(node->migrating, (node->migrating_count * sizeof(sds)), MALLOC_LOCAL); node->migrating[node->migrating_count - 2] = slot; @@ -1091,7 +1094,7 @@ static int fetchClusterConfiguration() { sds slot = sdsnew(slotsdef); sds src = sdsnew(p); node->importing_count += 2; - node->importing = zrealloc(node->importing, + node->importing = (char**)zrealloc(node->importing, (node->importing_count * sizeof(sds)), MALLOC_LOCAL); node->importing[node->importing_count - 2] = slot; @@ -1183,7 +1186,7 @@ static int fetchClusterSlotsConfiguration(client c) { node->updated_slots_count = 0; dictReplace(masters, node->name, node) ; } - reply = redisCommand(ctx, "CLUSTER SLOTS"); + reply = (redisReply*)redisCommand(ctx, "CLUSTER SLOTS"); if (reply == NULL || reply->type == REDIS_REPLY_ERROR) { success = 0; if (reply) @@ -1211,9 +1214,9 @@ static int fetchClusterSlotsConfiguration(client c) { goto cleanup; } sdsfree(name); - clusterNode *node = dictGetVal(entry); + clusterNode *node = (clusterNode*)dictGetVal(entry); if (node->updated_slots == NULL) - node->updated_slots = zcalloc(CLUSTER_SLOTS * sizeof(int), MALLOC_LOCAL); + node->updated_slots = (int*)zcalloc(CLUSTER_SLOTS * sizeof(int), MALLOC_LOCAL); for (slot = from; slot <= to; slot++) node->updated_slots[node->updated_slots_count++] = slot; } @@ -1436,7 +1439,7 @@ int showThroughput(struct aeEventLoop *eventLoop, long long id, void *clientData /* Return true if the named test was selected using the -t command line * switch, or if all the tests are selected (no -t passed by user). */ -int test_is_selected(char *name) { +int test_is_selected(const char *name) { char buf[256]; int l = strlen(name); @@ -1499,7 +1502,7 @@ int main(int argc, const char **argv) { argc -= i; argv += i; - config.latency = zmalloc(sizeof(long long)*config.requests, MALLOC_LOCAL); + config.latency = (long long*)zmalloc(sizeof(long long)*config.requests, MALLOC_LOCAL); if (config.cluster_mode) { /* Fetch cluster configuration. */ @@ -1596,7 +1599,7 @@ int main(int argc, const char **argv) { } /* Run default benchmark suite. */ - data = zmalloc(config.datasize+1, MALLOC_LOCAL); + data = (char*)zmalloc(config.datasize+1, MALLOC_LOCAL); do { memset(data,'x',config.datasize); data[config.datasize] = '\0'; diff --git a/src/redis-check-aof.c b/src/redis-check-aof.cpp similarity index 98% rename from src/redis-check-aof.c rename to src/redis-check-aof.cpp index 4f8c3833a..cb707b9ac 100644 --- a/src/redis-check-aof.c +++ b/src/redis-check-aof.cpp @@ -190,7 +190,7 @@ int redis_check_aof_main(int argc, char **argv) { if (has_preamble) { printf("The AOF appears to start with an RDB preamble.\n" "Checking the RDB preamble to start:\n"); - if (redis_check_rdb_main(argc,argv,fp) == C_ERR) { + if (redis_check_rdb_main(argc,(const char**)argv,fp) == C_ERR) { printf("RDB preamble of AOF file is not sane, aborting.\n"); exit(1); } else { diff --git a/src/redis-check-rdb.c b/src/redis-check-rdb.cpp similarity index 98% rename from src/redis-check-rdb.c rename to src/redis-check-rdb.cpp index 2fd8366a5..a5570095f 100644 --- a/src/redis-check-rdb.c +++ b/src/redis-check-rdb.cpp @@ -37,7 +37,7 @@ void rdbLoadProgressCallback(rio *r, const void *buf, size_t len); int rdbCheckMode = 0; struct { - rio *rio; + ::rio *rio; robj *key; /* Current key we are reading. */ int key_type; /* Current key type if != -1. */ unsigned long keys; /* Number of keys processed. */ @@ -59,7 +59,7 @@ struct { #define RDB_CHECK_DOING_READ_LEN 6 #define RDB_CHECK_DOING_READ_AUX 7 -char *rdb_check_doing_string[] = { +const char *rdb_check_doing_string[] = { "start", "read-type", "read-expire", @@ -70,7 +70,7 @@ char *rdb_check_doing_string[] = { "read-aux" }; -char *rdb_type_string[] = { +const char *rdb_type_string[] = { "string", "list-linked", "set-hashtable", @@ -176,7 +176,7 @@ void rdbCheckSetupSignals(void) { * 1 is returned. * The file is specified as a filename in 'rdbfilename' if 'fp' is not NULL, * otherwise the already open file 'fp' is checked. */ -int redis_check_rdb(char *rdbfilename, FILE *fp) { +int redis_check_rdb(const char *rdbfilename, FILE *fp) { uint64_t dbid; int type, rdbver; char buf[1024]; @@ -339,7 +339,7 @@ err: * status code according to success (RDB is sane) or error (RDB is corrupted). * Otherwise if called with a non NULL fp, the function returns C_OK or * C_ERR depending on the success or failure. */ -int redis_check_rdb_main(int argc, char **argv, FILE *fp) { +int redis_check_rdb_main(int argc, const char **argv, FILE *fp) { if (argc != 2 && fp == NULL) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); diff --git a/src/redis-cli-cpphelper.cpp b/src/redis-cli-cpphelper.cpp new file mode 100644 index 000000000..208c1656d --- /dev/null +++ b/src/redis-cli-cpphelper.cpp @@ -0,0 +1,933 @@ +#include "fmacros.h" +#include "version.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include +#include /* use sds.h from hiredis, so that only one set of sds functions will be present in the binary */ +} +#include "dict.h" +#include "adlist.h" +#include "zmalloc.h" +#include "storage.h" + +#include "redis-cli.h" + +static dict *clusterManagerGetLinkStatus(void); + +/* The Cluster Manager global structure */ +struct clusterManager cluster_manager; + +extern "C" uint64_t dictSdsHash(const void *key) { + return dictGenHashFunction((unsigned char*)key, sdslen((char*)key)); +} + +extern "C" int dictSdsKeyCompare(void *privdata, const void *key1, + const void *key2) +{ + int l1,l2; + DICT_NOTUSED(privdata); + + l1 = sdslen((sds)key1); + l2 = sdslen((sds)key2); + if (l1 != l2) return 0; + return memcmp(key1, key2, l1) == 0; +} + +extern "C" void dictSdsDestructor(void *privdata, void *val) +{ + DICT_NOTUSED(privdata); + sdsfree((sds)val); +} + +extern "C" void dictListDestructor(void *privdata, void *val) +{ + DICT_NOTUSED(privdata); + listRelease((list*)val); +} + +/* Used by clusterManagerFixSlotsCoverage */ +dict *clusterManagerUncoveredSlots = NULL; + +/* Info about a cluster internal link. */ + +typedef struct clusterManagerLink { + sds node_name; + sds node_addr; + int connected; + int handshaking; +} clusterManagerLink; + +static dictType clusterManagerDictType = { + dictSdsHash, /* hash function */ + NULL, /* key dup */ + NULL, /* val dup */ + dictSdsKeyCompare, /* key compare */ + NULL, /* key destructor */ + dictSdsDestructor /* val destructor */ +}; + +static dictType clusterManagerLinkDictType = { + dictSdsHash, /* hash function */ + NULL, /* key dup */ + NULL, /* val dup */ + dictSdsKeyCompare, /* key compare */ + dictSdsDestructor, /* key destructor */ + dictListDestructor /* val destructor */ +}; + + +extern "C" void freeClusterManager(void) { + listIter li; + listNode *ln; + if (cluster_manager.nodes != NULL) { + listRewind(cluster_manager.nodes,&li); + while ((ln = listNext(&li)) != NULL) { + clusterManagerNode *n = (clusterManagerNode*)ln->value; + freeClusterManagerNode(n); + } + listRelease(cluster_manager.nodes); + cluster_manager.nodes = NULL; + } + if (cluster_manager.errors != NULL) { + listRewind(cluster_manager.errors,&li); + while ((ln = listNext(&li)) != NULL) { + sds err = (sds)ln->value; + sdsfree(err); + } + listRelease(cluster_manager.errors); + cluster_manager.errors = NULL; + } + if (clusterManagerUncoveredSlots != NULL) + dictRelease(clusterManagerUncoveredSlots); +} + +/* Return the anti-affinity score, which is a measure of the amount of + * violations of anti-affinity in the current cluster layout, that is, how + * badly the masters and slaves are distributed in the different IP + * addresses so that slaves of the same master are not in the master + * host and are also in different hosts. + * + * The score is calculated as follows: + * + * SAME_AS_MASTER = 10000 * each slave in the same IP of its master. + * SAME_AS_SLAVE = 1 * each slave having the same IP as another slave + of the same master. + * FINAL_SCORE = SAME_AS_MASTER + SAME_AS_SLAVE + * + * So a greater score means a worse anti-affinity level, while zero + * means perfect anti-affinity. + * + * The anti affinity optimizator will try to get a score as low as + * possible. Since we do not want to sacrifice the fact that slaves should + * not be in the same host as the master, we assign 10000 times the score + * to this violation, so that we'll optimize for the second factor only + * if it does not impact the first one. + * + * The ipnodes argument is an array of clusterManagerNodeArray, one for + * each IP, while ip_count is the total number of IPs in the configuration. + * + * The function returns the above score, and the list of + * offending slaves can be stored into the 'offending' argument, + * so that the optimizer can try changing the configuration of the + * slaves violating the anti-affinity goals. */ +int clusterManagerGetAntiAffinityScore(clusterManagerNodeArray *ipnodes, + int ip_count, clusterManagerNode ***offending, int *offending_len) +{ + int score = 0, i, j; + int node_len = cluster_manager.nodes->len; + clusterManagerNode **offending_p = NULL; + if (offending != NULL) { + *offending = (clusterManagerNode**)zcalloc(node_len * sizeof(clusterManagerNode*), MALLOC_LOCAL); + offending_p = *offending; + } + /* For each set of nodes in the same host, split by + * related nodes (masters and slaves which are involved in + * replication of each other) */ + for (i = 0; i < ip_count; i++) { + clusterManagerNodeArray *node_array = &(ipnodes[i]); + dict *related = dictCreate(&clusterManagerDictType, NULL); + char *ip = NULL; + for (j = 0; j < node_array->len; j++) { + clusterManagerNode *node = node_array->nodes[j]; + if (node == NULL) continue; + if (!ip) ip = node->ip; + sds types; + /* We always use the Master ID as key. */ + sds key = (!node->replicate ? node->name : node->replicate); + assert(key != NULL); + dictEntry *entry = dictFind(related, key); + if (entry) types = sdsdup((sds) dictGetVal(entry)); + else types = sdsempty(); + /* Master type 'm' is always set as the first character of the + * types string. */ + if (!node->replicate) types = sdscatprintf(types, "m%s", types); + else types = sdscat(types, "s"); + dictReplace(related, key, types); + } + /* Now it's trivial to check, for each related group having the + * same host, what is their local score. */ + dictIterator *iter = dictGetIterator(related); + dictEntry *entry; + while ((entry = dictNext(iter)) != NULL) { + sds types = (sds) dictGetVal(entry); + sds name = (sds) dictGetKey(entry); + int typeslen = sdslen(types); + if (typeslen < 2) continue; + if (types[0] == 'm') score += (10000 * (typeslen - 1)); + else score += (1 * typeslen); + if (offending == NULL) continue; + /* Populate the list of offending nodes. */ + listIter li; + listNode *ln; + listRewind(cluster_manager.nodes, &li); + while ((ln = listNext(&li)) != NULL) { + clusterManagerNode *n = (clusterManagerNode*)ln->value; + if (n->replicate == NULL) continue; + if (!strcmp(n->replicate, name) && !strcmp(n->ip, ip)) { + *(offending_p++) = n; + if (offending_len != NULL) (*offending_len)++; + break; + } + } + } + //if (offending_len != NULL) *offending_len = offending_p - *offending; + dictReleaseIterator(iter); + dictRelease(related); + } + return score; +} + + +/* Wait until the cluster configuration is consistent. */ +extern "C" void clusterManagerWaitForClusterJoin(void) { + printf("Waiting for the cluster to join\n"); + int counter = 0, + check_after = CLUSTER_JOIN_CHECK_AFTER + + (int)(listLength(cluster_manager.nodes) * 0.15f); + while(!clusterManagerIsConfigConsistent()) { + printf("."); + fflush(stdout); + sleep(1); + if (++counter > check_after) { + dict *status = clusterManagerGetLinkStatus(); + dictIterator *iter = NULL; + if (status != NULL && dictSize(status) > 0) { + printf("\n"); + clusterManagerLogErr("Warning: %d node(s) may " + "be unreachable\n", dictSize(status)); + iter = dictGetIterator(status); + dictEntry *entry; + while ((entry = dictNext(iter)) != NULL) { + sds nodeaddr = (sds) dictGetKey(entry); + char *node_ip = NULL; + int node_port = 0, node_bus_port = 0; + list *from = (list *) dictGetVal(entry); + if (parseClusterNodeAddress(nodeaddr, &node_ip, + &node_port, &node_bus_port) && node_bus_port) { + clusterManagerLogErr(" - The port %d of node %s may " + "be unreachable from:\n", + node_bus_port, node_ip); + } else { + clusterManagerLogErr(" - Node %s may be unreachable " + "from:\n", nodeaddr); + } + listIter li; + listNode *ln; + listRewind(from, &li); + while ((ln = listNext(&li)) != NULL) { + sds from_addr = (sds)ln->value; + clusterManagerLogErr(" %s\n", from_addr); + sdsfree(from_addr); + } + clusterManagerLogErr("Cluster bus ports must be reachable " + "by every node.\nRemember that " + "cluster bus ports are different " + "from standard instance ports.\n"); + listEmpty(from); + } + } + if (iter != NULL) dictReleaseIterator(iter); + if (status != NULL) dictRelease(status); + counter = 0; + } + } + printf("\n"); +} + +list *clusterManagerGetDisconnectedLinks(clusterManagerNode *node) { + list *links = NULL; + char *lines = NULL, *p, *line; + redisReply *reply = (redisReply*)CLUSTER_MANAGER_COMMAND(node, "CLUSTER NODES"); + if (!clusterManagerCheckRedisReply(node, reply, NULL)) goto cleanup; + links = listCreate(); + lines = reply->str; + while ((p = strstr(lines, "\n")) != NULL) { + int i = 0; + *p = '\0'; + line = lines; + lines = p + 1; + char *nodename = NULL, *addr = NULL, *flags = NULL, *link_status = NULL; + while ((p = strchr(line, ' ')) != NULL) { + *p = '\0'; + char *token = line; + line = p + 1; + if (i == 0) nodename = token; + else if (i == 1) addr = token; + else if (i == 2) flags = token; + else if (i == 7) link_status = token; + else if (i == 8) break; + i++; + } + if (i == 7) link_status = line; + if (nodename == NULL || addr == NULL || flags == NULL || + link_status == NULL) continue; + if (strstr(flags, "myself") != NULL) continue; + int disconnected = ((strstr(flags, "disconnected") != NULL) || + (strstr(link_status, "disconnected"))); + int handshaking = (strstr(flags, "handshake") != NULL); + if (disconnected || handshaking) { + clusterManagerLink *link = (clusterManagerLink*)zmalloc(sizeof(*link), MALLOC_LOCAL); + link->node_name = sdsnew(nodename); + link->node_addr = sdsnew(addr); + link->connected = 0; + link->handshaking = handshaking; + listAddNodeTail(links, link); + } + } +cleanup: + if (reply != NULL) freeReplyObject(reply); + return links; +} + +/* Check for disconnected cluster links. It returns a dict whose keys + * are the unreachable node addresses and the values are lists of + * node addresses that cannot reach the unreachable node. */ +dict *clusterManagerGetLinkStatus(void) { + if (cluster_manager.nodes == NULL) return NULL; + dict *status = dictCreate(&clusterManagerLinkDictType, NULL); + listIter li; + listNode *ln; + listRewind(cluster_manager.nodes, &li); + while ((ln = listNext(&li)) != NULL) { + clusterManagerNode *node = (clusterManagerNode*)ln->value; + list *links = clusterManagerGetDisconnectedLinks(node); + if (links) { + listIter lli; + listNode *lln; + listRewind(links, &lli); + while ((lln = listNext(&lli)) != NULL) { + clusterManagerLink *link = (clusterManagerLink*)lln->value; + list *from = NULL; + dictEntry *entry = dictFind(status, link->node_addr); + if (entry) from = (list*)dictGetVal(entry); + else { + from = listCreate(); + dictAdd(status, sdsdup(link->node_addr), from); + } + sds myaddr = sdsempty(); + myaddr = sdscatfmt(myaddr, "%s:%u", node->ip, node->port); + listAddNodeTail(from, myaddr); + sdsfree(link->node_name); + sdsfree(link->node_addr); + zfree(link); + } + listRelease(links); + } + } + return status; +} + + +/* This function returns a random master node, return NULL if none */ + +static clusterManagerNode *clusterManagerNodeMasterRandom() { + int master_count = 0; + int idx; + listIter li; + listNode *ln; + listRewind(cluster_manager.nodes, &li); + while ((ln = listNext(&li)) != NULL) { + clusterManagerNode *n = (clusterManagerNode*)ln->value; + if (n->flags & CLUSTER_MANAGER_FLAG_SLAVE) continue; + master_count++; + } + + srand(time(NULL)); + idx = rand() % master_count; + listRewind(cluster_manager.nodes, &li); + while ((ln = listNext(&li)) != NULL) { + clusterManagerNode *n = (clusterManagerNode*)ln->value; + if (n->flags & CLUSTER_MANAGER_FLAG_SLAVE) continue; + if (!idx--) { + return n; + } + } + /* Can not be reached */ + return NULL; +} + +static int clusterManagerFixSlotsCoverage(char *all_slots) { + int i, fixed = 0; + dictIterator *iter = nullptr; + dictEntry *entry = nullptr; + list *none = NULL, *single = NULL, *multi = NULL; + clusterManagerLogInfo(">>> Fixing slots coverage...\n"); + printf("List of not covered slots: \n"); + int uncovered_count = 0; + sds log = sdsempty(); + for (i = 0; i < CLUSTER_MANAGER_SLOTS; i++) { + int covered = all_slots[i]; + if (!covered) { + sds key = sdsfromlonglong((long long) i); + if (uncovered_count++ > 0) printf(","); + printf("%s", (char *) key); + list *slot_nodes = listCreate(); + sds slot_nodes_str = sdsempty(); + listIter li; + listNode *ln; + listRewind(cluster_manager.nodes, &li); + while ((ln = listNext(&li)) != NULL) { + clusterManagerNode *n = (clusterManagerNode*)ln->value; + if (n->flags & CLUSTER_MANAGER_FLAG_SLAVE || n->replicate) + continue; + redisReply *reply = (redisReply*)CLUSTER_MANAGER_COMMAND(n, + "CLUSTER GETKEYSINSLOT %d %d", i, 1); + if (!clusterManagerCheckRedisReply(n, reply, NULL)) { + fixed = -1; + if (reply) freeReplyObject(reply); + goto cleanup; + } + assert(reply->type == REDIS_REPLY_ARRAY); + if (reply->elements > 0) { + listAddNodeTail(slot_nodes, n); + if (listLength(slot_nodes) > 1) + slot_nodes_str = sdscat(slot_nodes_str, ", "); + slot_nodes_str = sdscatfmt(slot_nodes_str, + "%s:%u", n->ip, n->port); + } + freeReplyObject(reply); + } + log = sdscatfmt(log, "\nSlot %S has keys in %u nodes: %S", + key, listLength(slot_nodes), slot_nodes_str); + sdsfree(slot_nodes_str); + dictAdd(clusterManagerUncoveredSlots, key, slot_nodes); + } + } + printf("\n%s\n", log); + /* For every slot, take action depending on the actual condition: + * 1) No node has keys for this slot. + * 2) A single node has keys for this slot. + * 3) Multiple nodes have keys for this slot. */ + none = listCreate(); + single = listCreate(); + multi = listCreate(); + iter = dictGetIterator(clusterManagerUncoveredSlots); + while ((entry = dictNext(iter)) != NULL) { + sds slot = (sds) dictGetKey(entry); + list *nodes = (list *) dictGetVal(entry); + switch (listLength(nodes)){ + case 0: listAddNodeTail(none, slot); break; + case 1: listAddNodeTail(single, slot); break; + default: listAddNodeTail(multi, slot); break; + } + } + dictReleaseIterator(iter); + + /* Handle case "1": keys in no node. */ + if (listLength(none) > 0) { + printf("The following uncovered slots have no keys " + "across the cluster:\n"); + clusterManagerPrintSlotsList(none); + if (confirmWithYes("Fix these slots by covering with a random node?")){ + listIter li; + listNode *ln; + listRewind(none, &li); + while ((ln = listNext(&li)) != NULL) { + sds slot = (sds)ln->value; + int s = atoi(slot); + clusterManagerNode *n = clusterManagerNodeMasterRandom(); + clusterManagerLogInfo(">>> Covering slot %s with %s:%d\n", + slot, n->ip, n->port); + if (!clusterManagerSetSlotOwner(n, s, 0)) { + fixed = -1; + goto cleanup; + } + /* Since CLUSTER ADDSLOTS succeeded, we also update the slot + * info into the node struct, in order to keep it synced */ + n->slots[s] = 1; + fixed++; + } + } + } + + /* Handle case "2": keys only in one node. */ + if (listLength(single) > 0) { + printf("The following uncovered slots have keys in just one node:\n"); + clusterManagerPrintSlotsList(single); + if (confirmWithYes("Fix these slots by covering with those nodes?")){ + listIter li; + listNode *ln; + listRewind(single, &li); + while ((ln = listNext(&li)) != NULL) { + sds slot = (sds)ln->value; + int s = atoi(slot); + dictEntry *entry = dictFind(clusterManagerUncoveredSlots, slot); + assert(entry != NULL); + list *nodes = (list *) dictGetVal(entry); + listNode *fn = listFirst(nodes); + assert(fn != NULL); + clusterManagerNode *n = (clusterManagerNode*)fn->value; + clusterManagerLogInfo(">>> Covering slot %s with %s:%d\n", + slot, n->ip, n->port); + if (!clusterManagerSetSlotOwner(n, s, 0)) { + fixed = -1; + goto cleanup; + } + /* Since CLUSTER ADDSLOTS succeeded, we also update the slot + * info into the node struct, in order to keep it synced */ + n->slots[atoi(slot)] = 1; + fixed++; + } + } + } + + /* Handle case "3": keys in multiple nodes. */ + if (listLength(multi) > 0) { + printf("The following uncovered slots have keys in multiple nodes:\n"); + clusterManagerPrintSlotsList(multi); + if (confirmWithYes("Fix these slots by moving keys " + "into a single node?")) { + listIter li; + listNode *ln; + listRewind(multi, &li); + while ((ln = listNext(&li)) != NULL) { + sds slot = (sds)ln->value; + dictEntry *entry = dictFind(clusterManagerUncoveredSlots, slot); + assert(entry != NULL); + list *nodes = (list *) dictGetVal(entry); + int s = atoi(slot); + clusterManagerNode *target = + clusterManagerGetNodeWithMostKeysInSlot(nodes, s, NULL); + if (target == NULL) { + fixed = -1; + goto cleanup; + } + clusterManagerLogInfo(">>> Covering slot %s moving keys " + "to %s:%d\n", slot, + target->ip, target->port); + if (!clusterManagerSetSlotOwner(target, s, 1)) { + fixed = -1; + goto cleanup; + } + /* Since CLUSTER ADDSLOTS succeeded, we also update the slot + * info into the node struct, in order to keep it synced */ + target->slots[atoi(slot)] = 1; + listIter nli; + listNode *nln; + listRewind(nodes, &nli); + while ((nln = listNext(&nli)) != NULL) { + clusterManagerNode *src = (clusterManagerNode*)nln->value; + if (src == target) continue; + /* Assign the slot to target node in the source node. */ + if (!clusterManagerSetSlot(src, target, s, "NODE", NULL)) + fixed = -1; + if (fixed < 0) goto cleanup; + /* Set the source node in 'importing' state + * (even if we will actually migrate keys away) + * in order to avoid receiving redirections + * for MIGRATE. */ + if (!clusterManagerSetSlot(src, target, s, + "IMPORTING", NULL)) fixed = -1; + if (fixed < 0) goto cleanup; + int opts = CLUSTER_MANAGER_OPT_VERBOSE | + CLUSTER_MANAGER_OPT_COLD; + if (!clusterManagerMoveSlot(src, target, s, opts, NULL)) { + fixed = -1; + goto cleanup; + } + if (!clusterManagerClearSlotStatus(src, s)) + fixed = -1; + if (fixed < 0) goto cleanup; + } + fixed++; + } + } + } +cleanup: + sdsfree(log); + if (none) listRelease(none); + if (single) listRelease(single); + if (multi) listRelease(multi); + return fixed; +} + + +extern "C" int clusterManagerCheckCluster(int quiet) { + listNode *ln = listFirst(cluster_manager.nodes); + if (!ln) return 0; + clusterManagerNode *node = (clusterManagerNode*)ln->value; + clusterManagerLogInfo(">>> Performing Cluster Check (using node %s:%d)\n", + node->ip, node->port); + int result = 1, consistent = 0; + int do_fix = config.cluster_manager_command.flags & + CLUSTER_MANAGER_CMD_FLAG_FIX; + if (!quiet) clusterManagerShowNodes(); + consistent = clusterManagerIsConfigConsistent(); + if (!consistent) { + sds err = sdsnew("[ERR] Nodes don't agree about configuration!"); + clusterManagerOnError(err); + result = 0; + } else { + clusterManagerLogOk("[OK] All nodes agree about slots " + "configuration.\n"); + } + /* Check open slots */ + clusterManagerLogInfo(">>> Check for open slots...\n"); + listIter li; + listRewind(cluster_manager.nodes, &li); + int i; + dict *open_slots = NULL; + while ((ln = listNext(&li)) != NULL) { + clusterManagerNode *n = (clusterManagerNode*)ln->value; + if (n->migrating != NULL) { + if (open_slots == NULL) + open_slots = dictCreate(&clusterManagerDictType, NULL); + sds errstr = sdsempty(); + errstr = sdscatprintf(errstr, + "[WARNING] Node %s:%d has slots in " + "migrating state ", + n->ip, + n->port); + for (i = 0; i < n->migrating_count; i += 2) { + sds slot = n->migrating[i]; + dictReplace(open_slots, slot, sdsdup(n->migrating[i + 1])); + const char *fmt = (i > 0 ? ",%S" : "%S"); + errstr = sdscatfmt(errstr, fmt, slot); + } + errstr = sdscat(errstr, "."); + clusterManagerOnError(errstr); + } + if (n->importing != NULL) { + if (open_slots == NULL) + open_slots = dictCreate(&clusterManagerDictType, NULL); + sds errstr = sdsempty(); + errstr = sdscatprintf(errstr, + "[WARNING] Node %s:%d has slots in " + "importing state ", + n->ip, + n->port); + for (i = 0; i < n->importing_count; i += 2) { + sds slot = n->importing[i]; + dictReplace(open_slots, slot, sdsdup(n->importing[i + 1])); + const char *fmt = (i > 0 ? ",%S" : "%S"); + errstr = sdscatfmt(errstr, fmt, slot); + } + errstr = sdscat(errstr, "."); + clusterManagerOnError(errstr); + } + } + if (open_slots != NULL) { + result = 0; + dictIterator *iter = dictGetIterator(open_slots); + dictEntry *entry; + sds errstr = sdsnew("[WARNING] The following slots are open: "); + i = 0; + while ((entry = dictNext(iter)) != NULL) { + sds slot = (sds) dictGetKey(entry); + const char *fmt = (i++ > 0 ? ",%S" : "%S"); + errstr = sdscatfmt(errstr, fmt, slot); + } + clusterManagerLogErr("%s.\n", (char *) errstr); + sdsfree(errstr); + if (do_fix) { + /* Fix open slots. */ + dictReleaseIterator(iter); + iter = dictGetIterator(open_slots); + while ((entry = dictNext(iter)) != NULL) { + sds slot = (sds) dictGetKey(entry); + result = clusterManagerFixOpenSlot(atoi(slot)); + if (!result) break; + } + } + dictReleaseIterator(iter); + dictRelease(open_slots); + } + clusterManagerLogInfo(">>> Check slots coverage...\n"); + char slots[CLUSTER_MANAGER_SLOTS]; + memset(slots, 0, CLUSTER_MANAGER_SLOTS); + int coverage = clusterManagerGetCoveredSlots(slots); + if (coverage == CLUSTER_MANAGER_SLOTS) { + clusterManagerLogOk("[OK] All %d slots covered.\n", + CLUSTER_MANAGER_SLOTS); + } else { + sds err = sdsempty(); + err = sdscatprintf(err, "[ERR] Not all %d slots are " + "covered by nodes.\n", + CLUSTER_MANAGER_SLOTS); + clusterManagerOnError(err); + result = 0; + if (do_fix/* && result*/) { + dictType dtype = clusterManagerDictType; + dtype.keyDestructor = dictSdsDestructor; + dtype.valDestructor = dictListDestructor; + clusterManagerUncoveredSlots = dictCreate(&dtype, NULL); + int fixed = clusterManagerFixSlotsCoverage(slots); + if (fixed > 0) result = 1; + } + } + int search_multiple_owners = config.cluster_manager_command.flags & + CLUSTER_MANAGER_CMD_FLAG_CHECK_OWNERS; + if (search_multiple_owners) { + /* Check whether there are multiple owners, even when slots are + * fully covered and there are no open slots. */ + clusterManagerLogInfo(">>> Check for multiple slot owners...\n"); + int slot = 0, slots_with_multiple_owners = 0; + for (; slot < CLUSTER_MANAGER_SLOTS; slot++) { + listIter li; + listNode *ln; + listRewind(cluster_manager.nodes, &li); + list *owners = listCreate(); + while ((ln = listNext(&li)) != NULL) { + clusterManagerNode *n = (clusterManagerNode*)ln->value; + if (n->flags & CLUSTER_MANAGER_FLAG_SLAVE) continue; + if (n->slots[slot]) listAddNodeTail(owners, n); + else { + /* Nodes having keys for the slot will be considered + * owners too. */ + int count = clusterManagerCountKeysInSlot(n, slot); + if (count > 0) listAddNodeTail(owners, n); + } + } + if (listLength(owners) > 1) { + result = 0; + clusterManagerLogErr("[WARNING] Slot %d has %d owners:\n", + slot, listLength(owners)); + listRewind(owners, &li); + while ((ln = listNext(&li)) != NULL) { + clusterManagerNode *n = (clusterManagerNode*)ln->value; + clusterManagerLogErr(" %s:%d\n", n->ip, n->port); + } + slots_with_multiple_owners++; + if (do_fix) { + result = clusterManagerFixMultipleSlotOwners(slot, owners); + if (!result) { + clusterManagerLogErr("Failed to fix multiple owners " + "for slot %d\n", slot); + listRelease(owners); + break; + } else slots_with_multiple_owners--; + } + } + listRelease(owners); + } + if (slots_with_multiple_owners == 0) + clusterManagerLogOk("[OK] No multiple owners found.\n"); + } + return result; +} + +static typeinfo* typeinfo_add(dict *types, const char* name, typeinfo* type_template) { + typeinfo *info = (typeinfo*)zmalloc(sizeof(typeinfo), MALLOC_LOCAL); + *info = *type_template; + info->name = sdsnew(name); + dictAdd(types, info->name, info); + return info; +} + +static dictType typeinfoDictType = { + dictSdsHash, /* hash function */ + NULL, /* key dup */ + NULL, /* val dup */ + dictSdsKeyCompare, /* key compare */ + NULL, /* key destructor (owned by the value)*/ + type_free /* val destructor */ +}; + +static void getKeyTypes(dict *types_dict, redisReply *keys, typeinfo **types) { + redisReply *reply; + unsigned int i; + + /* Pipeline TYPE commands */ + for(i=0;ielements;i++) { + redisAppendCommand(context, "TYPE %s", keys->element[i]->str); + } + + /* Retrieve types */ + for(i=0;ielements;i++) { + if(redisGetReply(context, (void**)&reply)!=REDIS_OK) { + fprintf(stderr, "Error getting type for key '%s' (%d: %s)\n", + keys->element[i]->str, context->err, context->errstr); + exit(1); + } else if(reply->type != REDIS_REPLY_STATUS) { + if(reply->type == REDIS_REPLY_ERROR) { + fprintf(stderr, "TYPE returned an error: %s\n", reply->str); + } else { + fprintf(stderr, + "Invalid reply type (%d) for TYPE on key '%s'!\n", + reply->type, keys->element[i]->str); + } + exit(1); + } + + sds typereply = sdsnew(reply->str); + dictEntry *de = dictFind(types_dict, typereply); + sdsfree(typereply); + typeinfo *type = NULL; + if (de) + type = (typeinfo*)dictGetVal(de); + else if (strcmp(reply->str, "none")) /* create new types for modules, (but not for deleted keys) */ + type = typeinfo_add(types_dict, reply->str, &type_other); + types[i] = type; + freeReplyObject(reply); + } +} + +void findBigKeys(int memkeys, unsigned memkeys_samples) { + unsigned long long sampled = 0, total_keys, totlen=0, *sizes=NULL, it=0; + redisReply *reply, *keys; + unsigned int arrsize=0, i; + dictIterator *di; + dictEntry *de; + typeinfo **types = NULL; + double pct; + + dict *types_dict = dictCreate(&typeinfoDictType, NULL); + typeinfo_add(types_dict, "string", &type_string); + typeinfo_add(types_dict, "list", &type_list); + typeinfo_add(types_dict, "set", &type_set); + typeinfo_add(types_dict, "hash", &type_hash); + typeinfo_add(types_dict, "zset", &type_zset); + typeinfo_add(types_dict, "stream", &type_stream); + + /* Total keys pre scanning */ + total_keys = getDbSize(); + + /* Status message */ + printf("\n# Scanning the entire keyspace to find biggest keys as well as\n"); + printf("# average sizes per key type. You can use -i 0.1 to sleep 0.1 sec\n"); + printf("# per 100 SCAN commands (not usually needed).\n\n"); + + /* SCAN loop */ + do { + /* Calculate approximate percentage completion */ + pct = 100 * (double)sampled/total_keys; + + /* Grab some keys and point to the keys array */ + reply = sendScan(&it); + keys = reply->element[1]; + + /* Reallocate our type and size array if we need to */ + if(keys->elements > arrsize) { + types = (typeinfo**)zrealloc(types, sizeof(int)*keys->elements, MALLOC_LOCAL); + sizes = (unsigned long long*)zrealloc(sizes, sizeof(unsigned long long)*keys->elements, MALLOC_LOCAL); + + if(!types || !sizes) { + fprintf(stderr, "Failed to allocate storage for keys!\n"); + exit(1); + } + + arrsize = keys->elements; + } + + /* Retrieve types and then sizes */ + getKeyTypes(types_dict, keys, types); + getKeySizes(keys, types, sizes, memkeys, memkeys_samples); + + /* Now update our stats */ + for(i=0;ielements;i++) { + typeinfo *type = types[i]; + /* Skip keys that disappeared between SCAN and TYPE */ + if(!type) + continue; + + type->totalsize += sizes[i]; + type->count++; + totlen += keys->element[i]->len; + sampled++; + + if(type->biggestname, keys->element[i]->str, sizes[i], + !memkeys? type->sizeunit: "bytes"); + + /* Keep track of biggest key name for this type */ + if (type->biggest_key) + sdsfree(type->biggest_key); + type->biggest_key = sdsnew(keys->element[i]->str); + if(!type->biggest_key) { + fprintf(stderr, "Failed to allocate memory for key!\n"); + exit(1); + } + + /* Keep track of the biggest size for this type */ + type->biggest = sizes[i]; + } + + /* Update overall progress */ + if(sampled % 1000000 == 0) { + printf("[%05.2f%%] Sampled %llu keys so far\n", pct, sampled); + } + } + + /* Sleep if we've been directed to do so */ + if(sampled && (sampled %100) == 0 && config.interval) { + usleep(config.interval); + } + + freeReplyObject(reply); + } while(it != 0); + + if(types) zfree(types); + if(sizes) zfree(sizes); + + /* We're done */ + printf("\n-------- summary -------\n\n"); + + printf("Sampled %llu keys in the keyspace!\n", sampled); + printf("Total key length in bytes is %llu (avg len %.2f)\n\n", + totlen, totlen ? (double)totlen/sampled : 0); + + /* Output the biggest keys we found, for types we did find */ + di = dictGetIterator(types_dict); + while ((de = dictNext(di))) { + typeinfo *type = (typeinfo*)dictGetVal(de); + if(type->biggest_key) { + printf("Biggest %6s found '%s' has %llu %s\n", type->name, type->biggest_key, + type->biggest, !memkeys? type->sizeunit: "bytes"); + } + } + dictReleaseIterator(di); + + printf("\n"); + + di = dictGetIterator(types_dict); + while ((de = dictNext(di))) { + typeinfo *type = (typeinfo*)dictGetVal(de); + printf("%llu %ss with %llu %s (%05.2f%% of keys, avg size %.2f)\n", + type->count, type->name, type->totalsize, !memkeys? type->sizeunit: "bytes", + sampled ? 100 * (double)type->count/sampled : 0, + type->count ? (double)type->totalsize/type->count : 0); + } + dictReleaseIterator(di); + + dictRelease(types_dict); + + /* Success! */ + exit(0); +} diff --git a/src/redis-cli.c b/src/redis-cli.c index 25f8b775d..40c8501fe 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -48,7 +48,6 @@ #include #include /* use sds.h from hiredis, so that only one set of sds functions will be present in the binary */ -#include "dict.h" #include "adlist.h" #include "zmalloc.h" #include "linenoise.h" @@ -57,181 +56,11 @@ #include "ae.h" #include "storage.h" -#define UNUSED(V) ((void) V) - -#define OUTPUT_STANDARD 0 -#define OUTPUT_RAW 1 -#define OUTPUT_CSV 2 -#define REDIS_CLI_KEEPALIVE_INTERVAL 15 /* seconds */ -#define REDIS_CLI_DEFAULT_PIPE_TIMEOUT 30 /* seconds */ -#define REDIS_CLI_HISTFILE_ENV "REDISCLI_HISTFILE" -#define REDIS_CLI_HISTFILE_DEFAULT ".rediscli_history" -#define REDIS_CLI_RCFILE_ENV "REDISCLI_RCFILE" -#define REDIS_CLI_RCFILE_DEFAULT ".redisclirc" -#define REDIS_CLI_AUTH_ENV "REDISCLI_AUTH" - -#define CLUSTER_MANAGER_SLOTS 16384 -#define CLUSTER_MANAGER_MIGRATE_TIMEOUT 60000 -#define CLUSTER_MANAGER_MIGRATE_PIPELINE 10 -#define CLUSTER_MANAGER_REBALANCE_THRESHOLD 2 - -#define CLUSTER_MANAGER_INVALID_HOST_ARG \ - "[ERR] Invalid arguments: you need to pass either a valid " \ - "address (ie. 120.0.0.1:7000) or space separated IP " \ - "and port (ie. 120.0.0.1 7000)\n" -#define CLUSTER_MANAGER_MODE() (config.cluster_manager_command.name != NULL) -#define CLUSTER_MANAGER_MASTERS_COUNT(nodes, replicas) (nodes/(replicas + 1)) -#define CLUSTER_MANAGER_COMMAND(n,...) \ - (redisCommand(n->context, __VA_ARGS__)) - -#define CLUSTER_MANAGER_NODE_ARRAY_FREE(array) zfree(array->alloc) - -#define CLUSTER_MANAGER_PRINT_REPLY_ERROR(n, err) \ - clusterManagerLogErr("Node %s:%d replied with error:\n%s\n", \ - n->ip, n->port, err); - -#define clusterManagerLogInfo(...) \ - clusterManagerLog(CLUSTER_MANAGER_LOG_LVL_INFO,__VA_ARGS__) - -#define clusterManagerLogErr(...) \ - clusterManagerLog(CLUSTER_MANAGER_LOG_LVL_ERR,__VA_ARGS__) - -#define clusterManagerLogWarn(...) \ - clusterManagerLog(CLUSTER_MANAGER_LOG_LVL_WARN,__VA_ARGS__) - -#define clusterManagerLogOk(...) \ - clusterManagerLog(CLUSTER_MANAGER_LOG_LVL_SUCCESS,__VA_ARGS__) - -#define CLUSTER_MANAGER_FLAG_MYSELF 1 << 0 -#define CLUSTER_MANAGER_FLAG_SLAVE 1 << 1 -#define CLUSTER_MANAGER_FLAG_FRIEND 1 << 2 -#define CLUSTER_MANAGER_FLAG_NOADDR 1 << 3 -#define CLUSTER_MANAGER_FLAG_DISCONNECT 1 << 4 -#define CLUSTER_MANAGER_FLAG_FAIL 1 << 5 - -#define CLUSTER_MANAGER_CMD_FLAG_FIX 1 << 0 -#define CLUSTER_MANAGER_CMD_FLAG_SLAVE 1 << 1 -#define CLUSTER_MANAGER_CMD_FLAG_YES 1 << 2 -#define CLUSTER_MANAGER_CMD_FLAG_AUTOWEIGHTS 1 << 3 -#define CLUSTER_MANAGER_CMD_FLAG_EMPTYMASTER 1 << 4 -#define CLUSTER_MANAGER_CMD_FLAG_SIMULATE 1 << 5 -#define CLUSTER_MANAGER_CMD_FLAG_REPLACE 1 << 6 -#define CLUSTER_MANAGER_CMD_FLAG_COPY 1 << 7 -#define CLUSTER_MANAGER_CMD_FLAG_COLOR 1 << 8 -#define CLUSTER_MANAGER_CMD_FLAG_CHECK_OWNERS 1 << 9 - -#define CLUSTER_MANAGER_OPT_GETFRIENDS 1 << 0 -#define CLUSTER_MANAGER_OPT_COLD 1 << 1 -#define CLUSTER_MANAGER_OPT_UPDATE 1 << 2 -#define CLUSTER_MANAGER_OPT_QUIET 1 << 6 -#define CLUSTER_MANAGER_OPT_VERBOSE 1 << 7 - -#define CLUSTER_MANAGER_LOG_LVL_INFO 1 -#define CLUSTER_MANAGER_LOG_LVL_WARN 2 -#define CLUSTER_MANAGER_LOG_LVL_ERR 3 -#define CLUSTER_MANAGER_LOG_LVL_SUCCESS 4 - -#define CLUSTER_JOIN_CHECK_AFTER 20 - -#define LOG_COLOR_BOLD "29;1m" -#define LOG_COLOR_RED "31;1m" -#define LOG_COLOR_GREEN "32;1m" -#define LOG_COLOR_YELLOW "33;1m" -#define LOG_COLOR_RESET "0m" - -/* cliConnect() flags. */ -#define CC_FORCE (1<<0) /* Re-connect if already connected. */ -#define CC_QUIET (1<<1) /* Don't log connecting errors. */ - -/* --latency-dist palettes. */ -int spectrum_palette_color_size = 19; -int spectrum_palette_color[] = {0,233,234,235,237,239,241,243,245,247,144,143,142,184,226,214,208,202,196}; - -int spectrum_palette_mono_size = 13; -int spectrum_palette_mono[] = {0,233,234,235,237,239,241,243,245,247,249,251,253}; - -/* The actual palette in use. */ -int *spectrum_palette; -int spectrum_palette_size; - -/* Dict Helpers */ - -static uint64_t dictSdsHash(const void *key); -static int dictSdsKeyCompare(void *privdata, const void *key1, - const void *key2); -static void dictSdsDestructor(void *privdata, void *val); -static void dictListDestructor(void *privdata, void *val); - -/* Cluster Manager Command Info */ -typedef struct clusterManagerCommand { - char *name; - int argc; - char **argv; - int flags; - int replicas; - char *from; - char *to; - char **weight; - int weight_argc; - char *master_id; - int slots; - int timeout; - int pipeline; - float threshold; - char *backup_dir; -} clusterManagerCommand; - -static void createClusterManagerCommand(char *cmdname, int argc, char **argv); +#include "redis-cli.h" -static redisContext *context; -static struct config { - char *hostip; - int hostport; - char *hostsocket; - long repeat; - long interval; - int dbnum; - int interactive; - int shutdown; - int monitor_mode; - int pubsub_mode; - int latency_mode; - int latency_dist_mode; - int latency_history; - int lru_test_mode; - long long lru_test_sample_size; - int cluster_mode; - int cluster_reissue_command; - int slave_mode; - int pipe_mode; - int pipe_timeout; - int getrdb_mode; - int stat_mode; - int scan_mode; - int intrinsic_latency_mode; - int intrinsic_latency_duration; - char *pattern; - char *rdb_filename; - int bigkeys; - int memkeys; - unsigned memkeys_samples; - int hotkeys; - int stdinarg; /* get last arg from stdin. (-x option) */ - char *auth; - int output; /* output mode, see OUTPUT_* defines */ - sds mb_delim; - char prompt[128]; - char *eval; - int eval_ldb; - int eval_ldb_sync; /* Ask for synchronous mode of the Lua debugger. */ - int eval_ldb_end; /* Lua debugging session ended. */ - int enable_ldb_on_eval; /* Handle manual SCRIPT DEBUG + EVAL commands. */ - int last_cmd_type; - int verbose; - clusterManagerCommand cluster_manager_command; - int no_auth_warning; -} config; +redisContext *context; +struct config config; /* User preferences. */ static struct pref { @@ -248,12 +77,29 @@ static int cliConnect(int force); static char *getInfoField(char *info, char *field); static long getLongInfoField(char *info, char *field); +/* --latency-dist palettes. */ +int spectrum_palette_color_size = 19; +int spectrum_palette_color[] = {0,233,234,235,237,239,241,243,245,247,144,143,142,184,226,214,208,202,196}; + +int spectrum_palette_mono_size = 13; +int spectrum_palette_mono[] = {0,233,234,235,237,239,241,243,245,247,249,251,253}; + +/* The actual palette in use. */ +int *spectrum_palette; +int spectrum_palette_size; + /*------------------------------------------------------------------------------ * Utility functions *--------------------------------------------------------------------------- */ uint16_t crc16(const char *buf, int len); +uint64_t dictSdsHash(const void *key); +int dictSdsKeyCompare(void *privdata, const void *key1, + const void *key2); +void dictSdsDestructor(void *privdata, void *val); +void dictListDestructor(void *privdata, void *val); + static long long ustime(void) { struct timeval tv; long long ust; @@ -407,34 +253,6 @@ static void parseRedisUri(const char *uri) { config.dbnum = atoi(curr); } -static uint64_t dictSdsHash(const void *key) { - return dictGenHashFunction((unsigned char*)key, sdslen((char*)key)); -} - -static int dictSdsKeyCompare(void *privdata, const void *key1, - const void *key2) -{ - int l1,l2; - DICT_NOTUSED(privdata); - - l1 = sdslen((sds)key1); - l2 = sdslen((sds)key2); - if (l1 != l2) return 0; - return memcmp(key1, key2, l1) == 0; -} - -static void dictSdsDestructor(void *privdata, void *val) -{ - DICT_NOTUSED(privdata); - sdsfree(val); -} - -void dictListDestructor(void *privdata, void *val) -{ - DICT_NOTUSED(privdata); - listRelease((list*)val); -} - /* _serverAssert is needed by dict */ void _serverAssert(const char *estr, const char *file, int line) { fprintf(stderr, "=== ASSERTION FAILED ==="); @@ -1593,7 +1411,7 @@ static void usage(void) { exit(1); } -static int confirmWithYes(char *msg) { +int confirmWithYes(const char *msg) { printf("%s (type 'yes' to accept): ", msg); fflush(stdout); char buf[4]; @@ -1930,80 +1748,8 @@ static int evalMode(int argc, char **argv) { *--------------------------------------------------------------------------- */ /* The Cluster Manager global structure */ -static struct clusterManager { - list *nodes; /* List of nodes in the configuration. */ - list *errors; -} cluster_manager; +struct cluster_manager; -/* Used by clusterManagerFixSlotsCoverage */ -dict *clusterManagerUncoveredSlots = NULL; - -typedef struct clusterManagerNode { - redisContext *context; - sds name; - char *ip; - int port; - uint64_t current_epoch; - time_t ping_sent; - time_t ping_recv; - int flags; - list *flags_str; /* Flags string representations */ - sds replicate; /* Master ID if node is a slave */ - int dirty; /* Node has changes that can be flushed */ - uint8_t slots[CLUSTER_MANAGER_SLOTS]; - int slots_count; - int replicas_count; - list *friends; - sds *migrating; /* An array of sds where even strings are slots and odd - * strings are the destination node IDs. */ - sds *importing; /* An array of sds where even strings are slots and odd - * strings are the source node IDs. */ - int migrating_count; /* Length of the migrating array (migrating slots*2) */ - int importing_count; /* Length of the importing array (importing slots*2) */ - float weight; /* Weight used by rebalance */ - int balance; /* Used by rebalance */ -} clusterManagerNode; - -/* Data structure used to represent a sequence of cluster nodes. */ -typedef struct clusterManagerNodeArray { - clusterManagerNode **nodes; /* Actual nodes array */ - clusterManagerNode **alloc; /* Pointer to the allocated memory */ - int len; /* Actual length of the array */ - int count; /* Non-NULL nodes count */ -} clusterManagerNodeArray; - -/* Used for the reshard table. */ -typedef struct clusterManagerReshardTableItem { - clusterManagerNode *source; - int slot; -} clusterManagerReshardTableItem; - -/* Info about a cluster internal link. */ - -typedef struct clusterManagerLink { - sds node_name; - sds node_addr; - int connected; - int handshaking; -} clusterManagerLink; - -static dictType clusterManagerDictType = { - dictSdsHash, /* hash function */ - NULL, /* key dup */ - NULL, /* val dup */ - dictSdsKeyCompare, /* key compare */ - NULL, /* key destructor */ - dictSdsDestructor /* val destructor */ -}; - -static dictType clusterManagerLinkDictType = { - dictSdsHash, /* hash function */ - NULL, /* key dup */ - NULL, /* val dup */ - dictSdsKeyCompare, /* key compare */ - dictSdsDestructor, /* key destructor */ - dictListDestructor /* val destructor */ -}; typedef int clusterManagerCommandProc(int argc, char **argv); typedef int (*clusterManagerOnReplyError)(redisReply *reply, @@ -2022,20 +1768,14 @@ static int clusterManagerNodeLoadInfo(clusterManagerNode *node, int opts, char **err); static int clusterManagerLoadInfoFromNode(clusterManagerNode *node, int opts); static int clusterManagerNodeIsEmpty(clusterManagerNode *node, char **err); -static int clusterManagerGetAntiAffinityScore(clusterManagerNodeArray *ipnodes, - int ip_count, clusterManagerNode ***offending, int *offending_len); static void clusterManagerOptimizeAntiAffinity(clusterManagerNodeArray *ipnodes, int ip_count); static sds clusterManagerNodeInfo(clusterManagerNode *node, int indent); -static void clusterManagerShowNodes(void); static void clusterManagerShowClusterInfo(void); static int clusterManagerFlushNodeConfig(clusterManagerNode *node, char **err); -static void clusterManagerWaitForClusterJoin(void); -static int clusterManagerCheckCluster(int quiet); -static void clusterManagerLog(int level, const char* fmt, ...); -static int clusterManagerIsConfigConsistent(void); -static dict *clusterManagerGetLinkStatus(void); -static void clusterManagerOnError(sds err); +void clusterManagerWaitForClusterJoin(void); +int clusterManagerCheckCluster(int quiet); +void clusterManagerOnError(sds err); static void clusterManagerNodeArrayInit(clusterManagerNodeArray *array, int len); static void clusterManagerNodeArrayReset(clusterManagerNodeArray *array); @@ -2098,7 +1838,7 @@ clusterManagerCommandDef clusterManagerCommands[] = { static void getRDB(clusterManagerNode *node); -static void createClusterManagerCommand(char *cmdname, int argc, char **argv) { +void createClusterManagerCommand(char *cmdname, int argc, char **argv) { clusterManagerCommand *cmd = &config.cluster_manager_command; cmd->name = cmdname; cmd->argc = argc; @@ -2129,7 +1869,7 @@ static clusterManagerCommandProc *validateClusterManagerCommand(void) { return proc; } -static int parseClusterNodeAddress(char *addr, char **ip_ptr, int *port_ptr, +int parseClusterNodeAddress(char *addr, char **ip_ptr, int *port_ptr, int *bus_port_ptr) { char *c = strrchr(addr, '@'); @@ -2183,7 +1923,7 @@ static void freeClusterManagerNodeFlags(list *flags) { listRelease(flags); } -static void freeClusterManagerNode(clusterManagerNode *node) { +void freeClusterManagerNode(clusterManagerNode *node) { if (node->context != NULL) redisFree(node->context); if (node->friends != NULL) { listIter li; @@ -2216,30 +1956,7 @@ static void freeClusterManagerNode(clusterManagerNode *node) { zfree(node); } -static void freeClusterManager(void) { - listIter li; - listNode *ln; - if (cluster_manager.nodes != NULL) { - listRewind(cluster_manager.nodes,&li); - while ((ln = listNext(&li)) != NULL) { - clusterManagerNode *n = ln->value; - freeClusterManagerNode(n); - } - listRelease(cluster_manager.nodes); - cluster_manager.nodes = NULL; - } - if (cluster_manager.errors != NULL) { - listRewind(cluster_manager.errors,&li); - while ((ln = listNext(&li)) != NULL) { - sds err = ln->value; - sdsfree(err); - } - listRelease(cluster_manager.errors); - cluster_manager.errors = NULL; - } - if (clusterManagerUncoveredSlots != NULL) - dictRelease(clusterManagerUncoveredSlots); -} +void freeClusterManager(void); static clusterManagerNode *clusterManagerNewNode(char *ip, int port) { clusterManagerNode *node = zmalloc(sizeof(*node), MALLOC_LOCAL); @@ -2280,7 +1997,7 @@ static sds clusterManagerGetNodeRDBFilename(clusterManagerNode *node) { * latest case, if the 'err' arg is not NULL, it gets allocated with a copy * of reply error (it's up to the caller function to free it), elsewhere * the error is directly printed. */ -static int clusterManagerCheckRedisReply(clusterManagerNode *n, +int clusterManagerCheckRedisReply(clusterManagerNode *n, redisReply *r, char **err) { int is_err = 0; @@ -2474,102 +2191,6 @@ result: return is_empty; } -/* Return the anti-affinity score, which is a measure of the amount of - * violations of anti-affinity in the current cluster layout, that is, how - * badly the masters and slaves are distributed in the different IP - * addresses so that slaves of the same master are not in the master - * host and are also in different hosts. - * - * The score is calculated as follows: - * - * SAME_AS_MASTER = 10000 * each slave in the same IP of its master. - * SAME_AS_SLAVE = 1 * each slave having the same IP as another slave - of the same master. - * FINAL_SCORE = SAME_AS_MASTER + SAME_AS_SLAVE - * - * So a greater score means a worse anti-affinity level, while zero - * means perfect anti-affinity. - * - * The anti affinity optimizator will try to get a score as low as - * possible. Since we do not want to sacrifice the fact that slaves should - * not be in the same host as the master, we assign 10000 times the score - * to this violation, so that we'll optimize for the second factor only - * if it does not impact the first one. - * - * The ipnodes argument is an array of clusterManagerNodeArray, one for - * each IP, while ip_count is the total number of IPs in the configuration. - * - * The function returns the above score, and the list of - * offending slaves can be stored into the 'offending' argument, - * so that the optimizer can try changing the configuration of the - * slaves violating the anti-affinity goals. */ -static int clusterManagerGetAntiAffinityScore(clusterManagerNodeArray *ipnodes, - int ip_count, clusterManagerNode ***offending, int *offending_len) -{ - int score = 0, i, j; - int node_len = cluster_manager.nodes->len; - clusterManagerNode **offending_p = NULL; - if (offending != NULL) { - *offending = zcalloc(node_len * sizeof(clusterManagerNode*), MALLOC_LOCAL); - offending_p = *offending; - } - /* For each set of nodes in the same host, split by - * related nodes (masters and slaves which are involved in - * replication of each other) */ - for (i = 0; i < ip_count; i++) { - clusterManagerNodeArray *node_array = &(ipnodes[i]); - dict *related = dictCreate(&clusterManagerDictType, NULL); - char *ip = NULL; - for (j = 0; j < node_array->len; j++) { - clusterManagerNode *node = node_array->nodes[j]; - if (node == NULL) continue; - if (!ip) ip = node->ip; - sds types; - /* We always use the Master ID as key. */ - sds key = (!node->replicate ? node->name : node->replicate); - assert(key != NULL); - dictEntry *entry = dictFind(related, key); - if (entry) types = sdsdup((sds) dictGetVal(entry)); - else types = sdsempty(); - /* Master type 'm' is always set as the first character of the - * types string. */ - if (!node->replicate) types = sdscatprintf(types, "m%s", types); - else types = sdscat(types, "s"); - dictReplace(related, key, types); - } - /* Now it's trivial to check, for each related group having the - * same host, what is their local score. */ - dictIterator *iter = dictGetIterator(related); - dictEntry *entry; - while ((entry = dictNext(iter)) != NULL) { - sds types = (sds) dictGetVal(entry); - sds name = (sds) dictGetKey(entry); - int typeslen = sdslen(types); - if (typeslen < 2) continue; - if (types[0] == 'm') score += (10000 * (typeslen - 1)); - else score += (1 * typeslen); - if (offending == NULL) continue; - /* Populate the list of offending nodes. */ - listIter li; - listNode *ln; - listRewind(cluster_manager.nodes, &li); - while ((ln = listNext(&li)) != NULL) { - clusterManagerNode *n = ln->value; - if (n->replicate == NULL) continue; - if (!strcmp(n->replicate, name) && !strcmp(n->ip, ip)) { - *(offending_p++) = n; - if (offending_len != NULL) (*offending_len)++; - break; - } - } - } - //if (offending_len != NULL) *offending_len = offending_p - *offending; - dictReleaseIterator(iter); - dictRelease(related); - } - return score; -} - static void clusterManagerOptimizeAntiAffinity(clusterManagerNodeArray *ipnodes, int ip_count) { @@ -2834,7 +2455,7 @@ static sds clusterManagerNodeInfo(clusterManagerNode *node, int indent) { return info; } -static void clusterManagerShowNodes(void) { +void clusterManagerShowNodes(void) { listIter li; listNode *ln; listRewind(cluster_manager.nodes, &li); @@ -2990,7 +2611,7 @@ static clusterManagerNode *clusterManagerGetSlotOwner(clusterManagerNode *n, } /* Set slot status to "importing" or "migrating" */ -static int clusterManagerSetSlot(clusterManagerNode *node1, +int clusterManagerSetSlot(clusterManagerNode *node1, clusterManagerNode *node2, int slot, const char *status, char **err) { redisReply *reply = CLUSTER_MANAGER_COMMAND(node1, "CLUSTER " @@ -3013,7 +2634,7 @@ cleanup: return success; } -static int clusterManagerClearSlotStatus(clusterManagerNode *node, int slot) { +int clusterManagerClearSlotStatus(clusterManagerNode *node, int slot) { redisReply *reply = CLUSTER_MANAGER_COMMAND(node, "CLUSTER SETSLOT %d %s", slot, "STABLE"); int success = clusterManagerCheckRedisReply(node, reply, NULL); @@ -3058,7 +2679,7 @@ static int clusterManagerAddSlot(clusterManagerNode *node, int slot) { return success; } -static signed int clusterManagerCountKeysInSlot(clusterManagerNode *node, +signed int clusterManagerCountKeysInSlot(clusterManagerNode *node, int slot) { redisReply *reply = CLUSTER_MANAGER_COMMAND(node, @@ -3089,7 +2710,7 @@ static int clusterManagerOnSetOwnerErr(redisReply *reply, return (bulk_idx != 1); } -static int clusterManagerSetSlotOwner(clusterManagerNode *owner, +int clusterManagerSetSlotOwner(clusterManagerNode *owner, int slot, int do_clear) { @@ -3408,7 +3029,7 @@ next: * CLUSTER_MANAGER_OPT_UPDATE -- Update node->slots for source/target nodes. * CLUSTER_MANAGER_OPT_QUIET -- Don't print info messages. */ -static int clusterManagerMoveSlot(clusterManagerNode *source, +int clusterManagerMoveSlot(clusterManagerNode *source, clusterManagerNode *target, int slot, int opts, char**err) { @@ -3501,62 +3122,6 @@ cleanup: return success; } -/* Wait until the cluster configuration is consistent. */ -static void clusterManagerWaitForClusterJoin(void) { - printf("Waiting for the cluster to join\n"); - int counter = 0, - check_after = CLUSTER_JOIN_CHECK_AFTER + - (int)(listLength(cluster_manager.nodes) * 0.15f); - while(!clusterManagerIsConfigConsistent()) { - printf("."); - fflush(stdout); - sleep(1); - if (++counter > check_after) { - dict *status = clusterManagerGetLinkStatus(); - dictIterator *iter = NULL; - if (status != NULL && dictSize(status) > 0) { - printf("\n"); - clusterManagerLogErr("Warning: %d node(s) may " - "be unreachable\n", dictSize(status)); - iter = dictGetIterator(status); - dictEntry *entry; - while ((entry = dictNext(iter)) != NULL) { - sds nodeaddr = (sds) dictGetKey(entry); - char *node_ip = NULL; - int node_port = 0, node_bus_port = 0; - list *from = (list *) dictGetVal(entry); - if (parseClusterNodeAddress(nodeaddr, &node_ip, - &node_port, &node_bus_port) && node_bus_port) { - clusterManagerLogErr(" - The port %d of node %s may " - "be unreachable from:\n", - node_bus_port, node_ip); - } else { - clusterManagerLogErr(" - Node %s may be unreachable " - "from:\n", nodeaddr); - } - listIter li; - listNode *ln; - listRewind(from, &li); - while ((ln = listNext(&li)) != NULL) { - sds from_addr = ln->value; - clusterManagerLogErr(" %s\n", from_addr); - sdsfree(from_addr); - } - clusterManagerLogErr("Cluster bus ports must be reachable " - "by every node.\nRemember that " - "cluster bus ports are different " - "from standard instance ports.\n"); - listEmpty(from); - } - } - if (iter != NULL) dictReleaseIterator(iter); - if (status != NULL) dictRelease(status); - counter = 0; - } - } - printf("\n"); -} - /* Load node's cluster configuration by calling "CLUSTER NODES" command. * Node's configuration (name, replicate, slots, ...) is then updated. * If CLUSTER_MANAGER_OPT_GETFRIENDS flag is set into 'opts' argument, @@ -3929,7 +3494,7 @@ cleanup: return signature; } -static int clusterManagerIsConfigConsistent(void) { +int clusterManagerIsConfigConsistent(void) { if (cluster_manager.nodes == NULL) return 0; int consistent = (listLength(cluster_manager.nodes) <= 1); // If the Cluster has only one node, it's always consistent @@ -3956,90 +3521,8 @@ static int clusterManagerIsConfigConsistent(void) { return consistent; } -static list *clusterManagerGetDisconnectedLinks(clusterManagerNode *node) { - list *links = NULL; - redisReply *reply = CLUSTER_MANAGER_COMMAND(node, "CLUSTER NODES"); - if (!clusterManagerCheckRedisReply(node, reply, NULL)) goto cleanup; - links = listCreate(); - char *lines = reply->str, *p, *line; - while ((p = strstr(lines, "\n")) != NULL) { - int i = 0; - *p = '\0'; - line = lines; - lines = p + 1; - char *nodename = NULL, *addr = NULL, *flags = NULL, *link_status = NULL; - while ((p = strchr(line, ' ')) != NULL) { - *p = '\0'; - char *token = line; - line = p + 1; - if (i == 0) nodename = token; - else if (i == 1) addr = token; - else if (i == 2) flags = token; - else if (i == 7) link_status = token; - else if (i == 8) break; - i++; - } - if (i == 7) link_status = line; - if (nodename == NULL || addr == NULL || flags == NULL || - link_status == NULL) continue; - if (strstr(flags, "myself") != NULL) continue; - int disconnected = ((strstr(flags, "disconnected") != NULL) || - (strstr(link_status, "disconnected"))); - int handshaking = (strstr(flags, "handshake") != NULL); - if (disconnected || handshaking) { - clusterManagerLink *link = zmalloc(sizeof(*link), MALLOC_LOCAL); - link->node_name = sdsnew(nodename); - link->node_addr = sdsnew(addr); - link->connected = 0; - link->handshaking = handshaking; - listAddNodeTail(links, link); - } - } -cleanup: - if (reply != NULL) freeReplyObject(reply); - return links; -} - -/* Check for disconnected cluster links. It returns a dict whose keys - * are the unreachable node addresses and the values are lists of - * node addresses that cannot reach the unreachable node. */ -static dict *clusterManagerGetLinkStatus(void) { - if (cluster_manager.nodes == NULL) return NULL; - dict *status = dictCreate(&clusterManagerLinkDictType, NULL); - listIter li; - listNode *ln; - listRewind(cluster_manager.nodes, &li); - while ((ln = listNext(&li)) != NULL) { - clusterManagerNode *node = ln->value; - list *links = clusterManagerGetDisconnectedLinks(node); - if (links) { - listIter lli; - listNode *lln; - listRewind(links, &lli); - while ((lln = listNext(&lli)) != NULL) { - clusterManagerLink *link = lln->value; - list *from = NULL; - dictEntry *entry = dictFind(status, link->node_addr); - if (entry) from = dictGetVal(entry); - else { - from = listCreate(); - dictAdd(status, sdsdup(link->node_addr), from); - } - sds myaddr = sdsempty(); - myaddr = sdscatfmt(myaddr, "%s:%u", node->ip, node->port); - listAddNodeTail(from, myaddr); - sdsfree(link->node_name); - sdsfree(link->node_addr); - zfree(link); - } - listRelease(links); - } - } - return status; -} - /* Add the error string to cluster_manager.errors and print it. */ -static void clusterManagerOnError(sds err) { +void clusterManagerOnError(sds err) { if (cluster_manager.errors == NULL) cluster_manager.errors = listCreate(); listAddNodeTail(cluster_manager.errors, err); @@ -4049,7 +3532,7 @@ static void clusterManagerOnError(sds err) { /* Check the slots coverage of the cluster. The 'all_slots' argument must be * and array of 16384 bytes. Every covered slot will be set to 1 in the * 'all_slots' array. The function returns the total number if covered slots.*/ -static int clusterManagerGetCoveredSlots(char *all_slots) { +int clusterManagerGetCoveredSlots(char *all_slots) { if (cluster_manager.nodes == NULL) return 0; listIter li; listNode *ln; @@ -4067,7 +3550,7 @@ static int clusterManagerGetCoveredSlots(char *all_slots) { return totslots; } -static void clusterManagerPrintSlotsList(list *slots) { +void clusterManagerPrintSlotsList(list *slots) { listIter li; listNode *ln; listRewind(slots, &li); @@ -4083,7 +3566,7 @@ static void clusterManagerPrintSlotsList(list *slots) { /* Return the node, among 'nodes' with the greatest number of keys * in the specified slot. */ -static clusterManagerNode * clusterManagerGetNodeWithMostKeysInSlot(list *nodes, +clusterManagerNode * clusterManagerGetNodeWithMostKeysInSlot(list *nodes, int slot, char **err) { @@ -4139,232 +3622,10 @@ static clusterManagerNode *clusterManagerNodeWithLeastReplicas() { return node; } -/* This function returns a random master node, return NULL if none */ - -static clusterManagerNode *clusterManagerNodeMasterRandom() { - int master_count = 0; - int idx; - listIter li; - listNode *ln; - listRewind(cluster_manager.nodes, &li); - while ((ln = listNext(&li)) != NULL) { - clusterManagerNode *n = ln->value; - if (n->flags & CLUSTER_MANAGER_FLAG_SLAVE) continue; - master_count++; - } - - srand(time(NULL)); - idx = rand() % master_count; - listRewind(cluster_manager.nodes, &li); - while ((ln = listNext(&li)) != NULL) { - clusterManagerNode *n = ln->value; - if (n->flags & CLUSTER_MANAGER_FLAG_SLAVE) continue; - if (!idx--) { - return n; - } - } - /* Can not be reached */ - return NULL; -} - -static int clusterManagerFixSlotsCoverage(char *all_slots) { - int i, fixed = 0; - list *none = NULL, *single = NULL, *multi = NULL; - clusterManagerLogInfo(">>> Fixing slots coverage...\n"); - printf("List of not covered slots: \n"); - int uncovered_count = 0; - sds log = sdsempty(); - for (i = 0; i < CLUSTER_MANAGER_SLOTS; i++) { - int covered = all_slots[i]; - if (!covered) { - sds key = sdsfromlonglong((long long) i); - if (uncovered_count++ > 0) printf(","); - printf("%s", (char *) key); - list *slot_nodes = listCreate(); - sds slot_nodes_str = sdsempty(); - listIter li; - listNode *ln; - listRewind(cluster_manager.nodes, &li); - while ((ln = listNext(&li)) != NULL) { - clusterManagerNode *n = ln->value; - if (n->flags & CLUSTER_MANAGER_FLAG_SLAVE || n->replicate) - continue; - redisReply *reply = CLUSTER_MANAGER_COMMAND(n, - "CLUSTER GETKEYSINSLOT %d %d", i, 1); - if (!clusterManagerCheckRedisReply(n, reply, NULL)) { - fixed = -1; - if (reply) freeReplyObject(reply); - goto cleanup; - } - assert(reply->type == REDIS_REPLY_ARRAY); - if (reply->elements > 0) { - listAddNodeTail(slot_nodes, n); - if (listLength(slot_nodes) > 1) - slot_nodes_str = sdscat(slot_nodes_str, ", "); - slot_nodes_str = sdscatfmt(slot_nodes_str, - "%s:%u", n->ip, n->port); - } - freeReplyObject(reply); - } - log = sdscatfmt(log, "\nSlot %S has keys in %u nodes: %S", - key, listLength(slot_nodes), slot_nodes_str); - sdsfree(slot_nodes_str); - dictAdd(clusterManagerUncoveredSlots, key, slot_nodes); - } - } - printf("\n%s\n", log); - /* For every slot, take action depending on the actual condition: - * 1) No node has keys for this slot. - * 2) A single node has keys for this slot. - * 3) Multiple nodes have keys for this slot. */ - none = listCreate(); - single = listCreate(); - multi = listCreate(); - dictIterator *iter = dictGetIterator(clusterManagerUncoveredSlots); - dictEntry *entry; - while ((entry = dictNext(iter)) != NULL) { - sds slot = (sds) dictGetKey(entry); - list *nodes = (list *) dictGetVal(entry); - switch (listLength(nodes)){ - case 0: listAddNodeTail(none, slot); break; - case 1: listAddNodeTail(single, slot); break; - default: listAddNodeTail(multi, slot); break; - } - } - dictReleaseIterator(iter); - - /* Handle case "1": keys in no node. */ - if (listLength(none) > 0) { - printf("The following uncovered slots have no keys " - "across the cluster:\n"); - clusterManagerPrintSlotsList(none); - if (confirmWithYes("Fix these slots by covering with a random node?")){ - listIter li; - listNode *ln; - listRewind(none, &li); - while ((ln = listNext(&li)) != NULL) { - sds slot = ln->value; - int s = atoi(slot); - clusterManagerNode *n = clusterManagerNodeMasterRandom(); - clusterManagerLogInfo(">>> Covering slot %s with %s:%d\n", - slot, n->ip, n->port); - if (!clusterManagerSetSlotOwner(n, s, 0)) { - fixed = -1; - goto cleanup; - } - /* Since CLUSTER ADDSLOTS succeeded, we also update the slot - * info into the node struct, in order to keep it synced */ - n->slots[s] = 1; - fixed++; - } - } - } - - /* Handle case "2": keys only in one node. */ - if (listLength(single) > 0) { - printf("The following uncovered slots have keys in just one node:\n"); - clusterManagerPrintSlotsList(single); - if (confirmWithYes("Fix these slots by covering with those nodes?")){ - listIter li; - listNode *ln; - listRewind(single, &li); - while ((ln = listNext(&li)) != NULL) { - sds slot = ln->value; - int s = atoi(slot); - dictEntry *entry = dictFind(clusterManagerUncoveredSlots, slot); - assert(entry != NULL); - list *nodes = (list *) dictGetVal(entry); - listNode *fn = listFirst(nodes); - assert(fn != NULL); - clusterManagerNode *n = fn->value; - clusterManagerLogInfo(">>> Covering slot %s with %s:%d\n", - slot, n->ip, n->port); - if (!clusterManagerSetSlotOwner(n, s, 0)) { - fixed = -1; - goto cleanup; - } - /* Since CLUSTER ADDSLOTS succeeded, we also update the slot - * info into the node struct, in order to keep it synced */ - n->slots[atoi(slot)] = 1; - fixed++; - } - } - } - - /* Handle case "3": keys in multiple nodes. */ - if (listLength(multi) > 0) { - printf("The following uncovered slots have keys in multiple nodes:\n"); - clusterManagerPrintSlotsList(multi); - if (confirmWithYes("Fix these slots by moving keys " - "into a single node?")) { - listIter li; - listNode *ln; - listRewind(multi, &li); - while ((ln = listNext(&li)) != NULL) { - sds slot = ln->value; - dictEntry *entry = dictFind(clusterManagerUncoveredSlots, slot); - assert(entry != NULL); - list *nodes = (list *) dictGetVal(entry); - int s = atoi(slot); - clusterManagerNode *target = - clusterManagerGetNodeWithMostKeysInSlot(nodes, s, NULL); - if (target == NULL) { - fixed = -1; - goto cleanup; - } - clusterManagerLogInfo(">>> Covering slot %s moving keys " - "to %s:%d\n", slot, - target->ip, target->port); - if (!clusterManagerSetSlotOwner(target, s, 1)) { - fixed = -1; - goto cleanup; - } - /* Since CLUSTER ADDSLOTS succeeded, we also update the slot - * info into the node struct, in order to keep it synced */ - target->slots[atoi(slot)] = 1; - listIter nli; - listNode *nln; - listRewind(nodes, &nli); - while ((nln = listNext(&nli)) != NULL) { - clusterManagerNode *src = nln->value; - if (src == target) continue; - /* Assign the slot to target node in the source node. */ - if (!clusterManagerSetSlot(src, target, s, "NODE", NULL)) - fixed = -1; - if (fixed < 0) goto cleanup; - /* Set the source node in 'importing' state - * (even if we will actually migrate keys away) - * in order to avoid receiving redirections - * for MIGRATE. */ - if (!clusterManagerSetSlot(src, target, s, - "IMPORTING", NULL)) fixed = -1; - if (fixed < 0) goto cleanup; - int opts = CLUSTER_MANAGER_OPT_VERBOSE | - CLUSTER_MANAGER_OPT_COLD; - if (!clusterManagerMoveSlot(src, target, s, opts, NULL)) { - fixed = -1; - goto cleanup; - } - if (!clusterManagerClearSlotStatus(src, s)) - fixed = -1; - if (fixed < 0) goto cleanup; - } - fixed++; - } - } - } -cleanup: - sdsfree(log); - if (none) listRelease(none); - if (single) listRelease(single); - if (multi) listRelease(multi); - return fixed; -} - /* Slot 'slot' was found to be in importing or migrating state in one or * more nodes. This function fixes this condition by migrating keys where * it seems more sensible. */ -static int clusterManagerFixOpenSlot(int slot) { +int clusterManagerFixOpenSlot(int slot) { clusterManagerLogInfo(">>> Fixing open slot %d\n", slot); /* Try to obtain the current slot owner, according to the current * nodes configuration. */ @@ -4674,7 +3935,7 @@ cleanup: return success; } -static int clusterManagerFixMultipleSlotOwners(int slot, list *owners) { +int clusterManagerFixMultipleSlotOwners(int slot, list *owners) { clusterManagerLogInfo(">>> Fixing multiple owners for slot %d...\n", slot); int success = 0; assert(listLength(owners) > 1); @@ -4711,170 +3972,6 @@ static int clusterManagerFixMultipleSlotOwners(int slot, list *owners) { return success; } -static int clusterManagerCheckCluster(int quiet) { - listNode *ln = listFirst(cluster_manager.nodes); - if (!ln) return 0; - clusterManagerNode *node = ln->value; - clusterManagerLogInfo(">>> Performing Cluster Check (using node %s:%d)\n", - node->ip, node->port); - int result = 1, consistent = 0; - int do_fix = config.cluster_manager_command.flags & - CLUSTER_MANAGER_CMD_FLAG_FIX; - if (!quiet) clusterManagerShowNodes(); - consistent = clusterManagerIsConfigConsistent(); - if (!consistent) { - sds err = sdsnew("[ERR] Nodes don't agree about configuration!"); - clusterManagerOnError(err); - result = 0; - } else { - clusterManagerLogOk("[OK] All nodes agree about slots " - "configuration.\n"); - } - /* Check open slots */ - clusterManagerLogInfo(">>> Check for open slots...\n"); - listIter li; - listRewind(cluster_manager.nodes, &li); - int i; - dict *open_slots = NULL; - while ((ln = listNext(&li)) != NULL) { - clusterManagerNode *n = ln->value; - if (n->migrating != NULL) { - if (open_slots == NULL) - open_slots = dictCreate(&clusterManagerDictType, NULL); - sds errstr = sdsempty(); - errstr = sdscatprintf(errstr, - "[WARNING] Node %s:%d has slots in " - "migrating state ", - n->ip, - n->port); - for (i = 0; i < n->migrating_count; i += 2) { - sds slot = n->migrating[i]; - dictReplace(open_slots, slot, sdsdup(n->migrating[i + 1])); - char *fmt = (i > 0 ? ",%S" : "%S"); - errstr = sdscatfmt(errstr, fmt, slot); - } - errstr = sdscat(errstr, "."); - clusterManagerOnError(errstr); - } - if (n->importing != NULL) { - if (open_slots == NULL) - open_slots = dictCreate(&clusterManagerDictType, NULL); - sds errstr = sdsempty(); - errstr = sdscatprintf(errstr, - "[WARNING] Node %s:%d has slots in " - "importing state ", - n->ip, - n->port); - for (i = 0; i < n->importing_count; i += 2) { - sds slot = n->importing[i]; - dictReplace(open_slots, slot, sdsdup(n->importing[i + 1])); - char *fmt = (i > 0 ? ",%S" : "%S"); - errstr = sdscatfmt(errstr, fmt, slot); - } - errstr = sdscat(errstr, "."); - clusterManagerOnError(errstr); - } - } - if (open_slots != NULL) { - result = 0; - dictIterator *iter = dictGetIterator(open_slots); - dictEntry *entry; - sds errstr = sdsnew("[WARNING] The following slots are open: "); - i = 0; - while ((entry = dictNext(iter)) != NULL) { - sds slot = (sds) dictGetKey(entry); - char *fmt = (i++ > 0 ? ",%S" : "%S"); - errstr = sdscatfmt(errstr, fmt, slot); - } - clusterManagerLogErr("%s.\n", (char *) errstr); - sdsfree(errstr); - if (do_fix) { - /* Fix open slots. */ - dictReleaseIterator(iter); - iter = dictGetIterator(open_slots); - while ((entry = dictNext(iter)) != NULL) { - sds slot = (sds) dictGetKey(entry); - result = clusterManagerFixOpenSlot(atoi(slot)); - if (!result) break; - } - } - dictReleaseIterator(iter); - dictRelease(open_slots); - } - clusterManagerLogInfo(">>> Check slots coverage...\n"); - char slots[CLUSTER_MANAGER_SLOTS]; - memset(slots, 0, CLUSTER_MANAGER_SLOTS); - int coverage = clusterManagerGetCoveredSlots(slots); - if (coverage == CLUSTER_MANAGER_SLOTS) { - clusterManagerLogOk("[OK] All %d slots covered.\n", - CLUSTER_MANAGER_SLOTS); - } else { - sds err = sdsempty(); - err = sdscatprintf(err, "[ERR] Not all %d slots are " - "covered by nodes.\n", - CLUSTER_MANAGER_SLOTS); - clusterManagerOnError(err); - result = 0; - if (do_fix/* && result*/) { - dictType dtype = clusterManagerDictType; - dtype.keyDestructor = dictSdsDestructor; - dtype.valDestructor = dictListDestructor; - clusterManagerUncoveredSlots = dictCreate(&dtype, NULL); - int fixed = clusterManagerFixSlotsCoverage(slots); - if (fixed > 0) result = 1; - } - } - int search_multiple_owners = config.cluster_manager_command.flags & - CLUSTER_MANAGER_CMD_FLAG_CHECK_OWNERS; - if (search_multiple_owners) { - /* Check whether there are multiple owners, even when slots are - * fully covered and there are no open slots. */ - clusterManagerLogInfo(">>> Check for multiple slot owners...\n"); - int slot = 0, slots_with_multiple_owners = 0; - for (; slot < CLUSTER_MANAGER_SLOTS; slot++) { - listIter li; - listNode *ln; - listRewind(cluster_manager.nodes, &li); - list *owners = listCreate(); - while ((ln = listNext(&li)) != NULL) { - clusterManagerNode *n = ln->value; - if (n->flags & CLUSTER_MANAGER_FLAG_SLAVE) continue; - if (n->slots[slot]) listAddNodeTail(owners, n); - else { - /* Nodes having keys for the slot will be considered - * owners too. */ - int count = clusterManagerCountKeysInSlot(n, slot); - if (count > 0) listAddNodeTail(owners, n); - } - } - if (listLength(owners) > 1) { - result = 0; - clusterManagerLogErr("[WARNING] Slot %d has %d owners:\n", - slot, listLength(owners)); - listRewind(owners, &li); - while ((ln = listNext(&li)) != NULL) { - clusterManagerNode *n = ln->value; - clusterManagerLogErr(" %s:%d\n", n->ip, n->port); - } - slots_with_multiple_owners++; - if (do_fix) { - result = clusterManagerFixMultipleSlotOwners(slot, owners); - if (!result) { - clusterManagerLogErr("Failed to fix multiple owners " - "for slot %d\n", slot); - listRelease(owners); - break; - } else slots_with_multiple_owners--; - } - } - listRelease(owners); - } - if (slots_with_multiple_owners == 0) - clusterManagerLogOk("[OK] No multiple owners found.\n"); - } - return result; -} - static clusterManagerNode *clusterNodeForResharding(char *id, clusterManagerNode *target, int *raise_err) @@ -4958,7 +4055,7 @@ static void clusterManagerReleaseReshardTable(list *table) { } } -static void clusterManagerLog(int level, const char* fmt, ...) { +void clusterManagerLog(int level, const char* fmt, ...) { int use_colors = (config.cluster_manager_command.flags & CLUSTER_MANAGER_CMD_FLAG_COLOR); if (use_colors) { @@ -6852,7 +5949,7 @@ static void pipeMode(void) { * Find big keys *--------------------------------------------------------------------------- */ -static redisReply *sendScan(unsigned long long *it) { +redisReply *sendScan(unsigned long long *it) { redisReply *reply = redisCommand(context, "SCAN %llu", *it); /* Handle any error conditions */ @@ -6880,7 +5977,7 @@ static redisReply *sendScan(unsigned long long *it) { return reply; } -static int getDbSize(void) { +int getDbSize(void) { redisReply *reply; int size; @@ -6898,16 +5995,6 @@ static int getDbSize(void) { return size; } -typedef struct { - char *name; - char *sizecmd; - char *sizeunit; - unsigned long long biggest; - unsigned long long count; - unsigned long long totalsize; - sds biggest_key; -} typeinfo; - typeinfo type_string = { "string", "STRLEN", "bytes" }; typeinfo type_list = { "list", "LLEN", "items" }; typeinfo type_set = { "set", "SCARD", "members" }; @@ -6916,14 +6003,6 @@ typeinfo type_zset = { "zset", "ZCARD", "members" }; typeinfo type_stream = { "stream", "XLEN", "entries" }; typeinfo type_other = { "other", NULL, "?" }; -static typeinfo* typeinfo_add(dict *types, char* name, typeinfo* type_template) { - typeinfo *info = zmalloc(sizeof(typeinfo), MALLOC_LOCAL); - *info = *type_template; - info->name = sdsnew(name); - dictAdd(types, info->name, info); - return info; -} - void type_free(void* priv_data, void* val) { typeinfo *info = val; UNUSED(priv_data); @@ -6933,55 +6012,7 @@ void type_free(void* priv_data, void* val) { zfree(info); } -static dictType typeinfoDictType = { - dictSdsHash, /* hash function */ - NULL, /* key dup */ - NULL, /* val dup */ - dictSdsKeyCompare, /* key compare */ - NULL, /* key destructor (owned by the value)*/ - type_free /* val destructor */ -}; - -static void getKeyTypes(dict *types_dict, redisReply *keys, typeinfo **types) { - redisReply *reply; - unsigned int i; - - /* Pipeline TYPE commands */ - for(i=0;ielements;i++) { - redisAppendCommand(context, "TYPE %s", keys->element[i]->str); - } - - /* Retrieve types */ - for(i=0;ielements;i++) { - if(redisGetReply(context, (void**)&reply)!=REDIS_OK) { - fprintf(stderr, "Error getting type for key '%s' (%d: %s)\n", - keys->element[i]->str, context->err, context->errstr); - exit(1); - } else if(reply->type != REDIS_REPLY_STATUS) { - if(reply->type == REDIS_REPLY_ERROR) { - fprintf(stderr, "TYPE returned an error: %s\n", reply->str); - } else { - fprintf(stderr, - "Invalid reply type (%d) for TYPE on key '%s'!\n", - reply->type, keys->element[i]->str); - } - exit(1); - } - - sds typereply = sdsnew(reply->str); - dictEntry *de = dictFind(types_dict, typereply); - sdsfree(typereply); - typeinfo *type = NULL; - if (de) - type = dictGetVal(de); - else if (strcmp(reply->str, "none")) /* create new types for modules, (but not for deleted keys) */ - type = typeinfo_add(types_dict, reply->str, &type_other); - types[i] = type; - freeReplyObject(reply); - } -} - -static void getKeySizes(redisReply *keys, typeinfo **types, +void getKeySizes(redisReply *keys, typeinfo **types, unsigned long long *sizes, int memkeys, unsigned memkeys_samples) { @@ -7034,141 +6065,6 @@ static void getKeySizes(redisReply *keys, typeinfo **types, } } -static void findBigKeys(int memkeys, unsigned memkeys_samples) { - unsigned long long sampled = 0, total_keys, totlen=0, *sizes=NULL, it=0; - redisReply *reply, *keys; - unsigned int arrsize=0, i; - dictIterator *di; - dictEntry *de; - typeinfo **types = NULL; - double pct; - - dict *types_dict = dictCreate(&typeinfoDictType, NULL); - typeinfo_add(types_dict, "string", &type_string); - typeinfo_add(types_dict, "list", &type_list); - typeinfo_add(types_dict, "set", &type_set); - typeinfo_add(types_dict, "hash", &type_hash); - typeinfo_add(types_dict, "zset", &type_zset); - typeinfo_add(types_dict, "stream", &type_stream); - - /* Total keys pre scanning */ - total_keys = getDbSize(); - - /* Status message */ - printf("\n# Scanning the entire keyspace to find biggest keys as well as\n"); - printf("# average sizes per key type. You can use -i 0.1 to sleep 0.1 sec\n"); - printf("# per 100 SCAN commands (not usually needed).\n\n"); - - /* SCAN loop */ - do { - /* Calculate approximate percentage completion */ - pct = 100 * (double)sampled/total_keys; - - /* Grab some keys and point to the keys array */ - reply = sendScan(&it); - keys = reply->element[1]; - - /* Reallocate our type and size array if we need to */ - if(keys->elements > arrsize) { - types = zrealloc(types, sizeof(int)*keys->elements, MALLOC_LOCAL); - sizes = zrealloc(sizes, sizeof(unsigned long long)*keys->elements, MALLOC_LOCAL); - - if(!types || !sizes) { - fprintf(stderr, "Failed to allocate storage for keys!\n"); - exit(1); - } - - arrsize = keys->elements; - } - - /* Retrieve types and then sizes */ - getKeyTypes(types_dict, keys, types); - getKeySizes(keys, types, sizes, memkeys, memkeys_samples); - - /* Now update our stats */ - for(i=0;ielements;i++) { - typeinfo *type = types[i]; - /* Skip keys that disappeared between SCAN and TYPE */ - if(!type) - continue; - - type->totalsize += sizes[i]; - type->count++; - totlen += keys->element[i]->len; - sampled++; - - if(type->biggestname, keys->element[i]->str, sizes[i], - !memkeys? type->sizeunit: "bytes"); - - /* Keep track of biggest key name for this type */ - if (type->biggest_key) - sdsfree(type->biggest_key); - type->biggest_key = sdsnew(keys->element[i]->str); - if(!type->biggest_key) { - fprintf(stderr, "Failed to allocate memory for key!\n"); - exit(1); - } - - /* Keep track of the biggest size for this type */ - type->biggest = sizes[i]; - } - - /* Update overall progress */ - if(sampled % 1000000 == 0) { - printf("[%05.2f%%] Sampled %llu keys so far\n", pct, sampled); - } - } - - /* Sleep if we've been directed to do so */ - if(sampled && (sampled %100) == 0 && config.interval) { - usleep(config.interval); - } - - freeReplyObject(reply); - } while(it != 0); - - if(types) zfree(types); - if(sizes) zfree(sizes); - - /* We're done */ - printf("\n-------- summary -------\n\n"); - - printf("Sampled %llu keys in the keyspace!\n", sampled); - printf("Total key length in bytes is %llu (avg len %.2f)\n\n", - totlen, totlen ? (double)totlen/sampled : 0); - - /* Output the biggest keys we found, for types we did find */ - di = dictGetIterator(types_dict); - while ((de = dictNext(di))) { - typeinfo *type = dictGetVal(de); - if(type->biggest_key) { - printf("Biggest %6s found '%s' has %llu %s\n", type->name, type->biggest_key, - type->biggest, !memkeys? type->sizeunit: "bytes"); - } - } - dictReleaseIterator(di); - - printf("\n"); - - di = dictGetIterator(types_dict); - while ((de = dictNext(di))) { - typeinfo *type = dictGetVal(de); - printf("%llu %ss with %llu %s (%05.2f%% of keys, avg size %.2f)\n", - type->count, type->name, type->totalsize, !memkeys? type->sizeunit: "bytes", - sampled ? 100 * (double)type->count/sampled : 0, - type->count ? (double)type->totalsize/type->count : 0); - } - dictReleaseIterator(di); - - dictRelease(types_dict); - - /* Success! */ - exit(0); -} - static void getKeyFreqs(redisReply *keys, unsigned long long *freqs) { redisReply *reply; unsigned int i; diff --git a/src/redis-cli.h b/src/redis-cli.h new file mode 100644 index 000000000..bda80c42b --- /dev/null +++ b/src/redis-cli.h @@ -0,0 +1,279 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define UNUSED(V) ((void) V) + +#define OUTPUT_STANDARD 0 +#define OUTPUT_RAW 1 +#define OUTPUT_CSV 2 +#define REDIS_CLI_KEEPALIVE_INTERVAL 15 /* seconds */ +#define REDIS_CLI_DEFAULT_PIPE_TIMEOUT 30 /* seconds */ +#define REDIS_CLI_HISTFILE_ENV "REDISCLI_HISTFILE" +#define REDIS_CLI_HISTFILE_DEFAULT ".rediscli_history" +#define REDIS_CLI_RCFILE_ENV "REDISCLI_RCFILE" +#define REDIS_CLI_RCFILE_DEFAULT ".redisclirc" +#define REDIS_CLI_AUTH_ENV "REDISCLI_AUTH" + +#define CLUSTER_MANAGER_SLOTS 16384 +#define CLUSTER_MANAGER_MIGRATE_TIMEOUT 60000 +#define CLUSTER_MANAGER_MIGRATE_PIPELINE 10 +#define CLUSTER_MANAGER_REBALANCE_THRESHOLD 2 + +#define CLUSTER_MANAGER_INVALID_HOST_ARG \ + "[ERR] Invalid arguments: you need to pass either a valid " \ + "address (ie. 120.0.0.1:7000) or space separated IP " \ + "and port (ie. 120.0.0.1 7000)\n" +#define CLUSTER_MANAGER_MODE() (config.cluster_manager_command.name != NULL) +#define CLUSTER_MANAGER_MASTERS_COUNT(nodes, replicas) (nodes/(replicas + 1)) +#define CLUSTER_MANAGER_COMMAND(n,...) \ + (redisCommand(n->context, __VA_ARGS__)) + +#define CLUSTER_MANAGER_NODE_ARRAY_FREE(array) zfree(array->alloc) + +#define CLUSTER_MANAGER_PRINT_REPLY_ERROR(n, err) \ + clusterManagerLogErr("Node %s:%d replied with error:\n%s\n", \ + n->ip, n->port, err); + +#define clusterManagerLogInfo(...) \ + clusterManagerLog(CLUSTER_MANAGER_LOG_LVL_INFO,__VA_ARGS__) + +#define clusterManagerLogErr(...) \ + clusterManagerLog(CLUSTER_MANAGER_LOG_LVL_ERR,__VA_ARGS__) + +#define clusterManagerLogWarn(...) \ + clusterManagerLog(CLUSTER_MANAGER_LOG_LVL_WARN,__VA_ARGS__) + +#define clusterManagerLogOk(...) \ + clusterManagerLog(CLUSTER_MANAGER_LOG_LVL_SUCCESS,__VA_ARGS__) + +#define CLUSTER_MANAGER_FLAG_MYSELF 1 << 0 +#define CLUSTER_MANAGER_FLAG_SLAVE 1 << 1 +#define CLUSTER_MANAGER_FLAG_FRIEND 1 << 2 +#define CLUSTER_MANAGER_FLAG_NOADDR 1 << 3 +#define CLUSTER_MANAGER_FLAG_DISCONNECT 1 << 4 +#define CLUSTER_MANAGER_FLAG_FAIL 1 << 5 + +#define CLUSTER_MANAGER_CMD_FLAG_FIX 1 << 0 +#define CLUSTER_MANAGER_CMD_FLAG_SLAVE 1 << 1 +#define CLUSTER_MANAGER_CMD_FLAG_YES 1 << 2 +#define CLUSTER_MANAGER_CMD_FLAG_AUTOWEIGHTS 1 << 3 +#define CLUSTER_MANAGER_CMD_FLAG_EMPTYMASTER 1 << 4 +#define CLUSTER_MANAGER_CMD_FLAG_SIMULATE 1 << 5 +#define CLUSTER_MANAGER_CMD_FLAG_REPLACE 1 << 6 +#define CLUSTER_MANAGER_CMD_FLAG_COPY 1 << 7 +#define CLUSTER_MANAGER_CMD_FLAG_COLOR 1 << 8 +#define CLUSTER_MANAGER_CMD_FLAG_CHECK_OWNERS 1 << 9 + +#define CLUSTER_MANAGER_OPT_GETFRIENDS 1 << 0 +#define CLUSTER_MANAGER_OPT_COLD 1 << 1 +#define CLUSTER_MANAGER_OPT_UPDATE 1 << 2 +#define CLUSTER_MANAGER_OPT_QUIET 1 << 6 +#define CLUSTER_MANAGER_OPT_VERBOSE 1 << 7 + +#define CLUSTER_MANAGER_LOG_LVL_INFO 1 +#define CLUSTER_MANAGER_LOG_LVL_WARN 2 +#define CLUSTER_MANAGER_LOG_LVL_ERR 3 +#define CLUSTER_MANAGER_LOG_LVL_SUCCESS 4 + +#define CLUSTER_JOIN_CHECK_AFTER 20 + +#define LOG_COLOR_BOLD "29;1m" +#define LOG_COLOR_RED "31;1m" +#define LOG_COLOR_GREEN "32;1m" +#define LOG_COLOR_YELLOW "33;1m" +#define LOG_COLOR_RESET "0m" + +/* cliConnect() flags. */ +#define CC_FORCE (1<<0) /* Re-connect if already connected. */ +#define CC_QUIET (1<<1) /* Don't log connecting errors. */ + +struct clusterManagerLink; +typedef struct clusterManagerLink clusterManagerLink; + +/* Dict Helpers */ + +uint64_t dictSdsHash(const void *key); +int dictSdsKeyCompare(void *privdata, const void *key1, + const void *key2); +void dictSdsDestructor(void *privdata, void *val); +void dictListDestructor(void *privdata, void *val); + +/* Cluster Manager Command Info */ +typedef struct clusterManagerCommand { + char *name; + int argc; + char **argv; + int flags; + int replicas; + char *from; + char *to; + char **weight; + int weight_argc; + char *master_id; + int slots; + int timeout; + int pipeline; + float threshold; + char *backup_dir; +} clusterManagerCommand; + +void createClusterManagerCommand(char *cmdname, int argc, char **argv); + +extern redisContext *context; +extern struct config { + char *hostip; + int hostport; + char *hostsocket; + long repeat; + long interval; + int dbnum; + int interactive; + int shutdown; + int monitor_mode; + int pubsub_mode; + int latency_mode; + int latency_dist_mode; + int latency_history; + int lru_test_mode; + long long lru_test_sample_size; + int cluster_mode; + int cluster_reissue_command; + int slave_mode; + int pipe_mode; + int pipe_timeout; + int getrdb_mode; + int stat_mode; + int scan_mode; + int intrinsic_latency_mode; + int intrinsic_latency_duration; + char *pattern; + char *rdb_filename; + int bigkeys; + int memkeys; + unsigned memkeys_samples; + int hotkeys; + int stdinarg; /* get last arg from stdin. (-x option) */ + char *auth; + int output; /* output mode, see OUTPUT_* defines */ + sds mb_delim; + char prompt[128]; + char *eval; + int eval_ldb; + int eval_ldb_sync; /* Ask for synchronous mode of the Lua debugger. */ + int eval_ldb_end; /* Lua debugging session ended. */ + int enable_ldb_on_eval; /* Handle manual SCRIPT DEBUG + EVAL commands. */ + int last_cmd_type; + int verbose; + clusterManagerCommand cluster_manager_command; + int no_auth_warning; +} config; + +/* The Cluster Manager global structure */ +extern struct clusterManager { + list *nodes; /* List of nodes in the configuration. */ + list *errors; +} cluster_manager; + +typedef struct clusterManagerNode { + redisContext *context; + sds name; + char *ip; + int port; + uint64_t current_epoch; + time_t ping_sent; + time_t ping_recv; + int flags; + list *flags_str; /* Flags string representations */ + sds replicate; /* Master ID if node is a slave */ + int dirty; /* Node has changes that can be flushed */ + uint8_t slots[CLUSTER_MANAGER_SLOTS]; + int slots_count; + int replicas_count; + list *friends; + sds *migrating; /* An array of sds where even strings are slots and odd + * strings are the destination node IDs. */ + sds *importing; /* An array of sds where even strings are slots and odd + * strings are the source node IDs. */ + int migrating_count; /* Length of the migrating array (migrating slots*2) */ + int importing_count; /* Length of the importing array (importing slots*2) */ + float weight; /* Weight used by rebalance */ + int balance; /* Used by rebalance */ +} clusterManagerNode; + +/* Data structure used to represent a sequence of cluster nodes. */ +typedef struct clusterManagerNodeArray { + clusterManagerNode **nodes; /* Actual nodes array */ + clusterManagerNode **alloc; /* Pointer to the allocated memory */ + int len; /* Actual length of the array */ + int count; /* Non-NULL nodes count */ +} clusterManagerNodeArray; + +/* Used for the reshard table. */ +typedef struct clusterManagerReshardTableItem { + clusterManagerNode *source; + int slot; +} clusterManagerReshardTableItem; + +typedef struct typeinfo { + char *name; + char *sizecmd; + char *sizeunit; + unsigned long long biggest; + unsigned long long count; + unsigned long long totalsize; + sds biggest_key; +} typeinfo; + +extern typeinfo type_string; +extern typeinfo type_list; +extern typeinfo type_set; +extern typeinfo type_hash; +extern typeinfo type_zset; +extern typeinfo type_stream; +extern typeinfo type_other; + +void findBigKeys(int memkeys, unsigned memkeys_samples); +int clusterManagerGetAntiAffinityScore(clusterManagerNodeArray *ipnodes, + int ip_count, clusterManagerNode ***offending, int *offending_len); +int clusterManagerFixMultipleSlotOwners(int slot, list *owners); +void getKeySizes(redisReply *keys, struct typeinfo **types, + unsigned long long *sizes, int memkeys, + unsigned memkeys_samples); +int clusterManagerFixOpenSlot(int slot); +void clusterManagerPrintSlotsList(list *slots); +int clusterManagerGetCoveredSlots(char *all_slots); +void clusterManagerOnError(sds err); +int clusterManagerIsConfigConsistent(void); +void freeClusterManagerNode(clusterManagerNode *node); +void clusterManagerLog(int level, const char* fmt, ...); +int parseClusterNodeAddress(char *addr, char **ip_ptr, int *port_ptr, + int *bus_port_ptr); +int clusterManagerCheckRedisReply(clusterManagerNode *n, + redisReply *r, char **err); +int confirmWithYes(const char *msg); +int clusterManagerSetSlotOwner(clusterManagerNode *owner, + int slot, + int do_clear); +clusterManagerNode * clusterManagerGetNodeWithMostKeysInSlot(list *nodes, + int slot, + char **err); +int clusterManagerSetSlot(clusterManagerNode *node1, + clusterManagerNode *node2, + int slot, const char *status, char **err); +int clusterManagerMoveSlot(clusterManagerNode *source, + clusterManagerNode *target, + int slot, int opts, char**err); +int clusterManagerClearSlotStatus(clusterManagerNode *node, int slot); +void clusterManagerShowNodes(void); +signed int clusterManagerCountKeysInSlot(clusterManagerNode *node, + int slot); +void type_free(void* priv_data, void* val); +int getDbSize(void); +redisReply *sendScan(unsigned long long *it); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/replication.cpp b/src/replication.cpp index 5d63e5a65..c062c312c 100644 --- a/src/replication.cpp +++ b/src/replication.cpp @@ -186,9 +186,9 @@ void freeReplicationBacklog(void) { * This function also increments the global replication offset stored at * server.master_repl_offset, because there is no case where we want to feed * the backlog without incrementing the offset. */ -void feedReplicationBacklog(void *ptr, size_t len) { +void feedReplicationBacklog(const void *ptr, size_t len) { serverAssert(GlobalLocksAcquired()); - unsigned char *p = (unsigned char*)ptr; + const unsigned char *p = (const unsigned char*)ptr; server.master_repl_offset += len; diff --git a/src/rio.c b/src/rio.cpp similarity index 98% rename from src/rio.c rename to src/rio.cpp index 8dcb77721..3c0c7672a 100644 --- a/src/rio.c +++ b/src/rio.cpp @@ -266,8 +266,8 @@ void rioInitWithFdset(rio *r, int *fds, int numfds) { int j; *r = rioFdsetIO; - r->io.fdset.fds = zmalloc(sizeof(int)*numfds, MALLOC_LOCAL); - r->io.fdset.state = zmalloc(sizeof(int)*numfds, MALLOC_LOCAL); + r->io.fdset.fds = (int*)zmalloc(sizeof(int)*numfds, MALLOC_LOCAL); + r->io.fdset.state = (int*)zmalloc(sizeof(int)*numfds, MALLOC_LOCAL); memcpy(r->io.fdset.fds,fds,sizeof(int)*numfds); for (j = 0; j < numfds; j++) r->io.fdset.state[j] = 0; r->io.fdset.numfds = numfds; @@ -287,7 +287,7 @@ void rioFreeFdset(rio *r) { /* This function can be installed both in memory and file streams when checksum * computation is needed. */ void rioGenericUpdateChecksum(rio *r, const void *buf, size_t len) { - r->cksum = crc64(r->cksum,buf,len); + r->cksum = crc64(r->cksum,(const unsigned char*)buf,len); } /* Set the file-based rio object to auto-fsync every 'bytes' file written. diff --git a/src/rio.h b/src/rio.h index f118556e1..172b7f9b2 100644 --- a/src/rio.h +++ b/src/rio.h @@ -36,6 +36,10 @@ #include #include "sds.h" +#ifdef __cplusplus +extern "C" { +#endif + struct _rio { /* Backend functions. * Since this functions do not tolerate short writes or reads the return @@ -141,4 +145,8 @@ int rioWriteBulkObject(rio *r, struct redisObject *obj); void rioGenericUpdateChecksum(rio *r, const void *buf, size_t len); void rioSetAutoSync(rio *r, off_t bytes); +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/sds.c b/src/sds.c index 9c0da50cb..b63d90920 100644 --- a/src/sds.c +++ b/src/sds.c @@ -1089,7 +1089,7 @@ sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen) { /* Join an array of C strings using the specified separator (also a C string). * Returns the result as an sds string. */ -sds sdsjoin(char **argv, int argc, char *sep) { +sds sdsjoin(char **argv, int argc, const char *sep) { sds join = sdsempty(); int j; diff --git a/src/sds.h b/src/sds.h index 4ae1e4dfd..7b8b5b803 100644 --- a/src/sds.h +++ b/src/sds.h @@ -60,6 +60,10 @@ struct __attribute__ ((__packed__)) sdshdr8 { unsigned char flags; /* 3 lsb of type, 5 unused bits */ #ifndef __cplusplus char buf[]; +#else + char *buf() { + return reinterpret_cast(this+1); + } #endif }; struct __attribute__ ((__packed__)) sdshdr16 { @@ -270,7 +274,7 @@ sds sdsfromlonglong(long long value); sds sdscatrepr(sds s, const char *p, size_t len); sds *sdssplitargs(const char *line, int *argc); sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen); -sds sdsjoin(char **argv, int argc, char *sep); +sds sdsjoin(char **argv, int argc, const char *sep); sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen); /* Low level functions exposed to the user API */ diff --git a/src/sentinel.c b/src/sentinel.cpp similarity index 95% rename from src/sentinel.c rename to src/sentinel.cpp index abaf7f3a9..2d0c2a481 100644 --- a/src/sentinel.c +++ b/src/sentinel.cpp @@ -375,7 +375,7 @@ sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master); void sentinelScheduleScriptExecution(char *path, ...); void sentinelStartFailover(sentinelRedisInstance *master); void sentinelDiscardReplyCallback(redisAsyncContext *c, void *reply, void *privdata); -int sentinelSendSlaveOf(sentinelRedisInstance *ri, char *host, int port); +int sentinelSendSlaveOf(sentinelRedisInstance *ri, const char *host, int port); char *sentinelVoteLeader(sentinelRedisInstance *master, uint64_t req_epoch, char *req_runid, uint64_t *leader_epoch); void sentinelFlushConfig(void); void sentinelGenerateInitialMonitorEvents(void); @@ -394,7 +394,7 @@ void releaseSentinelRedisInstance(sentinelRedisInstance *ri); void dictInstancesValDestructor (void *privdata, void *obj) { UNUSED(privdata); - releaseSentinelRedisInstance(obj); + releaseSentinelRedisInstance((sentinelRedisInstance*)obj); } /* Instance name (sds) -> instance (sentinelRedisInstance pointer) @@ -554,7 +554,7 @@ sentinelAddr *createSentinelAddr(char *hostname, int port) { errno = ENOENT; return NULL; } - sa = zmalloc(sizeof(*sa), MALLOC_LOCAL); + sa = (sentinelAddr*)zmalloc(sizeof(*sa), MALLOC_LOCAL); sa->ip = sdsnew(ip); sa->port = port; return sa; @@ -564,7 +564,7 @@ sentinelAddr *createSentinelAddr(char *hostname, int port) { sentinelAddr *dupSentinelAddr(sentinelAddr *src) { sentinelAddr *sa; - sa = zmalloc(sizeof(*sa), MALLOC_LOCAL); + sa = (sentinelAddr*)zmalloc(sizeof(*sa), MALLOC_LOCAL); sa->ip = sdsnew(src->ip); sa->port = src->port; return sa; @@ -607,7 +607,7 @@ int sentinelAddrIsEqual(sentinelAddr *a, sentinelAddr *b) { * * Any other specifier after "%@" is processed by printf itself. */ -void sentinelEvent(int level, char *type, sentinelRedisInstance *ri, +void sentinelEvent(int level, const char *type, sentinelRedisInstance *ri, const char *fmt, ...) { va_list ap; char msg[LOG_MAX_LEN]; @@ -674,7 +674,7 @@ void sentinelGenerateInitialMonitorEvents(void) { di = dictGetIterator(sentinel.masters); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); sentinelEvent(LL_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum); } dictReleaseIterator(di); @@ -708,10 +708,10 @@ void sentinelScheduleScriptExecution(char *path, ...) { va_end(ap); argv[0] = sdsnew(path); - sj = zmalloc(sizeof(*sj), MALLOC_LOCAL); + sj = (sentinelScriptJob*)zmalloc(sizeof(*sj), MALLOC_LOCAL); sj->flags = SENTINEL_SCRIPT_NONE; sj->retry_num = 0; - sj->argv = zmalloc(sizeof(char*)*(argc+1), MALLOC_LOCAL); + sj->argv = (char**)zmalloc(sizeof(char*)*(argc+1), MALLOC_LOCAL); sj->start_time = 0; sj->pid = 0; memcpy(sj->argv,argv,sizeof(char*)*(argc+1)); @@ -725,7 +725,7 @@ void sentinelScheduleScriptExecution(char *path, ...) { listRewind(sentinel.scripts_queue,&li); while ((ln = listNext(&li)) != NULL) { - sj = ln->value; + sj = (sentinelScriptJob*)ln->value; if (sj->flags & SENTINEL_SCRIPT_RUNNING) continue; /* The first node is the oldest as we add on tail. */ @@ -746,7 +746,7 @@ listNode *sentinelGetScriptListNodeByPid(pid_t pid) { listRewind(sentinel.scripts_queue,&li); while ((ln = listNext(&li)) != NULL) { - sentinelScriptJob *sj = ln->value; + sentinelScriptJob *sj = (sentinelScriptJob*)ln->value; if ((sj->flags & SENTINEL_SCRIPT_RUNNING) && sj->pid == pid) return ln; @@ -767,7 +767,7 @@ void sentinelRunPendingScripts(void) { while (sentinel.running_scripts < SENTINEL_SCRIPT_MAX_RUNNING && (ln = listNext(&li)) != NULL) { - sentinelScriptJob *sj = ln->value; + sentinelScriptJob *sj = (sentinelScriptJob*)ln->value; pid_t pid; /* Skip if already running. */ @@ -839,7 +839,7 @@ void sentinelCollectTerminatedScripts(void) { serverLog(LL_WARNING,"wait3() returned a pid (%ld) we can't find in our scripts execution queue!", (long)pid); continue; } - sj = ln->value; + sj = (sentinelScriptJob*)ln->value; /* If the script was terminated by a signal or returns an * exit code of "1" (that means: please retry), we reschedule it @@ -874,7 +874,7 @@ void sentinelKillTimedoutScripts(void) { listRewind(sentinel.scripts_queue,&li); while ((ln = listNext(&li)) != NULL) { - sentinelScriptJob *sj = ln->value; + sentinelScriptJob *sj = (sentinelScriptJob*)ln->value; if (sj->flags & SENTINEL_SCRIPT_RUNNING && (now - sj->start_time) > SENTINEL_SCRIPT_MAX_RUNTIME) @@ -894,7 +894,7 @@ void sentinelPendingScriptsCommand(client *c) { addReplyArrayLen(c,listLength(sentinel.scripts_queue)); listRewind(sentinel.scripts_queue,&li); while ((ln = listNext(&li)) != NULL) { - sentinelScriptJob *sj = ln->value; + sentinelScriptJob *sj = (sentinelScriptJob*)ln->value; int j = 0; addReplyMapLen(c,5); @@ -939,7 +939,7 @@ void sentinelPendingScriptsCommand(client *c) { * * from/to fields are respectively master -> promoted slave addresses for * "start" and "end". */ -void sentinelCallClientReconfScript(sentinelRedisInstance *master, int role, char *state, sentinelAddr *from, sentinelAddr *to) { +void sentinelCallClientReconfScript(sentinelRedisInstance *master, int role, const char *state, sentinelAddr *from, sentinelAddr *to) { char fromport[32], toport[32]; if (master->client_reconfig_script == NULL) return; @@ -955,7 +955,7 @@ void sentinelCallClientReconfScript(sentinelRedisInstance *master, int role, cha /* Create a not yet connected link object. */ instanceLink *createInstanceLink(void) { - instanceLink *link = zmalloc(sizeof(*link), MALLOC_LOCAL); + instanceLink *link = (instanceLink*)zmalloc(sizeof(*link), MALLOC_LOCAL); link->refcount = 1; link->disconnected = 1; @@ -1053,7 +1053,7 @@ int sentinelTryConnectionSharing(sentinelRedisInstance *ri) { di = dictGetIterator(sentinel.masters); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *master = dictGetVal(de), *match; + sentinelRedisInstance *master = (sentinelRedisInstance*)dictGetVal(de), *match; /* We want to share with the same physical Sentinel referenced * in other masters, so skip our master. */ if (master == ri->master) continue; @@ -1087,7 +1087,7 @@ int sentinelUpdateSentinelAddressInAllMasters(sentinelRedisInstance *ri) { di = dictGetIterator(sentinel.masters); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *master = dictGetVal(de), *match; + sentinelRedisInstance *master = (sentinelRedisInstance*)dictGetVal(de), *match; match = getSentinelRedisInstanceByAddrAndRunID(master->sentinels, NULL,0,ri->runid); /* If there is no match, this master does not know about this @@ -1122,7 +1122,7 @@ int sentinelUpdateSentinelAddressInAllMasters(sentinelRedisInstance *ri) { * Note: we don't free the hiredis context as hiredis will do it for us * for async connections. */ void instanceLinkConnectionError(const redisAsyncContext *c) { - instanceLink *link = c->data; + instanceLink *link = (instanceLink*)c->data; int pubsub; if (!link) return; @@ -1205,7 +1205,7 @@ sentinelRedisInstance *createSentinelRedisInstance(char *name, int flags, char * } /* Create the instance object. */ - ri = zmalloc(sizeof(*ri), MALLOC_LOCAL); + ri = (sentinelRedisInstance*)zmalloc(sizeof(*ri), MALLOC_LOCAL); /* Note that all the instances are started in the disconnected state, * the event loop will take care of connecting them. */ ri->flags = flags; @@ -1303,7 +1303,7 @@ sentinelRedisInstance *sentinelRedisInstanceLookupSlave( serverAssert(ri->flags & SRI_MASTER); anetFormatAddr(buf,sizeof(buf),ip,port); key = sdsnew(buf); - slave = dictFetchValue(ri->slaves,key); + slave = (sentinelRedisInstance*)dictFetchValue(ri->slaves,key); sdsfree(key); return slave; } @@ -1336,7 +1336,7 @@ int removeMatchingSentinelFromMaster(sentinelRedisInstance *master, char *runid) di = dictGetSafeIterator(master->sentinels); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); if (ri->runid && strcmp(ri->runid,runid) == 0) { dictDelete(master->sentinels,ri->name); @@ -1361,7 +1361,7 @@ sentinelRedisInstance *getSentinelRedisInstanceByAddrAndRunID(dict *instances, c serverAssert(ip || runid); /* User must pass at least one search param. */ di = dictGetIterator(instances); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); if (runid && !ri->runid) continue; if ((runid == NULL || strcmp(ri->runid, runid) == 0) && @@ -1381,7 +1381,7 @@ sentinelRedisInstance *sentinelGetMasterByName(char *name) { sentinelRedisInstance *ri; sds sdsname = sdsnew(name); - ri = dictFetchValue(sentinel.masters,sdsname); + ri = (sentinelRedisInstance*)dictFetchValue(sentinel.masters,sdsname); sdsfree(sdsname); return ri; } @@ -1393,7 +1393,7 @@ void sentinelAddFlagsToDictOfRedisInstances(dict *instances, int flags) { di = dictGetIterator(instances); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); ri->flags |= flags; } dictReleaseIterator(di); @@ -1407,7 +1407,7 @@ void sentinelDelFlagsToDictOfRedisInstances(dict *instances, int flags) { di = dictGetIterator(instances); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); ri->flags &= ~flags; } dictReleaseIterator(di); @@ -1467,7 +1467,7 @@ int sentinelResetMastersByPattern(char *pattern, int flags) { di = dictGetIterator(sentinel.masters); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); if (ri->name) { if (stringmatch(pattern,ri->name,0)) { @@ -1501,10 +1501,10 @@ int sentinelResetMasterAndChangeAddress(sentinelRedisInstance *master, char *ip, * Don't include the one having the address we are switching to. */ di = dictGetIterator(master->slaves); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *slave = dictGetVal(de); + sentinelRedisInstance *slave = (sentinelRedisInstance*)dictGetVal(de); if (sentinelAddrIsEqual(slave->addr,newaddr)) continue; - slaves = zrealloc(slaves,sizeof(sentinelAddr*)*(numslaves+1), MALLOC_LOCAL); + slaves = (sentinelAddr**)zrealloc(slaves,sizeof(sentinelAddr*)*(numslaves+1), MALLOC_LOCAL); slaves[numslaves++] = createSentinelAddr(slave->addr->ip, slave->addr->port); } @@ -1514,7 +1514,7 @@ int sentinelResetMasterAndChangeAddress(sentinelRedisInstance *master, char *ip, * as a slave as well, so that we'll be able to sense / reconfigure * the old master. */ if (!sentinelAddrIsEqual(newaddr,master->addr)) { - slaves = zrealloc(slaves,sizeof(sentinelAddr*)*(numslaves+1), MALLOC_LOCAL); + slaves = (sentinelAddr**)zrealloc(slaves,sizeof(sentinelAddr*)*(numslaves+1), MALLOC_LOCAL); slaves[numslaves++] = createSentinelAddr(master->addr->ip, master->addr->port); } @@ -1584,14 +1584,14 @@ void sentinelPropagateDownAfterPeriod(sentinelRedisInstance *master) { for (j = 0; d[j]; j++) { di = dictGetIterator(d[j]); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); ri->down_after_period = master->down_after_period; } dictReleaseIterator(di); } } -char *sentinelGetInstanceTypeString(sentinelRedisInstance *ri) { +const char *sentinelGetInstanceTypeString(sentinelRedisInstance *ri) { if (ri->flags & SRI_MASTER) return "master"; else if (ri->flags & SRI_SLAVE) return "slave"; else if (ri->flags & SRI_SENTINEL) return "sentinel"; @@ -1605,16 +1605,16 @@ char *sentinelGetInstanceTypeString(sentinelRedisInstance *ri) { * we check the one of the master), and map the command that we should send * to the set of renamed commads. However, if the command was not renamed, * we just return "command" itself. */ -char *sentinelInstanceMapCommand(sentinelRedisInstance *ri, char *command) { +const char *sentinelInstanceMapCommand(sentinelRedisInstance *ri, const char *command) { sds sc = sdsnew(command); if (ri->master) ri = ri->master; - char *retval = dictFetchValue(ri->renamed_commands, sc); + char *retval = (char*)dictFetchValue(ri->renamed_commands, sc); sdsfree(sc); return retval ? retval : command; } /* ============================ Config handling ============================= */ -char *sentinelHandleConfiguration(char **argv, int argc) { +const char *sentinelHandleConfiguration(char **argv, int argc) { sentinelRedisInstance *ri; if (!strcasecmp(argv[0],"monitor") && argc == 5) { @@ -1781,7 +1781,7 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { sentinelAddr *master_addr; /* sentinel monitor */ - master = dictGetVal(de); + master = (sentinelRedisInstance*)dictGetVal(de); master_addr = sentinelGetCurrentMasterAddress(master); line = sdscatprintf(sdsempty(),"sentinel monitor %s %s %d %d", master->name, master_addr->ip, master_addr->port, @@ -1853,7 +1853,7 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { while((de = dictNext(di2)) != NULL) { sentinelAddr *slave_addr; - ri = dictGetVal(de); + ri = (sentinelRedisInstance*)dictGetVal(de); slave_addr = ri->addr; /* If master_addr (obtained using sentinelGetCurrentMasterAddress() @@ -1873,7 +1873,7 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { /* sentinel known-sentinel */ di2 = dictGetIterator(master->sentinels); while((de = dictNext(di2)) != NULL) { - ri = dictGetVal(de); + ri = (sentinelRedisInstance*)dictGetVal(de); if (ri->runid == NULL) continue; line = sdscatprintf(sdsempty(), "sentinel known-sentinel %s %s %d %s", @@ -1885,8 +1885,8 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { /* sentinel rename-command */ di2 = dictGetIterator(master->renamed_commands); while((de = dictNext(di2)) != NULL) { - sds oldname = dictGetKey(de); - sds newname = dictGetVal(de); + sds oldname = (sds)dictGetKey(de); + sds newname = (sds)dictGetVal(de); line = sdscatprintf(sdsempty(), "sentinel rename-command %s %s %s", master->name, oldname, newname); @@ -1982,7 +1982,7 @@ void sentinelSendAuthIfNeeded(sentinelRedisInstance *ri, redisAsyncContext *c) { * * This makes it possible to list all the sentinel instances connected * to a Redis servewr with CLIENT LIST, grepping for a specific name format. */ -void sentinelSetClientName(sentinelRedisInstance *ri, redisAsyncContext *c, char *type) { +void sentinelSetClientName(sentinelRedisInstance *ri, redisAsyncContext *c, const char *type) { char name[64]; snprintf(name,sizeof(name),"sentinel-%.8s-%s",sentinel.myid,type); @@ -2337,13 +2337,13 @@ void sentinelRefreshInstanceInfo(sentinelRedisInstance *ri, const char *info) { } void sentinelInfoReplyCallback(redisAsyncContext *c, void *reply, void *privdata) { - sentinelRedisInstance *ri = privdata; - instanceLink *link = c->data; + sentinelRedisInstance *ri = (sentinelRedisInstance*)privdata; + instanceLink *link = (instanceLink*)c->data; redisReply *r; if (!reply || !link) return; link->pending_commands--; - r = reply; + r = (redisReply*)reply; if (r->type == REDIS_REPLY_STRING) sentinelRefreshInstanceInfo(ri,r->str); @@ -2352,7 +2352,7 @@ void sentinelInfoReplyCallback(redisAsyncContext *c, void *reply, void *privdata /* Just discard the reply. We use this when we are not monitoring the return * value of the command but its effects directly. */ void sentinelDiscardReplyCallback(redisAsyncContext *c, void *reply, void *privdata) { - instanceLink *link = c->data; + instanceLink *link = (instanceLink*)c->data; UNUSED(reply); UNUSED(privdata); @@ -2360,13 +2360,13 @@ void sentinelDiscardReplyCallback(redisAsyncContext *c, void *reply, void *privd } void sentinelPingReplyCallback(redisAsyncContext *c, void *reply, void *privdata) { - sentinelRedisInstance *ri = privdata; - instanceLink *link = c->data; + sentinelRedisInstance *ri = (sentinelRedisInstance*)privdata; + instanceLink *link = (instanceLink*)c->data; redisReply *r; if (!reply || !link) return; link->pending_commands--; - r = reply; + r = (redisReply*)reply; if (r->type == REDIS_REPLY_STATUS || r->type == REDIS_REPLY_ERROR) { @@ -2402,13 +2402,13 @@ void sentinelPingReplyCallback(redisAsyncContext *c, void *reply, void *privdata /* This is called when we get the reply about the PUBLISH command we send * to the master to advertise this sentinel. */ void sentinelPublishReplyCallback(redisAsyncContext *c, void *reply, void *privdata) { - sentinelRedisInstance *ri = privdata; - instanceLink *link = c->data; + sentinelRedisInstance *ri = (sentinelRedisInstance*)privdata; + instanceLink *link = (instanceLink*)c->data; redisReply *r; if (!reply || !link) return; link->pending_commands--; - r = reply; + r = (redisReply*)reply; /* Only update pub_time if we actually published our message. Otherwise * we'll retry again in 100 milliseconds. */ @@ -2421,7 +2421,7 @@ void sentinelPublishReplyCallback(redisAsyncContext *c, void *reply, void *privd * * If the master name specified in the message is not known, the message is * discarded. */ -void sentinelProcessHelloMessage(char *hello, int hello_len) { +void sentinelProcessHelloMessage(const char *hello, int hello_len) { /* Format is composed of 8 tokens: * 0=ip,1=port,2=runid,3=current_epoch,4=master_name, * 5=master_ip,6=master_port,7=master_config_epoch. */ @@ -2526,12 +2526,12 @@ cleanup: /* This is our Pub/Sub callback for the Hello channel. It's useful in order * to discover other sentinels attached at the same master. */ void sentinelReceiveHelloMessages(redisAsyncContext *c, void *reply, void *privdata) { - sentinelRedisInstance *ri = privdata; + sentinelRedisInstance *ri = (sentinelRedisInstance*)privdata; redisReply *r; UNUSED(c); if (!reply || !ri) return; - r = reply; + r = (redisReply*)reply; /* Update the last activity in the pubsub channel. Note that since we * receive our messages as well this timestamp can be used to detect @@ -2613,7 +2613,7 @@ void sentinelForceHelloUpdateDictOfRedisInstances(dict *instances) { di = dictGetSafeIterator(instances); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); if (ri->last_pub_time >= (SENTINEL_PUBLISH_PERIOD+1)) ri->last_pub_time -= (SENTINEL_PUBLISH_PERIOD+1); } @@ -2940,7 +2940,7 @@ void addReplyDictOfRedisInstances(client *c, dict *instances) { di = dictGetIterator(instances); addReplyArrayLen(c,dictSize(instances)); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); addReplySentinelRedisInstance(c,ri); } @@ -2955,7 +2955,7 @@ sentinelRedisInstance *sentinelGetMasterByNameOrReplyError(client *c, { sentinelRedisInstance *ri; - ri = dictFetchValue(sentinel.masters,ptrFromObj(name)); + ri = (sentinelRedisInstance*)dictFetchValue(sentinel.masters,ptrFromObj(name)); if (!ri) { addReplyError(c,"No such master with that name"); return NULL; @@ -2975,7 +2975,7 @@ int sentinelIsQuorumReachable(sentinelRedisInstance *master, int *usableptr) { di = dictGetIterator(master->sentinels); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); if (ri->flags & (SRI_S_DOWN|SRI_O_DOWN)) continue; usable++; @@ -2989,11 +2989,11 @@ int sentinelIsQuorumReachable(sentinelRedisInstance *master, int *usableptr) { } void sentinelCommand(client *c) { - if (!strcasecmp(ptrFromObj(c->argv[1]),"masters")) { + if (!strcasecmp(szFromObj(c->argv[1]),"masters")) { /* SENTINEL MASTERS */ if (c->argc != 2) goto numargserr; addReplyDictOfRedisInstances(c,sentinel.masters); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"master")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"master")) { /* SENTINEL MASTER */ sentinelRedisInstance *ri; @@ -3001,8 +3001,8 @@ void sentinelCommand(client *c) { if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) == NULL) return; addReplySentinelRedisInstance(c,ri); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"slaves") || - !strcasecmp(ptrFromObj(c->argv[1]),"replicas")) + } else if (!strcasecmp(szFromObj(c->argv[1]),"slaves") || + !strcasecmp(szFromObj(c->argv[1]),"replicas")) { /* SENTINEL REPLICAS */ sentinelRedisInstance *ri; @@ -3011,7 +3011,7 @@ void sentinelCommand(client *c) { if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) == NULL) return; addReplyDictOfRedisInstances(c,ri->slaves); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"sentinels")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"sentinels")) { /* SENTINEL SENTINELS */ sentinelRedisInstance *ri; @@ -3019,7 +3019,7 @@ void sentinelCommand(client *c) { if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) == NULL) return; addReplyDictOfRedisInstances(c,ri->sentinels); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"is-master-down-by-addr")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"is-master-down-by-addr")) { /* SENTINEL IS-MASTER-DOWN-BY-ADDR * * Arguments: @@ -3050,7 +3050,7 @@ void sentinelCommand(client *c) { != C_OK) return; ri = getSentinelRedisInstanceByAddrAndRunID(sentinel.masters, - ptrFromObj(c->argv[2]),port,NULL); + szFromObj(c->argv[2]),port,NULL); /* It exists? Is actually a master? Is subjectively down? It's down. * Note: if we are in tilt mode we always reply with "0". */ @@ -3060,9 +3060,9 @@ void sentinelCommand(client *c) { /* Vote for the master (or fetch the previous vote) if the request * includes a runid, otherwise the sender is not seeking for a vote. */ - if (ri && ri->flags & SRI_MASTER && strcasecmp(ptrFromObj(c->argv[5]),"*")) { + if (ri && ri->flags & SRI_MASTER && strcasecmp(szFromObj(c->argv[5]),"*")) { leader = sentinelVoteLeader(ri,(uint64_t)req_epoch, - ptrFromObj(c->argv[5]), + szFromObj(c->argv[5]), &leader_epoch); } @@ -3073,16 +3073,16 @@ void sentinelCommand(client *c) { addReplyBulkCString(c, leader ? leader : "*"); addReplyLongLong(c, (long long)leader_epoch); if (leader) sdsfree(leader); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"reset")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"reset")) { /* SENTINEL RESET */ if (c->argc != 3) goto numargserr; - addReplyLongLong(c,sentinelResetMastersByPattern(ptrFromObj(c->argv[2]),SENTINEL_GENERATE_EVENT)); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"get-master-addr-by-name")) { + addReplyLongLong(c,sentinelResetMastersByPattern(szFromObj(c->argv[2]),SENTINEL_GENERATE_EVENT)); + } else if (!strcasecmp(szFromObj(c->argv[1]),"get-master-addr-by-name")) { /* SENTINEL GET-MASTER-ADDR-BY-NAME */ sentinelRedisInstance *ri; if (c->argc != 3) goto numargserr; - ri = sentinelGetMasterByName(ptrFromObj(c->argv[2])); + ri = sentinelGetMasterByName(szFromObj(c->argv[2])); if (ri == NULL) { addReplyNullArray(c); } else { @@ -3092,7 +3092,7 @@ void sentinelCommand(client *c) { addReplyBulkCString(c,addr->ip); addReplyBulkLongLong(c,addr->port); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"failover")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"failover")) { /* SENTINEL FAILOVER */ sentinelRedisInstance *ri; @@ -3112,12 +3112,12 @@ void sentinelCommand(client *c) { sentinelStartFailover(ri); ri->flags |= SRI_FORCE_FAILOVER; addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"pending-scripts")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"pending-scripts")) { /* SENTINEL PENDING-SCRIPTS */ if (c->argc != 2) goto numargserr; sentinelPendingScriptsCommand(c); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"monitor")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"monitor")) { /* SENTINEL MONITOR */ sentinelRedisInstance *ri; long quorum, port; @@ -3137,14 +3137,14 @@ void sentinelCommand(client *c) { /* Make sure the IP field is actually a valid IP before passing it * to createSentinelRedisInstance(), otherwise we may trigger a * DNS lookup at runtime. */ - if (anetResolveIP(NULL,ptrFromObj(c->argv[3]),ip,sizeof(ip)) == ANET_ERR) { + if (anetResolveIP(NULL,szFromObj(c->argv[3]),ip,sizeof(ip)) == ANET_ERR) { addReplyError(c,"Invalid IP address specified"); return; } /* Parameters are valid. Try to create the master instance. */ - ri = createSentinelRedisInstance(ptrFromObj(c->argv[2]),SRI_MASTER, - ptrFromObj(c->argv[3]),port,quorum,NULL); + ri = createSentinelRedisInstance(szFromObj(c->argv[2]),SRI_MASTER, + szFromObj(c->argv[3]),port,quorum,NULL); if (ri == NULL) { switch(errno) { case EBUSY: @@ -3162,12 +3162,12 @@ void sentinelCommand(client *c) { sentinelEvent(LL_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum); addReply(c,shared.ok); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"flushconfig")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"flushconfig")) { if (c->argc != 2) goto numargserr; sentinelFlushConfig(); addReply(c,shared.ok); return; - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"remove")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"remove")) { /* SENTINEL REMOVE */ sentinelRedisInstance *ri; @@ -3178,7 +3178,7 @@ void sentinelCommand(client *c) { dictDelete(sentinel.masters,ptrFromObj(c->argv[2])); sentinelFlushConfig(); addReply(c,shared.ok); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"ckquorum")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"ckquorum")) { /* SENTINEL CKQUORUM */ sentinelRedisInstance *ri; int usable; @@ -3205,10 +3205,10 @@ void sentinelCommand(client *c) { e = sdscat(e,"\r\n"); addReplySds(c,e); } - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"set")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"set")) { if (c->argc < 3) goto numargserr; sentinelSetCommand(c); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"info-cache")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"info-cache")) { /* SENTINEL INFO-CACHE */ if (c->argc < 2) goto numargserr; mstime_t now = mstime(); @@ -3224,7 +3224,7 @@ void sentinelCommand(client *c) { for (int i = 2; i < c->argc; i++) { sentinelRedisInstance *ri; - ri = sentinelGetMasterByName(ptrFromObj(c->argv[i])); + ri = sentinelGetMasterByName(szFromObj(c->argv[i])); if (!ri) continue; /* ignore non-existing names */ dictAdd(masters_local, ri->name, ri); } @@ -3244,7 +3244,7 @@ void sentinelCommand(client *c) { dictEntry *de; di = dictGetIterator(masters_local); while ((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); addReplyBulkCBuffer(c,ri->name,strlen(ri->name)); addReplyArrayLen(c,dictSize(ri->slaves) + 1); /* +1 for self */ addReplyArrayLen(c,2); @@ -3258,7 +3258,7 @@ void sentinelCommand(client *c) { dictEntry *sde; sdi = dictGetIterator(ri->slaves); while ((sde = dictNext(sdi)) != NULL) { - sentinelRedisInstance *sri = dictGetVal(sde); + sentinelRedisInstance *sri = (sentinelRedisInstance*)dictGetVal(sde); addReplyArrayLen(c,2); addReplyLongLong(c, now - sri->info_refresh); if (sri->info) @@ -3270,24 +3270,24 @@ void sentinelCommand(client *c) { } dictReleaseIterator(di); if (masters_local != sentinel.masters) dictRelease(masters_local); - } else if (!strcasecmp(ptrFromObj(c->argv[1]),"simulate-failure")) { + } else if (!strcasecmp(szFromObj(c->argv[1]),"simulate-failure")) { /* SENTINEL SIMULATE-FAILURE ... */ int j; sentinel.simfailure_flags = SENTINEL_SIMFAILURE_NONE; for (j = 2; j < c->argc; j++) { - if (!strcasecmp(ptrFromObj(c->argv[j]),"crash-after-election")) { + if (!strcasecmp(szFromObj(c->argv[j]),"crash-after-election")) { sentinel.simfailure_flags |= SENTINEL_SIMFAILURE_CRASH_AFTER_ELECTION; serverLog(LL_WARNING,"Failure simulation: this Sentinel " "will crash after being successfully elected as failover " "leader"); - } else if (!strcasecmp(ptrFromObj(c->argv[j]),"crash-after-promotion")) { + } else if (!strcasecmp(szFromObj(c->argv[j]),"crash-after-promotion")) { sentinel.simfailure_flags |= SENTINEL_SIMFAILURE_CRASH_AFTER_PROMOTION; serverLog(LL_WARNING,"Failure simulation: this Sentinel " "will crash after promoting the selected replica to master"); - } else if (!strcasecmp(ptrFromObj(c->argv[j]),"help")) { + } else if (!strcasecmp(szFromObj(c->argv[j]),"help")) { addReplyArrayLen(c,2); addReplyBulkCString(c,"crash-after-election"); addReplyBulkCString(c,"crash-after-promotion"); @@ -3326,7 +3326,7 @@ void sentinelInfoCommand(client *c) { } int defsections = 0, allsections = 0; - char *section = c->argc == 2 ? ptrFromObj(c->argv[1]) : NULL; + char *section = c->argc == 2 ? szFromObj(c->argv[1]) : NULL; if (section) { allsections = !strcasecmp(section,"all"); defsections = !strcasecmp(section,"default"); @@ -3363,8 +3363,8 @@ void sentinelInfoCommand(client *c) { di = dictGetIterator(sentinel.masters); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); - char *status = "ok"; + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); + const char *status = "ok"; if (ri->flags & SRI_O_DOWN) status = "odown"; else if (ri->flags & SRI_S_DOWN) status = "sdown"; @@ -3394,7 +3394,7 @@ void sentinelRoleCommand(client *c) { di = dictGetIterator(sentinel.masters); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); addReplyBulkCString(c,ri->name); } @@ -3414,7 +3414,7 @@ void sentinelSetCommand(client *c) { /* Process option - value pairs. */ for (j = 3; j < c->argc; j++) { int moreargs = (c->argc-1) - j; - option = ptrFromObj(c->argv[j]); + option = szFromObj(c->argv[j]); long long ll; int old_j = j; /* Used to know what to log as an event. */ @@ -3448,7 +3448,7 @@ void sentinelSetCommand(client *c) { changes++; } else if (!strcasecmp(option,"notification-script") && moreargs > 0) { /* notification-script */ - char *value = ptrFromObj(c->argv[++j]); + char *value = szFromObj(c->argv[++j]); if (sentinel.deny_scripts_reconfig) { addReplyError(c, "Reconfiguration of scripts path is denied for " @@ -3468,7 +3468,7 @@ void sentinelSetCommand(client *c) { changes++; } else if (!strcasecmp(option,"client-reconfig-script") && moreargs > 0) { /* client-reconfig-script */ - char *value = ptrFromObj(c->argv[++j]); + char *value = szFromObj(c->argv[++j]); if (sentinel.deny_scripts_reconfig) { addReplyError(c, "Reconfiguration of scripts path is denied for " @@ -3489,7 +3489,7 @@ void sentinelSetCommand(client *c) { changes++; } else if (!strcasecmp(option,"auth-pass") && moreargs > 0) { /* auth-pass */ - char *value = ptrFromObj(c->argv[++j]); + char *value = szFromObj(c->argv[++j]); sdsfree(ri->auth_pass); ri->auth_pass = strlen(value) ? sdsnew(value) : NULL; changes++; @@ -3504,8 +3504,8 @@ void sentinelSetCommand(client *c) { changes++; } else if (!strcasecmp(option,"rename-command") && moreargs > 1) { /* rename-command */ - sds oldname = ptrFromObj(c->argv[++j]); - sds newname = ptrFromObj(c->argv[++j]); + sds oldname = szFromObj(c->argv[++j]); + sds newname = szFromObj(c->argv[++j]); if ((sdslen(oldname) == 0) || (sdslen(newname) == 0)) { badarg = sdslen(newname) ? j-1 : j; @@ -3565,11 +3565,11 @@ badfmt: /* Bad format errors */ * Because we have a Sentinel PUBLISH, the code to send hello messages is the same * for all the three kind of instances: masters, slaves, sentinels. */ void sentinelPublishCommand(client *c) { - if (strcmp(ptrFromObj(c->argv[1]),SENTINEL_HELLO_CHANNEL)) { + if (strcmp(szFromObj(c->argv[1]),SENTINEL_HELLO_CHANNEL)) { addReplyError(c, "Only HELLO messages are accepted by Sentinel instances."); return; } - sentinelProcessHelloMessage(ptrFromObj(c->argv[2]),sdslen(ptrFromObj(c->argv[2]))); + sentinelProcessHelloMessage(szFromObj(c->argv[2]),sdslen(szFromObj(c->argv[2]))); addReplyLongLong(c,1); } @@ -3659,7 +3659,7 @@ void sentinelCheckObjectivelyDown(sentinelRedisInstance *master) { /* Count all the other sentinels. */ di = dictGetIterator(master->sentinels); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); if (ri->flags & SRI_MASTER_DOWN) quorum++; } @@ -3686,13 +3686,13 @@ void sentinelCheckObjectivelyDown(sentinelRedisInstance *master) { /* Receive the SENTINEL is-master-down-by-addr reply, see the * sentinelAskMasterStateToOtherSentinels() function for more information. */ void sentinelReceiveIsMasterDownReply(redisAsyncContext *c, void *reply, void *privdata) { - sentinelRedisInstance *ri = privdata; - instanceLink *link = c->data; + sentinelRedisInstance *ri = (sentinelRedisInstance*)privdata; + instanceLink *link = (instanceLink*)c->data; redisReply *r; if (!reply || !link) return; link->pending_commands--; - r = reply; + r = (redisReply*)reply; /* Ignore every error or unexpected reply. * Note that if the command returns an error for any reason we'll @@ -3734,7 +3734,7 @@ void sentinelAskMasterStateToOtherSentinels(sentinelRedisInstance *master, int f di = dictGetIterator(master->sentinels); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); mstime_t elapsed = mstime() - ri->last_master_down_reply_time; char port[32]; int retval; @@ -3860,7 +3860,7 @@ char *sentinelGetLeader(sentinelRedisInstance *master, uint64_t epoch) { /* Count other sentinels votes */ di = dictGetIterator(master->sentinels); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); if (ri->leader != NULL && ri->leader_epoch == sentinel.current_epoch) sentinelLeaderIncr(counters,ri->leader); } @@ -3875,7 +3875,7 @@ char *sentinelGetLeader(sentinelRedisInstance *master, uint64_t epoch) { if (votes > max_votes) { max_votes = votes; - winner = dictGetKey(de); + winner = (char*)dictGetKey(de); } } dictReleaseIterator(di); @@ -3917,7 +3917,7 @@ char *sentinelGetLeader(sentinelRedisInstance *master, uint64_t epoch) { * The command returns C_OK if the SLAVEOF command was accepted for * (later) delivery otherwise C_ERR. The command replies are just * discarded. */ -int sentinelSendSlaveOf(sentinelRedisInstance *ri, char *host, int port) { +int sentinelSendSlaveOf(sentinelRedisInstance *ri, const char *host, int port) { char portstr[32]; int retval; @@ -4096,7 +4096,7 @@ int compareSlavesForPromotion(const void *a, const void *b) { } sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master) { - sentinelRedisInstance **instance = + sentinelRedisInstance **instance = (sentinelRedisInstance**) zmalloc(sizeof(instance[0])*dictSize(master->slaves), MALLOC_LOCAL); sentinelRedisInstance *selected = NULL; int instances = 0; @@ -4110,7 +4110,7 @@ sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master) { di = dictGetIterator(master->slaves); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *slave = dictGetVal(de); + sentinelRedisInstance *slave = (sentinelRedisInstance*)dictGetVal(de); mstime_t info_validity_time; if (slave->flags & (SRI_S_DOWN|SRI_O_DOWN)) continue; @@ -4245,7 +4245,7 @@ void sentinelFailoverDetectEnd(sentinelRedisInstance *master) { * configured. */ di = dictGetIterator(master->slaves); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *slave = dictGetVal(de); + sentinelRedisInstance *slave = (sentinelRedisInstance*)dictGetVal(de); if (slave->flags & (SRI_PROMOTED|SRI_RECONF_DONE)) continue; if (slave->flags & SRI_S_DOWN) continue; @@ -4275,7 +4275,7 @@ void sentinelFailoverDetectEnd(sentinelRedisInstance *master) { di = dictGetIterator(master->slaves); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *slave = dictGetVal(de); + sentinelRedisInstance *slave = (sentinelRedisInstance*)dictGetVal(de); int retval; if (slave->flags & (SRI_RECONF_DONE|SRI_RECONF_SENT)) continue; @@ -4303,7 +4303,7 @@ void sentinelFailoverReconfNextSlave(sentinelRedisInstance *master) { di = dictGetIterator(master->slaves); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *slave = dictGetVal(de); + sentinelRedisInstance *slave = (sentinelRedisInstance*)dictGetVal(de); if (slave->flags & (SRI_RECONF_SENT|SRI_RECONF_INPROG)) in_progress++; @@ -4314,7 +4314,7 @@ void sentinelFailoverReconfNextSlave(sentinelRedisInstance *master) { while(in_progress < master->parallel_syncs && (de = dictNext(di)) != NULL) { - sentinelRedisInstance *slave = dictGetVal(de); + sentinelRedisInstance *slave = (sentinelRedisInstance*)dictGetVal(de); int retval; /* Skip the promoted slave, and already configured slaves. */ @@ -4461,7 +4461,7 @@ void sentinelHandleDictOfRedisInstances(dict *instances) { /* There are a number of things we need to perform against every master. */ di = dictGetIterator(instances); while((de = dictNext(di)) != NULL) { - sentinelRedisInstance *ri = dictGetVal(de); + sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de); sentinelHandleRedisInstance(ri); if (ri->flags & SRI_MASTER) { diff --git a/src/server.cpp b/src/server.cpp index 795cc570a..694127989 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -997,10 +997,6 @@ struct redisCommand redisCommandTable[] = { "admin no-script ok-loading ok-stale", 0,NULL,0,0,0,0,0,0}, - {"lolwut",lolwutCommand,-1, - "read-only fast", - 0,NULL,0,0,0,0,0,0}, - {"acl",aclCommand,-2, "admin no-script ok-loading ok-stale", 0,NULL,0,0,0,0,0,0}, @@ -1139,13 +1135,13 @@ void exitFromChild(int retcode) { * keys and redis objects as values (objects can hold SDS strings, * lists, sets). */ -extern "C" void dictVanillaFree(void *privdata, void *val) +void dictVanillaFree(void *privdata, void *val) { DICT_NOTUSED(privdata); zfree(val); } -extern "C" void dictListDestructor(void *privdata, void *val) +void dictListDestructor(void *privdata, void *val) { DICT_NOTUSED(privdata); listRelease((list*)val); @@ -1165,7 +1161,7 @@ int dictSdsKeyCompare(void *privdata, const void *key1, /* A case insensitive version used for the command lookup table and other * places where case insensitive non binary-safe comparison is needed. */ -extern "C" int dictSdsKeyCaseCompare(void *privdata, const void *key1, +int dictSdsKeyCaseCompare(void *privdata, const void *key1, const void *key2) { DICT_NOTUSED(privdata); @@ -1205,7 +1201,7 @@ uint64_t dictSdsHash(const void *key) { return dictGenHashFunction((unsigned char*)key, sdslen((char*)key)); } -extern "C" uint64_t dictSdsCaseHash(const void *key) { +uint64_t dictSdsCaseHash(const void *key) { return dictGenCaseHashFunction((unsigned char*)key, sdslen((char*)key)); } @@ -2155,7 +2151,7 @@ void afterSleep(struct aeEventLoop *eventLoop) { /* =========================== Server initialization ======================== */ -extern "C" void createSharedObjects(void) { +void createSharedObjects(void) { int j; shared.crlf = createObject(OBJ_STRING,sdsnew("\r\n")); @@ -2299,7 +2295,6 @@ void initServerConfig(void) { server.unixsocketperm = CONFIG_DEFAULT_UNIX_SOCKET_PERM; server.sofd = -1; server.protected_mode = CONFIG_DEFAULT_PROTECTED_MODE; - server.gopher_enabled = CONFIG_DEFAULT_GOPHER_ENABLED; server.dbnum = CONFIG_DEFAULT_DBNUM; server.verbosity = CONFIG_DEFAULT_VERBOSITY; server.maxidletime = CONFIG_DEFAULT_CLIENT_TIMEOUT; @@ -4761,7 +4756,7 @@ void redisOutOfMemoryHandler(size_t allocation_size) { serverPanic("Redis aborting for OUT OF MEMORY"); } -void redisSetProcTitle(char *title) { +void redisSetProcTitle(const char *title) { #ifdef USE_SETPROCTITLE const char *server_mode = ""; if (server.cluster_enabled) server_mode = " [cluster]"; @@ -4968,7 +4963,7 @@ int main(int argc, char **argv) { * the program main. However the program is part of the Redis executable * so that we can easily execute an RDB check on loading errors. */ if (strstr(argv[0],"keydb-check-rdb") != NULL) - redis_check_rdb_main(argc,argv,NULL); + redis_check_rdb_main(argc,(const char**)argv,NULL); else if (strstr(argv[0],"keydb-check-aof") != NULL) redis_check_aof_main(argc,argv); diff --git a/src/server.h b/src/server.h index 7f669c1d0..069077c96 100644 --- a/src/server.h +++ b/src/server.h @@ -136,7 +136,6 @@ extern "C" { #define CONFIG_DEFAULT_UNIX_SOCKET_PERM 0 #define CONFIG_DEFAULT_TCP_KEEPALIVE 300 #define CONFIG_DEFAULT_PROTECTED_MODE 1 -#define CONFIG_DEFAULT_GOPHER_ENABLED 0 #define CONFIG_DEFAULT_LOGFILE "" #define CONFIG_DEFAULT_SYSLOG_ENABLED 0 #define CONFIG_DEFAULT_STOP_WRITES_ON_BGSAVE_ERROR 1 @@ -1171,8 +1170,6 @@ struct redisServer { dict *migrate_cached_sockets;/* MIGRATE cached sockets */ uint64_t next_client_id; /* Next client unique ID. Incremental. */ int protected_mode; /* Don't accept external connections. */ - int gopher_enabled; /* If true the server will reply to gopher - queries. Will still serve RESP2 queries. */ /* RDB / AOF loading information */ int loading; /* We are loading data from disk if true */ off_t loading_total_bytes; @@ -1604,7 +1601,7 @@ void getRandomBytes(unsigned char *p, size_t len); uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l); void exitFromChild(int retcode); size_t redisPopcount(void *s, long count); -void redisSetProcTitle(char *title); +void redisSetProcTitle(const char *title); /* networking.c -- Networking and Client related operations */ client *createClient(int fd, int iel); @@ -1621,7 +1618,6 @@ void setDeferredAttributeLen(client *c, void *node, long length); void setDeferredPushLen(client *c, void *node, long length); void processInputBuffer(client *c, int callFlags); void processInputBufferAndReplicate(client *c); -void processGopherRequest(client *c); void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask); void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask); void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask); @@ -1785,7 +1781,7 @@ int getDoubleFromObject(const robj *o, double *target); int getLongLongFromObject(robj *o, long long *target); int getLongDoubleFromObject(robj *o, long double *target); int getLongDoubleFromObjectOrReply(client *c, robj *o, long double *target, const char *msg); -char *strEncoding(int encoding); +const char *strEncoding(int encoding); int compareStringObjects(robj *a, robj *b); int collateStringObjects(robj *a, robj *b); int equalStringObjects(robj *a, robj *b); @@ -1827,7 +1823,7 @@ void changeReplicationId(void); void clearReplicationId2(void); void chopReplicationBacklog(void); void replicationCacheMasterUsingMyself(struct redisMaster *mi); -void feedReplicationBacklog(void *ptr, size_t len); +void feedReplicationBacklog(const void *ptr, size_t len); /* Generic persistence functions */ void startLoading(FILE *fp); @@ -1881,7 +1877,7 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen); sds ACLDefaultUserFirstPassword(void); uint64_t ACLGetCommandCategoryFlagByName(const char *name); int ACLAppendUserForLoading(sds *argv, int argc, int *argc_err); -char *ACLSetUserStringError(void); +const char *ACLSetUserStringError(void); int ACLLoadConfiguredUsers(void); sds ACLDescribeUser(user *u); void ACLLoadUsersAtStartup(void); @@ -2130,12 +2126,12 @@ int clusterSendModuleMessageToTarget(const char *target, uint64_t module_id, uin void initSentinelConfig(void); void initSentinel(void); void sentinelTimer(void); -char *sentinelHandleConfiguration(char **argv, int argc); +const char *sentinelHandleConfiguration(char **argv, int argc); void sentinelIsRunning(void); /* keydb-check-rdb & aof */ -int redis_check_rdb(char *rdbfilename, FILE *fp); -int redis_check_rdb_main(int argc, char **argv, FILE *fp); +int redis_check_rdb(const char *rdbfilename, FILE *fp); +int redis_check_rdb_main(int argc, const char **argv, FILE *fp); int redis_check_aof_main(int argc, char **argv); /* Scripting */ @@ -2376,7 +2372,6 @@ void xclaimCommand(client *c); void xinfoCommand(client *c); void xdelCommand(client *c); void xtrimCommand(client *c); -void lolwutCommand(client *c); void aclCommand(client *c); void replicaReplayCommand(client *c); @@ -2407,7 +2402,7 @@ void watchdogScheduleSignal(int period); void serverLogHexDump(int level, const char *descr, void *value, size_t len); int memtest_preserving_test(unsigned long *m, size_t bytes, int passes); void mixDigest(unsigned char *digest, void *ptr, size_t len); -void xorDigest(unsigned char *digest, void *ptr, size_t len); +void xorDigest(unsigned char *digest, const void *ptr, size_t len); int populateCommandTableParseFlags(struct redisCommand *c, const char *strflags); int moduleGILAcquiredByModule(void); diff --git a/src/slowlog.c b/src/slowlog.cpp similarity index 91% rename from src/slowlog.c rename to src/slowlog.cpp index 847b4a083..d79371bb0 100644 --- a/src/slowlog.c +++ b/src/slowlog.cpp @@ -46,12 +46,12 @@ * Incrementing the ref count of all the objects retained is up to * this function. */ slowlogEntry *slowlogCreateEntry(client *c, robj **argv, int argc, long long duration) { - slowlogEntry *se = zmalloc(sizeof(*se), MALLOC_LOCAL); + slowlogEntry *se = (slowlogEntry*)zmalloc(sizeof(*se), MALLOC_LOCAL); int j, slargc = argc; if (slargc > SLOWLOG_ENTRY_MAX_ARGC) slargc = SLOWLOG_ENTRY_MAX_ARGC; se->argc = slargc; - se->argv = zmalloc(sizeof(robj*)*slargc, MALLOC_LOCAL); + se->argv = (robj**)zmalloc(sizeof(robj*)*slargc, MALLOC_LOCAL); for (j = 0; j < slargc; j++) { /* Logging too many arguments is a useless memory waste, so we stop * at SLOWLOG_ENTRY_MAX_ARGC, but use the last argument to specify @@ -64,13 +64,13 @@ slowlogEntry *slowlogCreateEntry(client *c, robj **argv, int argc, long long dur /* Trim too long strings as well... */ if (argv[j]->type == OBJ_STRING && sdsEncodedObject(argv[j]) && - sdslen(ptrFromObj(argv[j])) > SLOWLOG_ENTRY_MAX_STRING) + sdslen(szFromObj(argv[j])) > SLOWLOG_ENTRY_MAX_STRING) { sds s = sdsnewlen(ptrFromObj(argv[j]), SLOWLOG_ENTRY_MAX_STRING); s = sdscatprintf(s,"... (%lu more bytes)", (unsigned long) - sdslen(ptrFromObj(argv[j])) - SLOWLOG_ENTRY_MAX_STRING); + sdslen(szFromObj(argv[j])) - SLOWLOG_ENTRY_MAX_STRING); se->argv[j] = createObject(OBJ_STRING,s); } else if (argv[j]->refcount == OBJ_SHARED_REFCOUNT) { se->argv[j] = argv[j]; @@ -89,7 +89,7 @@ slowlogEntry *slowlogCreateEntry(client *c, robj **argv, int argc, long long dur se->duration = duration; se->id = server.slowlog_entry_id++; se->peerid = sdsnew(getClientPeerId(c)); - se->cname = c->name ? sdsnew(ptrFromObj(c->name)) : sdsempty(); + se->cname = c->name ? sdsnew(szFromObj(c->name)) : sdsempty(); return se; } @@ -98,7 +98,7 @@ slowlogEntry *slowlogCreateEntry(client *c, robj **argv, int argc, long long dur * * This function will take care to release all the retained object. */ void slowlogFreeEntry(void *septr) { - slowlogEntry *se = septr; + slowlogEntry *se = (slowlogEntry*)septr; int j; for (j = 0; j < se->argc; j++) @@ -140,7 +140,7 @@ void slowlogReset(void) { /* The SLOWLOG command. Implements all the subcommands needed to handle the * Redis slow log. */ void slowlogCommand(client *c) { - if (c->argc == 2 && !strcasecmp(ptrFromObj(c->argv[1]),"help")) { + if (c->argc == 2 && !strcasecmp(szFromObj(c->argv[1]),"help")) { const char *help[] = { "GET [count] -- Return top entries from the slowlog (default: 10)." " Entries are made of:", @@ -150,13 +150,13 @@ void slowlogCommand(client *c) { NULL }; addReplyHelp(c, help); - } else if (c->argc == 2 && !strcasecmp(ptrFromObj(c->argv[1]),"reset")) { + } else if (c->argc == 2 && !strcasecmp(szFromObj(c->argv[1]),"reset")) { slowlogReset(); addReply(c,shared.ok); - } else if (c->argc == 2 && !strcasecmp(ptrFromObj(c->argv[1]),"len")) { + } else if (c->argc == 2 && !strcasecmp(szFromObj(c->argv[1]),"len")) { addReplyLongLong(c,listLength(server.slowlog)); } else if ((c->argc == 2 || c->argc == 3) && - !strcasecmp(ptrFromObj(c->argv[1]),"get")) + !strcasecmp(szFromObj(c->argv[1]),"get")) { long count = 10, sent = 0; listIter li; @@ -173,7 +173,7 @@ NULL while(count-- && (ln = listNext(&li))) { int j; - se = ln->value; + se = (slowlogEntry*)ln->value; addReplyArrayLen(c,6); addReplyLongLong(c,se->id); addReplyLongLong(c,se->time); diff --git a/src/sparkline.c b/src/sparkline.cpp similarity index 96% rename from src/sparkline.c rename to src/sparkline.cpp index 5ee6c7252..bc94b4939 100644 --- a/src/sparkline.c +++ b/src/sparkline.cpp @@ -55,7 +55,7 @@ static int label_margin_top = 1; /* Create a new sequence. */ struct sequence *createSparklineSequence(void) { - struct sequence *seq = zmalloc(sizeof(*seq), MALLOC_LOCAL); + struct sequence *seq = (sequence*)zmalloc(sizeof(*seq), MALLOC_LOCAL); seq->length = 0; seq->samples = NULL; return seq; @@ -70,7 +70,7 @@ void sparklineSequenceAddSample(struct sequence *seq, double value, char *label) if (value < seq->min) seq->min = value; else if (value > seq->max) seq->max = value; } - seq->samples = zrealloc(seq->samples,sizeof(struct sample)*(seq->length+1), MALLOC_SHARED); + seq->samples = (sample*)zrealloc(seq->samples,sizeof(struct sample)*(seq->length+1), MALLOC_SHARED); seq->samples[seq->length].value = value; seq->samples[seq->length].label = label; seq->length++; @@ -99,7 +99,7 @@ sds sparklineRenderRange(sds output, struct sequence *seq, int rows, int offset, double relmax = seq->max - seq->min; int steps = charset_len*rows; int row = 0; - char *chars = zmalloc(len, MALLOC_LOCAL); + char *chars = (char*)zmalloc(len, MALLOC_LOCAL); int loop = 1; int opt_fill = flags & SPARKLINE_FILL; int opt_log = flags & SPARKLINE_LOG_SCALE; diff --git a/src/sparkline.h b/src/sparkline.h index 6025d2b98..7fefa5c72 100644 --- a/src/sparkline.h +++ b/src/sparkline.h @@ -47,10 +47,18 @@ struct sequence { #define SPARKLINE_FILL 1 /* Fill the area under the curve. */ #define SPARKLINE_LOG_SCALE 2 /* Use logarithmic scale. */ +#ifdef __cplusplus +extern "C" { +#endif + struct sequence *createSparklineSequence(void); void sparklineSequenceAddSample(struct sequence *seq, double value, char *label); void freeSparklineSequence(struct sequence *seq); sds sparklineRenderRange(sds output, struct sequence *seq, int rows, int offset, int len, int flags); sds sparklineRender(sds output, struct sequence *seq, int columns, int rows, int flags); +#ifdef __cplusplus +} +#endif + #endif /* __SPARKLINE_H */ diff --git a/src/storage.c b/src/storage.cpp similarity index 100% rename from src/storage.c rename to src/storage.cpp diff --git a/src/syncio.c b/src/syncio.cpp similarity index 100% rename from src/syncio.c rename to src/syncio.cpp diff --git a/src/zipmap.h b/src/zipmap.h index ac588f05a..140e8888f 100644 --- a/src/zipmap.h +++ b/src/zipmap.h @@ -35,6 +35,10 @@ #ifndef _ZIPMAP_H #define _ZIPMAP_H +#ifdef __cplusplus +extern "C" { +#endif + unsigned char *zipmapNew(void); unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char *val, unsigned int vlen, int *update); unsigned char *zipmapDel(unsigned char *zm, unsigned char *key, unsigned int klen, int *deleted); @@ -50,4 +54,8 @@ void zipmapRepr(unsigned char *p); int zipmapTest(int argc, char *argv[]); #endif +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/zmalloc.c b/src/zmalloc.c index dc580834c..3847ee75a 100644 --- a/src/zmalloc.c +++ b/src/zmalloc.c @@ -358,7 +358,7 @@ int zmalloc_get_allocator_info(size_t *allocated, * Example: zmalloc_get_smap_bytes_by_field("Rss:",-1); */ #if defined(HAVE_PROC_SMAPS) -size_t zmalloc_get_smap_bytes_by_field(char *field, long pid) { +size_t zmalloc_get_smap_bytes_by_field(const char *field, long pid) { char line[1024]; size_t bytes = 0; int flen = strlen(field); @@ -386,7 +386,7 @@ size_t zmalloc_get_smap_bytes_by_field(char *field, long pid) { return bytes; } #else -size_t zmalloc_get_smap_bytes_by_field(char *field, long pid) { +size_t zmalloc_get_smap_bytes_by_field(const char *field, long pid) { ((void) field); ((void) pid); return 0; diff --git a/src/zmalloc.h b/src/zmalloc.h index a7b980025..e92d8a199 100644 --- a/src/zmalloc.h +++ b/src/zmalloc.h @@ -96,7 +96,7 @@ void zmalloc_set_oom_handler(void (*oom_handler)(size_t)); size_t zmalloc_get_rss(void); int zmalloc_get_allocator_info(size_t *allocated, size_t *active, size_t *resident); size_t zmalloc_get_private_dirty(long pid); -size_t zmalloc_get_smap_bytes_by_field(char *field, long pid); +size_t zmalloc_get_smap_bytes_by_field(const char *field, long pid); size_t zmalloc_get_memory_size(void); void zlibc_free(void *ptr);