Move remaning files dependent on server.h over to C++

Former-commit-id: 8c133b605c65212b023d35b3cb71e63b6a4c443a
This commit is contained in:
John Sully 2019-04-08 01:00:48 -04:00
parent e766f66b11
commit 7859e0562f
54 changed files with 2450 additions and 2734 deletions

10
deps/hiredis/sds.h vendored
View File

@ -45,31 +45,41 @@ typedef char *sds;
* However is here to document the layout of type 5 SDS strings. */ * However is here to document the layout of type 5 SDS strings. */
struct __attribute__ ((__packed__)) sdshdr5 { struct __attribute__ ((__packed__)) sdshdr5 {
unsigned char flags; /* 3 lsb of type, and 5 msb of string length */ unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
#ifndef __cplusplus
char buf[]; char buf[];
#endif
}; };
struct __attribute__ ((__packed__)) sdshdr8 { struct __attribute__ ((__packed__)) sdshdr8 {
uint8_t len; /* used */ uint8_t len; /* used */
uint8_t alloc; /* excluding the header and null terminator */ uint8_t alloc; /* excluding the header and null terminator */
unsigned char flags; /* 3 lsb of type, 5 unused bits */ unsigned char flags; /* 3 lsb of type, 5 unused bits */
#ifndef __cplusplus
char buf[]; char buf[];
#endif
}; };
struct __attribute__ ((__packed__)) sdshdr16 { struct __attribute__ ((__packed__)) sdshdr16 {
uint16_t len; /* used */ uint16_t len; /* used */
uint16_t alloc; /* excluding the header and null terminator */ uint16_t alloc; /* excluding the header and null terminator */
unsigned char flags; /* 3 lsb of type, 5 unused bits */ unsigned char flags; /* 3 lsb of type, 5 unused bits */
#ifndef __cplusplus
char buf[]; char buf[];
#endif
}; };
struct __attribute__ ((__packed__)) sdshdr32 { struct __attribute__ ((__packed__)) sdshdr32 {
uint32_t len; /* used */ uint32_t len; /* used */
uint32_t alloc; /* excluding the header and null terminator */ uint32_t alloc; /* excluding the header and null terminator */
unsigned char flags; /* 3 lsb of type, 5 unused bits */ unsigned char flags; /* 3 lsb of type, 5 unused bits */
#ifndef __cplusplus
char buf[]; char buf[];
#endif
}; };
struct __attribute__ ((__packed__)) sdshdr64 { struct __attribute__ ((__packed__)) sdshdr64 {
uint64_t len; /* used */ uint64_t len; /* used */
uint64_t alloc; /* excluding the header and null terminator */ uint64_t alloc; /* excluding the header and null terminator */
unsigned char flags; /* 3 lsb of type, 5 unused bits */ unsigned char flags; /* 3 lsb of type, 5 unused bits */
#ifndef __cplusplus
char buf[]; char buf[];
#endif
}; };
#define SDS_TYPE_5 0 #define SDS_TYPE_5 0

View File

@ -197,9 +197,9 @@ endif
REDIS_SERVER_NAME=keydb-server REDIS_SERVER_NAME=keydb-server
REDIS_SENTINEL_NAME=keydb-sentinel 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_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_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_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 REDIS_CHECK_RDB_NAME=keydb-check-rdb

View File

@ -157,17 +157,17 @@ uint64_t ACLGetCommandCategoryFlagByName(const char *name) {
/* Method for passwords/pattern comparison used for the user->passwords list /* Method for passwords/pattern comparison used for the user->passwords list
* so that we can search for items with listSearchKey(). */ * so that we can search for items with listSearchKey(). */
int ACLListMatchSds(void *a, void *b) { 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. */ /* Method to free list elements from ACL users password/ptterns lists. */
void ACLListFreeSds(void *item) { void ACLListFreeSds(void *item) {
sdsfree(item); sdsfree((sds)item);
} }
/* Method to duplicate list elements from ACL users password/ptterns lists. */ /* Method to duplicate list elements from ACL users password/ptterns lists. */
void *ACLListDupSds(void *item) { void *ACLListDupSds(void *item) {
return sdsdup(item); return sdsdup((sds)item);
} }
/* Create a new user with the specified name, store it in the list /* 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. */ * If the user with such name already exists NULL is returned. */
user *ACLCreateUser(const char *name, size_t namelen) { user *ACLCreateUser(const char *name, size_t namelen) {
if (raxFind(Users,(unsigned char*)name,namelen) != raxNotFound) return NULL; 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->name = sdsnewlen(name,namelen);
u->flags = USER_FLAG_DISABLED; u->flags = USER_FLAG_DISABLED;
u->allowed_subcommands = NULL; u->allowed_subcommands = NULL;
@ -229,7 +229,7 @@ void ACLFreeUserAndKillClients(user *u) {
listNode *ln; listNode *ln;
listRewind(server.clients,&li); listRewind(server.clients,&li);
while ((ln = listNext(&li)) != NULL) { while ((ln = listNext(&li)) != NULL) {
client *c = listNodeValue(ln); client *c = (client*)listNodeValue(ln);
if (c->puser == u) { if (c->puser == u) {
/* We'll free the conenction asynchronously, so /* We'll free the conenction asynchronously, so
* in theory to set a different user is not needed. * 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); dictIterator *di = dictGetIterator(server.orig_commands);
dictEntry *de; dictEntry *de;
while ((de = dictNext(di)) != NULL) { 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 & CMD_MODULE) continue; /* Ignore modules commands. */
if (cmd->flags & cflag) { if (cmd->flags & cflag) {
ACLSetUserCommandBit(u,cmd->id,value); 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); dictIterator *di = dictGetIterator(server.orig_commands);
dictEntry *de; dictEntry *de;
while ((de = dictNext(di)) != NULL) { while ((de = dictNext(di)) != NULL) {
struct redisCommand *cmd = dictGetVal(de); struct redisCommand *cmd = (redisCommand*)dictGetVal(de);
if (cmd->flags & cflag) { if (cmd->flags & cflag) {
if (ACLGetUserCommandBit(u,cmd->id)) if (ACLGetUserCommandBit(u,cmd->id))
(*on)++; (*on)++;
@ -431,7 +431,7 @@ sds ACLDescribeUserCommandRules(user *u) {
dictIterator *di = dictGetIterator(server.orig_commands); dictIterator *di = dictGetIterator(server.orig_commands);
dictEntry *de; dictEntry *de;
while ((de = dictNext(di)) != NULL) { while ((de = dictNext(di)) != NULL) {
struct redisCommand *cmd = dictGetVal(de); struct redisCommand *cmd = (redisCommand*)dictGetVal(de);
int userbit = ACLGetUserCommandBit(u,cmd->id); int userbit = ACLGetUserCommandBit(u,cmd->id);
int fakebit = ACLGetUserCommandBit(fakeuser,cmd->id); int fakebit = ACLGetUserCommandBit(fakeuser,cmd->id);
if (userbit != fakebit) { if (userbit != fakebit) {
@ -501,7 +501,7 @@ sds ACLDescribeUser(user *u) {
listNode *ln; listNode *ln;
listRewind(u->passwords,&li); listRewind(u->passwords,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
sds thispass = listNodeValue(ln); sds thispass = (sds)listNodeValue(ln);
res = sdscatlen(res,">",1); res = sdscatlen(res,">",1);
res = sdscatsds(res,thispass); res = sdscatsds(res,thispass);
res = sdscatlen(res," ",1); res = sdscatlen(res," ",1);
@ -513,7 +513,7 @@ sds ACLDescribeUser(user *u) {
} else { } else {
listRewind(u->patterns,&li); listRewind(u->patterns,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
sds thispat = listNodeValue(ln); sds thispat = (sds)listNodeValue(ln);
res = sdscatlen(res,"~",1); res = sdscatlen(res,"~",1);
res = sdscatsds(res,thispat); res = sdscatsds(res,thispat);
res = sdscatlen(res," ",1); res = sdscatlen(res," ",1);
@ -533,7 +533,7 @@ sds ACLDescribeUser(user *u) {
struct redisCommand *ACLLookupCommand(const char *name) { struct redisCommand *ACLLookupCommand(const char *name) {
struct redisCommand *cmd; struct redisCommand *cmd;
sds sdsname = sdsnew(name); sds sdsname = sdsnew(name);
cmd = dictFetchValue(server.orig_commands, sdsname); cmd = (redisCommand*)dictFetchValue(server.orig_commands, sdsname);
sdsfree(sdsname); sdsfree(sdsname);
return cmd; 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 /* If this is the first subcommand to be configured for
* this user, we have to allocate the subcommands array. */ * this user, we have to allocate the subcommands array. */
if (u->allowed_subcommands == NULL) { 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); 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). */ /* Now we can make space for the new item (and the null term). */
items += 2; 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); sizeof(sds)*items, MALLOC_LOCAL);
u->allowed_subcommands[id][items-2] = sdsnew(sub); u->allowed_subcommands[id][items-2] = sdsnew(sub);
u->allowed_subcommands[id][items-1] = NULL; 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 /* Return a description of the error that occurred in ACLSetUser() according to
* the errno value set by the function on error. */ * the errno value set by the function on error. */
char *ACLSetUserStringError(void) { const char *ACLSetUserStringError(void) {
char *errmsg = "Wrong format"; const char *errmsg = "Wrong format";
if (errno == ENOENT) if (errno == ENOENT)
errmsg = "Unknown command or category name in ACL"; errmsg = "Unknown command or category name in ACL";
else if (errno == EINVAL) else if (errno == EINVAL)
@ -830,7 +830,7 @@ char *ACLSetUserStringError(void) {
sds ACLDefaultUserFirstPassword(void) { sds ACLDefaultUserFirstPassword(void) {
if (listLength(DefaultUser->passwords) == 0) return NULL; if (listLength(DefaultUser->passwords) == 0) return NULL;
listNode *first = listFirst(DefaultUser->passwords); listNode *first = listFirst(DefaultUser->passwords);
return listNodeValue(first); return (sds)listNodeValue(first);
} }
/* Initialize the default user, that will always exist for all the process /* 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. * ENONENT: if the specified user does not exist at all.
*/ */
int ACLCheckUserCredentials(robj *username, robj *password) { 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) { if (u == NULL) {
errno = ENOENT; errno = ENOENT;
return C_ERR; return C_ERR;
@ -878,8 +878,8 @@ int ACLCheckUserCredentials(robj *username, robj *password) {
listNode *ln; listNode *ln;
listRewind(u->passwords,&li); listRewind(u->passwords,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
sds thispass = listNodeValue(ln); sds thispass = (sds)listNodeValue(ln);
if (!time_independent_strcmp(ptrFromObj(password), thispass)) if (!time_independent_strcmp(szFromObj(password), thispass))
return C_OK; return C_OK;
} }
@ -944,7 +944,7 @@ unsigned long ACLGetCommandID(const char *cmdname) {
user *ACLGetUserByName(const char *name, size_t namelen) { user *ACLGetUserByName(const char *name, size_t namelen) {
void *myuser = raxFind(Users,(unsigned char*)name,namelen); void *myuser = raxFind(Users,(unsigned char*)name,namelen);
if (myuser == raxNotFound) return NULL; if (myuser == raxNotFound) return NULL;
return myuser; return (user*)myuser;
} }
/* Check if the command ready to be excuted in the client 'c', and already /* Check if the command ready to be excuted in the client 'c', and already
@ -982,7 +982,7 @@ int ACLCheckCommandPerm(client *c) {
while (1) { while (1) {
if (u->allowed_subcommands[id][subid] == NULL) if (u->allowed_subcommands[id][subid] == NULL)
return ACL_DENIED_CMD; return ACL_DENIED_CMD;
if (!strcasecmp(ptrFromObj(c->argv[1]), if (!strcasecmp(szFromObj(c->argv[1]),
u->allowed_subcommands[id][subid])) u->allowed_subcommands[id][subid]))
break; /* Subcommand match found. Stop here. */ break; /* Subcommand match found. Stop here. */
subid++; subid++;
@ -1005,11 +1005,11 @@ int ACLCheckCommandPerm(client *c) {
/* Test this key against every pattern. */ /* Test this key against every pattern. */
int match = 0; int match = 0;
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
sds pattern = listNodeValue(ln); sds pattern = (sds)listNodeValue(ln);
size_t plen = sdslen(pattern); size_t plen = sdslen(pattern);
int idx = keyidx[j]; int idx = keyidx[j];
if (stringmatchlen(pattern,plen,ptrFromObj(c->argv[idx]), if (stringmatchlen(pattern,plen,szFromObj(c->argv[idx]),
sdslen(ptrFromObj(c->argv[idx])),0)) sdslen(szFromObj(c->argv[idx])),0))
{ {
match = 1; match = 1;
break; 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. */ /* 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]); for (int j = 1; j < argc; j++) copy[j-1] = sdsdup(argv[j]);
copy[argc-1] = NULL; copy[argc-1] = NULL;
listAddNodeTail(UsersToLoad,copy); listAddNodeTail(UsersToLoad,copy);
@ -1087,7 +1087,7 @@ int ACLLoadConfiguredUsers(void) {
listNode *ln; listNode *ln;
listRewind(UsersToLoad,&li); listRewind(UsersToLoad,&li);
while ((ln = listNext(&li)) != NULL) { while ((ln = listNext(&li)) != NULL) {
sds *aclrules = listNodeValue(ln); sds *aclrules = (sds*)listNodeValue(ln);
sds username = aclrules[0]; sds username = aclrules[0];
user *u = ACLCreateUser(username,sdslen(username)); user *u = ACLCreateUser(username,sdslen(username));
if (!u) { if (!u) {
@ -1099,7 +1099,7 @@ int ACLLoadConfiguredUsers(void) {
/* Load every rule defined for this user. */ /* Load every rule defined for this user. */
for (int j = 1; aclrules[j]; j++) { for (int j = 1; aclrules[j]; j++) {
if (ACLSetUser(u,aclrules[j],sdslen(aclrules[j])) != C_OK) { 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 " serverLog(LL_WARNING,"Error loading ACL rule '%s' for "
"the user named '%s': %s", "the user named '%s': %s",
aclrules[j],aclrules[0],errmsg); aclrules[j],aclrules[0],errmsg);
@ -1220,7 +1220,7 @@ sds ACLLoadFromFile(const char *filename) {
int j; int j;
for (j = 2; j < argc; j++) { for (j = 2; j < argc; j++) {
if (ACLSetUser(fakeuser,argv[j],sdslen(argv[j])) != C_OK) { if (ACLSetUser(fakeuser,argv[j],sdslen(argv[j])) != C_OK) {
char *errmsg = ACLSetUserStringError(); const char *errmsg = ACLSetUserStringError();
errors = sdscatprintf(errors, errors = sdscatprintf(errors,
"%s:%d: %s. ", "%s:%d: %s. ",
server.acl_filename, linenum, errmsg); server.acl_filename, linenum, errmsg);
@ -1262,10 +1262,10 @@ sds ACLLoadFromFile(const char *filename) {
/* The default user pointer is referenced in different places: instead /* The default user pointer is referenced in different places: instead
* of replacing such occurrences it is much simpler to copy the new * of replacing such occurrences it is much simpler to copy the new
* default user configuration in the old one. */ * default user configuration in the old one. */
user *new = ACLGetUserByName("default",7); user *newuser = ACLGetUserByName("default",7);
serverAssert(new != NULL); serverAssert(newuser != NULL);
ACLCopyUser(DefaultUser,new); ACLCopyUser(DefaultUser,newuser);
ACLFreeUser(new); ACLFreeUser(newuser);
raxInsert(Users,(unsigned char*)"default",7,DefaultUser,NULL); raxInsert(Users,(unsigned char*)"default",7,DefaultUser,NULL);
raxRemove(old_users,(unsigned char*)"default",7,NULL); raxRemove(old_users,(unsigned char*)"default",7,NULL);
ACLFreeUsersSet(old_users); ACLFreeUsersSet(old_users);
@ -1294,7 +1294,7 @@ int ACLSaveToFile(const char *filename) {
raxStart(&ri,Users); raxStart(&ri,Users);
raxSeek(&ri,"^",NULL,0); raxSeek(&ri,"^",NULL,0);
while(raxNext(&ri)) { while(raxNext(&ri)) {
user *u = ri.data; user *u = (user*)ri.data;
/* Return information in the configuration file format. */ /* Return information in the configuration file format. */
sds user = sdsnew("user "); sds user = sdsnew("user ");
user = sdscatsds(user,u->name); user = sdscatsds(user,u->name);
@ -1393,9 +1393,9 @@ void ACLLoadUsersAtStartup(void) {
* ACL WHOAMI * ACL WHOAMI
*/ */
void aclCommand(client *c) { void aclCommand(client *c) {
char *sub = ptrFromObj(c->argv[1]); char *sub = szFromObj(c->argv[1]);
if (!strcasecmp(sub,"setuser") && c->argc >= 3) { 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 /* Create a temporary user to validate and stage all changes against
* before applying to an existing user or creating a new user. If all * before applying to an existing user or creating a new user. If all
* arguments are valid the user parameters will all be applied together. * arguments are valid the user parameters will all be applied together.
@ -1405,8 +1405,8 @@ void aclCommand(client *c) {
if (u) ACLCopyUser(tempu, u); if (u) ACLCopyUser(tempu, u);
for (int j = 3; j < c->argc; j++) { for (int j = 3; j < c->argc; j++) {
if (ACLSetUser(tempu,ptrFromObj(c->argv[j]),sdslen(ptrFromObj(c->argv[j]))) != C_OK) { if (ACLSetUser(tempu,szFromObj(c->argv[j]),sdslen(szFromObj(c->argv[j]))) != C_OK) {
char *errmsg = ACLSetUserStringError(); const char *errmsg = ACLSetUserStringError();
addReplyErrorFormat(c, addReplyErrorFormat(c,
"Error in ACL SETUSER modifier '%s': %s", "Error in ACL SETUSER modifier '%s': %s",
(char*)ptrFromObj(c->argv[j]), errmsg); (char*)ptrFromObj(c->argv[j]), errmsg);
@ -1425,7 +1425,7 @@ void aclCommand(client *c) {
} else if (!strcasecmp(sub,"deluser") && c->argc >= 3) { } else if (!strcasecmp(sub,"deluser") && c->argc >= 3) {
int deleted = 0; int deleted = 0;
for (int j = 2; j < c->argc; j++) { for (int j = 2; j < c->argc; j++) {
sds username = ptrFromObj(c->argv[j]); sds username = szFromObj(c->argv[j]);
if (!strcmp(username,"default")) { if (!strcmp(username,"default")) {
addReplyError(c,"The 'default' user cannot be removed"); addReplyError(c,"The 'default' user cannot be removed");
return; return;
@ -1433,7 +1433,7 @@ void aclCommand(client *c) {
} }
for (int j = 2; j < c->argc; j++) { for (int j = 2; j < c->argc; j++) {
sds username = ptrFromObj(c->argv[j]); sds username = szFromObj(c->argv[j]);
user *u; user *u;
if (raxRemove(Users,(unsigned char*)username, if (raxRemove(Users,(unsigned char*)username,
sdslen(username), sdslen(username),
@ -1445,7 +1445,7 @@ void aclCommand(client *c) {
} }
addReplyLongLong(c,deleted); addReplyLongLong(c,deleted);
} else if (!strcasecmp(sub,"getuser") && c->argc == 3) { } 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) { if (u == NULL) {
addReplyNull(c); addReplyNull(c);
return; return;
@ -1472,7 +1472,7 @@ void aclCommand(client *c) {
listNode *ln; listNode *ln;
listRewind(u->passwords,&li); listRewind(u->passwords,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
sds thispass = listNodeValue(ln); sds thispass = (sds)listNodeValue(ln);
addReplyBulkCBuffer(c,thispass,sdslen(thispass)); addReplyBulkCBuffer(c,thispass,sdslen(thispass));
} }
@ -1492,7 +1492,7 @@ void aclCommand(client *c) {
listNode *ln; listNode *ln;
listRewind(u->patterns,&li); listRewind(u->patterns,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
sds thispat = listNodeValue(ln); sds thispat = (sds)listNodeValue(ln);
addReplyBulkCBuffer(c,thispat,sdslen(thispat)); addReplyBulkCBuffer(c,thispat,sdslen(thispat));
} }
} }
@ -1505,7 +1505,7 @@ void aclCommand(client *c) {
raxStart(&ri,Users); raxStart(&ri,Users);
raxSeek(&ri,"^",NULL,0); raxSeek(&ri,"^",NULL,0);
while(raxNext(&ri)) { while(raxNext(&ri)) {
user *u = ri.data; user *u = (user*)ri.data;
if (justnames) { if (justnames) {
addReplyBulkCBuffer(c,u->name,sdslen(u->name)); addReplyBulkCBuffer(c,u->name,sdslen(u->name));
} else { } else {
@ -1554,7 +1554,7 @@ void aclCommand(client *c) {
addReplyBulkCString(c,ACLCommandCategories[j].name); addReplyBulkCString(c,ACLCommandCategories[j].name);
setDeferredArrayLen(c,dl,j); setDeferredArrayLen(c,dl,j);
} else if (!strcasecmp(sub,"cat") && c->argc == 3) { } 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) { if (cflag == 0) {
addReplyErrorFormat(c, "Unknown category '%s'", (char*)ptrFromObj(c->argv[2])); addReplyErrorFormat(c, "Unknown category '%s'", (char*)ptrFromObj(c->argv[2]));
return; return;
@ -1564,7 +1564,7 @@ void aclCommand(client *c) {
dictIterator *di = dictGetIterator(server.orig_commands); dictIterator *di = dictGetIterator(server.orig_commands);
dictEntry *de; dictEntry *de;
while ((de = dictNext(di)) != NULL) { 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 & CMD_MODULE) continue;
if (cmd->flags & cflag) { if (cmd->flags & cflag) {
addReplyBulkCString(c,cmd->name); addReplyBulkCString(c,cmd->name);

View File

@ -83,7 +83,7 @@ unsigned long aofRewriteBufferSize(void) {
listRewind(server.aof_rewrite_buf_blocks,&li); listRewind(server.aof_rewrite_buf_blocks,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
aofrwblock *block = listNodeValue(ln); aofrwblock *block = (aofrwblock*)listNodeValue(ln);
size += block->used; size += block->used;
} }
return size; return size;
@ -105,7 +105,7 @@ void aofChildWriteDiffData(aeEventLoop *el, int fd, void *privdata, int mask) {
while(1) { while(1) {
ln = listFirst(server.aof_rewrite_buf_blocks); 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) { if (server.aof_stop_sending_diff || !block) {
aeDeleteFileEvent(el,server.aof_pipe_write_data_to_child, aeDeleteFileEvent(el,server.aof_pipe_write_data_to_child,
AE_WRITABLE); 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. */ /* Append data to the AOF rewrite buffer, allocating new blocks if needed. */
void aofRewriteBufferAppend(unsigned char *s, unsigned long len) { void aofRewriteBufferAppend(unsigned char *s, unsigned long len) {
listNode *ln = listLast(server.aof_rewrite_buf_blocks); listNode *ln = listLast(server.aof_rewrite_buf_blocks);
aofrwblock *block = ln ? ln->value : NULL; aofrwblock *block = (aofrwblock*)(ln ? ln->value : NULL);
while(len) { while(len) {
/* If we already got at least an allocated block, try appending /* 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. */ if (len) { /* First block to allocate, or need another block. */
int numblocks; int numblocks;
block = zmalloc(sizeof(*block), MALLOC_LOCAL); block = (aofrwblock*)zmalloc(sizeof(*block), MALLOC_LOCAL);
block->free = AOF_RW_BUF_BLOCK_SIZE; block->free = AOF_RW_BUF_BLOCK_SIZE;
block->used = 0; block->used = 0;
listAddNodeTail(server.aof_rewrite_buf_blocks,block); listAddNodeTail(server.aof_rewrite_buf_blocks,block);
@ -180,7 +180,7 @@ ssize_t aofRewriteBufferWrite(int fd) {
listRewind(server.aof_rewrite_buf_blocks,&li); listRewind(server.aof_rewrite_buf_blocks,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
aofrwblock *block = listNodeValue(ln); aofrwblock *block = (aofrwblock*)listNodeValue(ln);
ssize_t nwritten; ssize_t nwritten;
if (block->used) { if (block->used) {
@ -508,11 +508,11 @@ sds catAppendOnlyGenericCommand(sds dst, int argc, robj **argv) {
for (j = 0; j < argc; j++) { for (j = 0; j < argc; j++) {
o = getDecodedObject(argv[j]); o = getDecodedObject(argv[j]);
buf[0] = '$'; 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++] = '\r';
buf[len++] = '\n'; buf[len++] = '\n';
dst = sdscatlen(dst,buf,len); 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); dst = sdscatlen(dst,"\r\n",2);
decrRefCount(o); decrRefCount(o);
} }
@ -532,7 +532,7 @@ sds catAppendOnlyExpireAtCommand(sds buf, struct redisCommand *cmd, robj *key, r
/* Make sure we can use strtoll */ /* Make sure we can use strtoll */
seconds = getDecodedObject(seconds); seconds = getDecodedObject(seconds);
when = strtoll(ptrFromObj(seconds),NULL,10); when = strtoll(szFromObj(seconds),NULL,10);
/* Convert argument into milliseconds for EXPIRE, SETEX, EXPIREAT */ /* Convert argument into milliseconds for EXPIRE, SETEX, EXPIREAT */
if (cmd->proc == expireCommand || cmd->proc == setexCommand || if (cmd->proc == expireCommand || cmd->proc == setexCommand ||
cmd->proc == expireatCommand) 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 */ /* Translate SET [EX seconds][PX milliseconds] to SET and PEXPIREAT */
buf = catAppendOnlyGenericCommand(buf,3,argv); buf = catAppendOnlyGenericCommand(buf,3,argv);
for (i = 3; i < argc; i ++) { for (i = 3; i < argc; i ++) {
if (!strcasecmp(ptrFromObj(argv[i]), "ex")) exarg = argv[i+1]; if (!strcasecmp(szFromObj(argv[i]), "ex")) exarg = argv[i+1];
if (!strcasecmp(ptrFromObj(argv[i]), "px")) pxarg = argv[i+1]; if (!strcasecmp(szFromObj(argv[i]), "px")) pxarg = argv[i+1];
} }
serverAssert(!(exarg && pxarg)); serverAssert(!(exarg && pxarg));
if (exarg) 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 /* 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. */ * order to load the append only file we need to create a fake client. */
struct client *createFakeClient(void) { client *createFakeClient(void) {
struct client *c = zmalloc(sizeof(*c), MALLOC_LOCAL); client *c = (client*)zmalloc(sizeof(*c), MALLOC_LOCAL);
selectDb(c,0); selectDb(c,0);
c->fd = -1; c->fd = -1;
@ -762,7 +762,7 @@ int loadAppendOnlyFile(char *filename) {
argc = atoi(buf+1); argc = atoi(buf+1);
if (argc < 1) goto fmterr; if (argc < 1) goto fmterr;
argv = zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL); argv = (robj**)zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL);
fakeClient->argc = argc; fakeClient->argc = argc;
fakeClient->argv = argv; fakeClient->argv = argv;
@ -790,7 +790,7 @@ int loadAppendOnlyFile(char *filename) {
} }
/* Command lookup */ /* Command lookup */
cmd = lookupCommand(ptrFromObj(argv[0])); cmd = lookupCommand(szFromObj(argv[0]));
if (!cmd) { if (!cmd) {
serverLog(LL_WARNING, serverLog(LL_WARNING,
"Unknown command '%s' reading the append only file", "Unknown command '%s' reading the append only file",
@ -898,7 +898,7 @@ int rioWriteBulkObject(rio *r, robj *obj) {
if (obj->encoding == OBJ_ENCODING_INT) { if (obj->encoding == OBJ_ENCODING_INT) {
return rioWriteBulkLongLong(r,(long)obj->m_ptr); return rioWriteBulkLongLong(r,(long)obj->m_ptr);
} else if (sdsEncodedObject(obj)) { } else if (sdsEncodedObject(obj)) {
return rioWriteBulkString(r,ptrFromObj(obj),sdslen(ptrFromObj(obj))); return rioWriteBulkString(r,szFromObj(obj),sdslen(szFromObj(obj)));
} else { } else {
serverPanic("Unknown string encoding"); serverPanic("Unknown string encoding");
} }
@ -910,7 +910,7 @@ int rewriteListObject(rio *r, robj *key, robj *o) {
long long count = 0, items = listTypeLength(o); long long count = 0, items = listTypeLength(o);
if (o->encoding == OBJ_ENCODING_QUICKLIST) { if (o->encoding == OBJ_ENCODING_QUICKLIST) {
quicklist *list = ptrFromObj(o); quicklist *list = (quicklist*)ptrFromObj(o);
quicklistIter *li = quicklistGetIterator(list, AL_START_HEAD); quicklistIter *li = quicklistGetIterator(list, AL_START_HEAD);
quicklistEntry entry; quicklistEntry entry;
@ -947,7 +947,7 @@ int rewriteSetObject(rio *r, robj *key, robj *o) {
int ii = 0; int ii = 0;
int64_t llval; int64_t llval;
while(intsetGet(ptrFromObj(o),ii++,&llval)) { while(intsetGet((intset*)ptrFromObj(o),ii++,&llval)) {
if (count == 0) { if (count == 0) {
int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ?
AOF_REWRITE_ITEMS_PER_CMD : items; AOF_REWRITE_ITEMS_PER_CMD : items;
@ -961,11 +961,11 @@ int rewriteSetObject(rio *r, robj *key, robj *o) {
items--; items--;
} }
} else if (o->encoding == OBJ_ENCODING_HT) { } else if (o->encoding == OBJ_ENCODING_HT) {
dictIterator *di = dictGetIterator(ptrFromObj(o)); dictIterator *di = dictGetIterator((dict*)ptrFromObj(o));
dictEntry *de; dictEntry *de;
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sds ele = dictGetKey(de); sds ele = (sds)dictGetKey(de);
if (count == 0) { if (count == 0) {
int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ?
AOF_REWRITE_ITEMS_PER_CMD : items; 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); long long count = 0, items = zsetLength(o);
if (o->encoding == OBJ_ENCODING_ZIPLIST) { if (o->encoding == OBJ_ENCODING_ZIPLIST) {
unsigned char *zl = ptrFromObj(o); unsigned char *zl = (unsigned char*)ptrFromObj(o);
unsigned char *eptr, *sptr; unsigned char *eptr, *sptr;
unsigned char *vstr; unsigned char *vstr;
unsigned int vlen; unsigned int vlen;
@ -1026,13 +1026,13 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) {
items--; items--;
} }
} else if (o->encoding == OBJ_ENCODING_SKIPLIST) { } else if (o->encoding == OBJ_ENCODING_SKIPLIST) {
zset *zs = ptrFromObj(o); zset *zs = (zset*)ptrFromObj(o);
dictIterator *di = dictGetIterator(zs->pdict); dictIterator *di = dictGetIterator(zs->pdict);
dictEntry *de; dictEntry *de;
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sds ele = dictGetKey(de); sds ele = (sds)dictGetKey(de);
double *score = dictGetVal(de); double *score = (double*)dictGetVal(de);
if (count == 0) { if (count == 0) {
int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ? 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. /* Emit the commands needed to rebuild a stream object.
* The function returns 0 on error, 1 on success. */ * The function returns 0 on error, 1 on success. */
int rewriteStreamObject(rio *r, robj *key, robj *o) { int rewriteStreamObject(rio *r, robj *key, robj *o) {
stream *s = ptrFromObj(o); stream *s = (stream*)ptrFromObj(o);
streamIterator si; streamIterator si;
streamIteratorStart(&si,s,NULL,NULL,0); streamIteratorStart(&si,s,NULL,NULL,0);
streamID id; streamID id;
@ -1200,7 +1200,7 @@ int rewriteStreamObject(rio *r, robj *key, robj *o) {
raxStart(&ri,s->cgroups); raxStart(&ri,s->cgroups);
raxSeek(&ri,"^",NULL,0); raxSeek(&ri,"^",NULL,0);
while(raxNext(&ri)) { while(raxNext(&ri)) {
streamCG *group = ri.data; streamCG *group = (streamCG*)ri.data;
/* Emit the XGROUP CREATE in order to create the group. */ /* Emit the XGROUP CREATE in order to create the group. */
if (rioWriteBulkCount(r,'*',5) == 0) return 0; if (rioWriteBulkCount(r,'*',5) == 0) return 0;
if (rioWriteBulkString(r,"XGROUP",6) == 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); raxStart(&ri_cons,group->consumers);
raxSeek(&ri_cons,"^",NULL,0); raxSeek(&ri_cons,"^",NULL,0);
while(raxNext(&ri_cons)) { while(raxNext(&ri_cons)) {
streamConsumer *consumer = ri_cons.data; streamConsumer *consumer = (streamConsumer*)ri_cons.data;
/* For the current consumer, iterate all the PEL entries /* For the current consumer, iterate all the PEL entries
* to emit the XCLAIM protocol. */ * to emit the XCLAIM protocol. */
raxIterator ri_pel; raxIterator ri_pel;
raxStart(&ri_pel,consumer->pel); raxStart(&ri_pel,consumer->pel);
raxSeek(&ri_pel,"^",NULL,0); raxSeek(&ri_pel,"^",NULL,0);
while(raxNext(&ri_pel)) { while(raxNext(&ri_pel)) {
streamNACK *nack = ri_pel.data; streamNACK *nack = (streamNACK*)ri_pel.data;
if (rioWriteStreamPendingEntry(r,key,(char*)ri.key, if (rioWriteStreamPendingEntry(r,key,(char*)ri.key,
ri.key_len,consumer, ri.key_len,consumer,
ri_pel.key,nack) == 0) 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. */ * The function returns 0 on error, 1 on success. */
int rewriteModuleObject(rio *r, robj *key, robj *o) { int rewriteModuleObject(rio *r, robj *key, robj *o) {
RedisModuleIO io; RedisModuleIO io;
moduleValue *mv = ptrFromObj(o); moduleValue *mv = (moduleValue*)ptrFromObj(o);
moduleType *mt = mv->type; moduleType *mt = mv->type;
moduleInitIOContext(io,mt,r,key); moduleInitIOContext(io,mt,r,key);
mt->aof_rewrite(&io,key,mv->value); mt->aof_rewrite(&io,key,mv->value);
@ -1296,8 +1296,8 @@ int rewriteAppendOnlyFileRio(rio *aof) {
robj key, *o; robj key, *o;
long long expiretime; long long expiretime;
keystr = dictGetKey(de); keystr = (sds)dictGetKey(de);
o = dictGetVal(de); o = (robj*)dictGetVal(de);
initStaticStringObject(key,keystr); initStaticStringObject(key,keystr);
expiretime = getExpire(db,&key); expiretime = getExpire(db,&key);
@ -1360,6 +1360,8 @@ int rewriteAppendOnlyFile(char *filename) {
FILE *fp; FILE *fp;
char tmpfile[256]; char tmpfile[256];
char byte; char byte;
int nodata = 0;
mstime_t start = 0;
/* Note that we have to use a different temp name here compared to the /* Note that we have to use a different temp name here compared to the
* one used by rewriteAppendOnlyFileBackground() function. */ * 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 * 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 * will come. If it looks like we are wasting time, we abort (this
* happens after 20 ms without new data). */ * happens after 20 ms without new data). */
int nodata = 0; start = mstime();
mstime_t start = mstime();
while(mstime()-start < 1000 && nodata < 20) { while(mstime()-start < 1000 && nodata < 20) {
if (aeWait(server.aof_pipe_read_data_from_parent, AE_READABLE, 1) <= 0) if (aeWait(server.aof_pipe_read_data_from_parent, AE_READABLE, 1) <= 0)
{ {

View File

@ -129,7 +129,7 @@ void bioInit(void) {
} }
void bioCreateBackgroundJob(int type, void *arg1, void *arg2, void *arg3) { 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->time = time(NULL);
job->arg1 = arg1; job->arg1 = arg1;
@ -178,7 +178,7 @@ void *bioProcessBackgroundJobs(void *arg) {
} }
/* Pop the job from the queue. */ /* Pop the job from the queue. */
ln = listFirst(bio_jobs[type]); 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 /* It is now possible to unlock the background system as we know have
* a stand alone job structure to process.*/ * a stand alone job structure to process.*/
pthread_mutex_unlock(&bio_mutex[type]); pthread_mutex_unlock(&bio_mutex[type]);
@ -194,11 +194,11 @@ void *bioProcessBackgroundJobs(void *arg) {
* arg2 & arg3 -> free two dictionaries (a Redis DB). * arg2 & arg3 -> free two dictionaries (a Redis DB).
* only arg3 -> free the skiplist. */ * only arg3 -> free the skiplist. */
if (job->arg1) if (job->arg1)
lazyfreeFreeObjectFromBioThread(job->arg1); lazyfreeFreeObjectFromBioThread((robj*)job->arg1);
else if (job->arg2 && job->arg3) else if (job->arg2 && job->arg3)
lazyfreeFreeDatabaseFromBioThread(job->arg2,job->arg3); lazyfreeFreeDatabaseFromBioThread((dict*)job->arg2,(dict*)job->arg3);
else if (job->arg3) else if (job->arg3)
lazyfreeFreeSlotsMapFromBioThread(job->arg3); lazyfreeFreeSlotsMapFromBioThread((rax*)job->arg3);
} else { } else {
serverPanic("Wrong job type in bioProcessBackgroundJobs()."); serverPanic("Wrong job type in bioProcessBackgroundJobs().");
} }

View File

@ -39,7 +39,7 @@
* work with a input string length up to 512 MB. */ * work with a input string length up to 512 MB. */
size_t redisPopcount(void *s, long count) { size_t redisPopcount(void *s, long count) {
size_t bits = 0; size_t bits = 0;
unsigned char *p = s; unsigned char *p = (unsigned char*)s;
uint32_t *p4; 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}; 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. */ * is multiplied by 'bits'. This is useful for the BITFIELD command. */
int getBitOffsetFromArgument(client *c, robj *o, size_t *offset, int hash, int bits) { int getBitOffsetFromArgument(client *c, robj *o, size_t *offset, int hash, int bits) {
long long loffset; long long loffset;
char *err = "bit offset is not an integer or out of range"; const char *err = "bit offset is not an integer or out of range";
char *p = ptrFromObj(o); char *p = szFromObj(o);
size_t plen = sdslen(p); size_t plen = sdslen(p);
int usehash = 0; 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. */ * On error C_ERR is returned and an error is sent to the client. */
int getBitfieldTypeFromArgument(client *c, robj *o, int *sign, int *bits) { int getBitfieldTypeFromArgument(client *c, robj *o, int *sign, int *bits) {
char *p = ptrFromObj(o); char *p = szFromObj(o);
char *err = "Invalid bitfield type. Use something like i16 u8. Note that u64 is not supported but i64 is."; const char *err = "Invalid bitfield type. Use something like i16 u8. Note that u64 is not supported but i64 is.";
long long llbits; long long llbits;
if (p[0] == 'i') { if (p[0] == 'i') {
@ -485,7 +485,7 @@ robj *lookupStringForBitCommand(client *c, size_t maxbit) {
} else { } else {
if (checkType(c,o,OBJ_STRING)) return NULL; if (checkType(c,o,OBJ_STRING)) return NULL;
o = dbUnshareStringValue(c->db,c->argv[1],o); 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; 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)); if (len) *len = ll2string(llbuf,LONG_STR_SIZE,(long)ptrFromObj(o));
} else if (o) { } else if (o) {
p = (unsigned char*) ptrFromObj(o); p = (unsigned char*) ptrFromObj(o);
if (len) *len = sdslen(ptrFromObj(o)); if (len) *len = sdslen(szFromObj(o));
} else { } else {
if (len) *len = 0; if (len) *len = 0;
} }
@ -524,7 +524,7 @@ unsigned char *getObjectReadOnlyString(robj *o, long *len, char *llbuf) {
/* SETBIT key offset bitvalue */ /* SETBIT key offset bitvalue */
void setbitCommand(client *c) { void setbitCommand(client *c) {
robj *o; 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; size_t bitoffset;
ssize_t byte, bit; ssize_t byte, bit;
int byteval, bitval; int byteval, bitval;
@ -577,7 +577,7 @@ void getbitCommand(client *c) {
byte = bitoffset >> 3; byte = bitoffset >> 3;
bit = 7 - (bitoffset & 0x7); bit = 7 - (bitoffset & 0x7);
if (sdsEncodedObject(o)) { if (sdsEncodedObject(o)) {
if (byte < sdslen(ptrFromObj(o))) if (byte < sdslen(szFromObj(o)))
bitval = ((uint8_t*)ptrFromObj(o))[byte] & (1 << bit); bitval = ((uint8_t*)ptrFromObj(o))[byte] & (1 << bit);
} else { } else {
if (byte < (size_t)ll2string(llbuf,sizeof(llbuf),(long)ptrFromObj(o))) 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 */ /* BITOP op_name target_key src_key1 src_key2 src_key3 ... src_keyN */
void bitopCommand(client *c) { void bitopCommand(client *c) {
char *opname = ptrFromObj(c->argv[1]); char *opname = szFromObj(c->argv[1]);
robj *o, *targetkey = c->argv[2]; robj *o, *targetkey = c->argv[2];
unsigned long op, j, numkeys; unsigned long op, j, numkeys;
robj **objects; /* Array of source objects. */ 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. */ /* Lookup keys, and store pointers to the string objects into an array. */
numkeys = c->argc - 3; numkeys = c->argc - 3;
src = zmalloc(sizeof(unsigned char*) * numkeys, MALLOC_LOCAL); src = (unsigned char**)zmalloc(sizeof(unsigned char*) * numkeys, MALLOC_LOCAL);
len = zmalloc(sizeof(long) * numkeys, MALLOC_LOCAL); len = (unsigned long*)zmalloc(sizeof(long) * numkeys, MALLOC_LOCAL);
objects = zmalloc(sizeof(robj*) * numkeys, MALLOC_LOCAL); objects = (robj**)zmalloc(sizeof(robj*) * numkeys, MALLOC_LOCAL);
for (j = 0; j < numkeys; j++) { for (j = 0; j < numkeys; j++) {
o = lookupKeyRead(c->db,c->argv[j+3]); o = lookupKeyRead(c->db,c->argv[j+3]);
/* Handle non-existing keys as empty strings. */ /* Handle non-existing keys as empty strings. */
@ -647,8 +647,8 @@ void bitopCommand(client *c) {
return; return;
} }
objects[j] = getDecodedObject(o); objects[j] = getDecodedObject(o);
src[j] = ptrFromObj(objects[j]); src[j] = (unsigned char*)ptrFromObj(objects[j]);
len[j] = sdslen(ptrFromObj(objects[j])); len[j] = sdslen(szFromObj(objects[j]));
if (len[j] > maxlen) maxlen = len[j]; if (len[j] > maxlen) maxlen = len[j];
if (j == 0 || len[j] < minlen) minlen = 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++) { for (j = 2; j < c->argc; j++) {
int remargs = c->argc-j-1; /* Remaining args other than current. */ 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. */ int opcode; /* Current operation code. */
long long i64 = 0; /* Signed SET value. */ long long i64 = 0; /* Signed SET value. */
int sign = 0; /* Signed or unsigned type? */ int sign = 0; /* Signed or unsigned type? */
@ -935,7 +935,7 @@ void bitfieldCommand(client *c) {
else if (!strcasecmp(subcmd,"incrby") && remargs >= 3) else if (!strcasecmp(subcmd,"incrby") && remargs >= 3)
opcode = BITFIELDOP_INCRBY; opcode = BITFIELDOP_INCRBY;
else if (!strcasecmp(subcmd,"overflow") && remargs >= 1) { else if (!strcasecmp(subcmd,"overflow") && remargs >= 1) {
char *owtypename = ptrFromObj(c->argv[j+1]); char *owtypename = szFromObj(c->argv[j+1]);
j++; j++;
if (!strcasecmp(owtypename,"wrap")) if (!strcasecmp(owtypename,"wrap"))
owtype = BFOVERFLOW_WRAP; owtype = BFOVERFLOW_WRAP;
@ -978,7 +978,7 @@ void bitfieldCommand(client *c) {
} }
/* Populate the array of operations we'll process. */ /* 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].offset = bitoffset;
ops[numops].i64 = i64; ops[numops].i64 = i64;
ops[numops].opcode = opcode; ops[numops].opcode = opcode;
@ -1023,7 +1023,7 @@ void bitfieldCommand(client *c) {
int64_t oldval, newval, wrapped, retval; int64_t oldval, newval, wrapped, retval;
int overflow; int overflow;
oldval = getSignedBitfield(ptrFromObj(o),thisop->offset, oldval = getSignedBitfield((unsigned char*)ptrFromObj(o),thisop->offset,
thisop->bits); thisop->bits);
if (thisop->opcode == BITFIELDOP_INCRBY) { if (thisop->opcode == BITFIELDOP_INCRBY) {
@ -1044,7 +1044,7 @@ void bitfieldCommand(client *c) {
* NULL to signal the condition. */ * NULL to signal the condition. */
if (!(overflow && thisop->owtype == BFOVERFLOW_FAIL)) { if (!(overflow && thisop->owtype == BFOVERFLOW_FAIL)) {
addReplyLongLong(c,retval); addReplyLongLong(c,retval);
setSignedBitfield(ptrFromObj(o),thisop->offset, setSignedBitfield((unsigned char*)ptrFromObj(o),thisop->offset,
thisop->bits,newval); thisop->bits,newval);
} else { } else {
addReplyNull(c); addReplyNull(c);
@ -1053,7 +1053,7 @@ void bitfieldCommand(client *c) {
uint64_t oldval, newval, wrapped, retval; uint64_t oldval, newval, wrapped, retval;
int overflow; int overflow;
oldval = getUnsignedBitfield(ptrFromObj(o),thisop->offset, oldval = getUnsignedBitfield((unsigned char*)ptrFromObj(o),thisop->offset,
thisop->bits); thisop->bits);
if (thisop->opcode == BITFIELDOP_INCRBY) { if (thisop->opcode == BITFIELDOP_INCRBY) {
@ -1073,7 +1073,7 @@ void bitfieldCommand(client *c) {
* NULL to signal the condition. */ * NULL to signal the condition. */
if (!(overflow && thisop->owtype == BFOVERFLOW_FAIL)) { if (!(overflow && thisop->owtype == BFOVERFLOW_FAIL)) {
addReplyLongLong(c,retval); addReplyLongLong(c,retval);
setUnsignedBitfield(ptrFromObj(o),thisop->offset, setUnsignedBitfield((unsigned char*)ptrFromObj(o),thisop->offset,
thisop->bits,newval); thisop->bits,newval);
} else { } else {
addReplyNull(c); addReplyNull(c);

View File

@ -82,7 +82,7 @@ struct redisMaster *getFirstMaster()
serverAssert(listLength(server.masters) <= 1); serverAssert(listLength(server.masters) <= 1);
if (!listLength(server.masters)) if (!listLength(server.masters))
return NULL; 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. */ * To simplify we allocate 1024+CLUSTER_SLOTS*128 bytes per line. */
maxline = 1024+CLUSTER_SLOTS*128; maxline = 1024+CLUSTER_SLOTS*128;
line = zmalloc(maxline, MALLOC_LOCAL); line = (char*)zmalloc(maxline, MALLOC_LOCAL);
while(fgets(line,maxline,fp) != NULL) { while(fgets(line,maxline,fp) != NULL) {
int argc; int argc;
sds *argv; sds *argv;
@ -442,7 +442,7 @@ void clusterInit(void) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
server.cluster = zmalloc(sizeof(clusterState), MALLOC_LOCAL); server.cluster = (clusterState*)zmalloc(sizeof(clusterState), MALLOC_LOCAL);
server.cluster->myself = NULL; server.cluster->myself = NULL;
server.cluster->currentEpoch = 0; server.cluster->currentEpoch = 0;
server.cluster->state = CLUSTER_FAIL; server.cluster->state = CLUSTER_FAIL;
@ -552,7 +552,7 @@ void clusterReset(int hard) {
if (listLength(server.masters) > 0) if (listLength(server.masters) > 0)
{ {
serverAssert(listLength(server.masters) == 1); serverAssert(listLength(server.masters) == 1);
replicationUnsetMaster(listFirst(server.masters)->value); replicationUnsetMaster((redisMaster*)listFirst(server.masters)->value);
} }
emptyDb(-1,EMPTYDB_NO_FLAGS,NULL); emptyDb(-1,EMPTYDB_NO_FLAGS,NULL);
} }
@ -567,7 +567,7 @@ void clusterReset(int hard) {
/* Forget all the nodes, but myself. */ /* Forget all the nodes, but myself. */
di = dictGetSafeIterator(server.cluster->nodes); di = dictGetSafeIterator(server.cluster->nodes);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = (clusterNode*)dictGetVal(de);
if (node == myself) continue; if (node == myself) continue;
clusterDelNode(node); clusterDelNode(node);
@ -604,7 +604,7 @@ void clusterReset(int hard) {
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
clusterLink *createClusterLink(clusterNode *node) { clusterLink *createClusterLink(clusterNode *node) {
clusterLink *link = zmalloc(sizeof(*link), MALLOC_LOCAL); clusterLink *link = (clusterLink*)zmalloc(sizeof(*link), MALLOC_LOCAL);
link->ctime = mstime(); link->ctime = mstime();
link->sndbuf = sdsempty(); link->sndbuf = sdsempty();
link->rcvbuf = 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 * The node is created and returned to the user, but it is not automatically
* added to the nodes hash table. */ * added to the nodes hash table. */
clusterNode *createClusterNode(char *nodename, int flags) { clusterNode *createClusterNode(char *nodename, int flags) {
clusterNode *node = zmalloc(sizeof(*node), MALLOC_LOCAL); clusterNode *node = (clusterNode*)zmalloc(sizeof(*node), MALLOC_LOCAL);
if (nodename) if (nodename)
memcpy(node->name, nodename, CLUSTER_NAMELEN); memcpy(node->name, nodename, CLUSTER_NAMELEN);
@ -758,7 +758,7 @@ int clusterNodeAddFailureReport(clusterNode *failing, clusterNode *sender) {
* the timestamp. */ * the timestamp. */
listRewind(l,&li); listRewind(l,&li);
while ((ln = listNext(&li)) != NULL) { while ((ln = listNext(&li)) != NULL) {
fr = ln->value; fr = (clusterNodeFailReport*)ln->value;
if (fr->node == sender) { if (fr->node == sender) {
fr->time = mstime(); fr->time = mstime();
return 0; return 0;
@ -766,7 +766,7 @@ int clusterNodeAddFailureReport(clusterNode *failing, clusterNode *sender) {
} }
/* Otherwise create a new report. */ /* Otherwise create a new report. */
fr = zmalloc(sizeof(*fr), MALLOC_LOCAL); fr = (clusterNodeFailReport*)zmalloc(sizeof(*fr), MALLOC_LOCAL);
fr->node = sender; fr->node = sender;
fr->time = mstime(); fr->time = mstime();
listAddNodeTail(l,fr); listAddNodeTail(l,fr);
@ -789,7 +789,7 @@ void clusterNodeCleanupFailureReports(clusterNode *node) {
listRewind(l,&li); listRewind(l,&li);
while ((ln = listNext(&li)) != NULL) { while ((ln = listNext(&li)) != NULL) {
fr = ln->value; fr = (clusterNodeFailReport*)ln->value;
if (now - fr->time > maxtime) listDelNode(l,ln); 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. */ /* Search for a failure report from this sender. */
listRewind(l,&li); listRewind(l,&li);
while ((ln = listNext(&li)) != NULL) { while ((ln = listNext(&li)) != NULL) {
fr = ln->value; fr = (clusterNodeFailReport*)ln->value;
if (fr->node == sender) break; if (fr->node == sender) break;
} }
if (!ln) return 0; /* No failure report from this sender. */ 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. */ /* If it's already a slave, don't add it again. */
for (j = 0; j < master->numslaves; j++) for (j = 0; j < master->numslaves; j++)
if (master->slaves[j] == slave) return C_ERR; 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); sizeof(clusterNode*)*(master->numslaves+1), MALLOC_LOCAL);
master->slaves[master->numslaves] = slave; master->slaves[master->numslaves] = slave;
master->numslaves++; master->numslaves++;
@ -937,7 +937,7 @@ void clusterDelNode(clusterNode *delnode) {
/* 2) Remove failure reports. */ /* 2) Remove failure reports. */
di = dictGetSafeIterator(server.cluster->nodes); di = dictGetSafeIterator(server.cluster->nodes);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = (clusterNode*)dictGetVal(de);
if (node == delnode) continue; if (node == delnode) continue;
clusterNodeDelFailureReport(node,delnode); clusterNodeDelFailureReport(node,delnode);
@ -956,7 +956,7 @@ clusterNode *clusterLookupNode(const char *name) {
de = dictFind(server.cluster->nodes,s); de = dictFind(server.cluster->nodes,s);
sdsfree(s); sdsfree(s);
if (de == NULL) return NULL; 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 /* 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); di = dictGetSafeIterator(server.cluster->nodes);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = (clusterNode*)dictGetVal(de);
if (node->configEpoch > max) max = node->configEpoch; if (node->configEpoch > max) max = node->configEpoch;
} }
dictReleaseIterator(di); dictReleaseIterator(di);
@ -1277,7 +1277,7 @@ int clusterHandshakeInProgress(char *ip, int port, int cport) {
di = dictGetSafeIterator(server.cluster->nodes); di = dictGetSafeIterator(server.cluster->nodes);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = (clusterNode*)dictGetVal(de);
if (!nodeInHandshake(node)) continue; if (!nodeInHandshake(node)) continue;
if (!strcasecmp(node->ip,ip) && if (!strcasecmp(node->ip,ip) &&
@ -2253,12 +2253,12 @@ void clusterBroadcastMessage(void *buf, size_t len) {
di = dictGetSafeIterator(server.cluster->nodes); di = dictGetSafeIterator(server.cluster->nodes);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = (clusterNode*)dictGetVal(de);
if (!node->link) continue; if (!node->link) continue;
if (node->flags & (CLUSTER_NODE_MYSELF|CLUSTER_NODE_HANDSHAKE)) if (node->flags & (CLUSTER_NODE_MYSELF|CLUSTER_NODE_HANDSHAKE))
continue; continue;
clusterSendMessage(node->link,buf,len); clusterSendMessage(node->link,(unsigned char*)buf,len);
} }
dictReleaseIterator(di); dictReleaseIterator(di);
} }
@ -2422,7 +2422,7 @@ void clusterSendPing(clusterLink *link, int type) {
/* Note: clusterBuildMessageHdr() expects the buffer to be always at least /* Note: clusterBuildMessageHdr() expects the buffer to be always at least
* sizeof(clusterMsg) or more. */ * sizeof(clusterMsg) or more. */
if (totlen < (int)sizeof(clusterMsg)) totlen = sizeof(clusterMsg); if (totlen < (int)sizeof(clusterMsg)) totlen = sizeof(clusterMsg);
buf = zcalloc(totlen, MALLOC_LOCAL); buf = (unsigned char*)zcalloc(totlen, MALLOC_LOCAL);
hdr = (clusterMsg*) buf; hdr = (clusterMsg*) buf;
/* Populate the header. */ /* Populate the header. */
@ -2434,32 +2434,32 @@ void clusterSendPing(clusterLink *link, int type) {
int maxiterations = wanted*3; int maxiterations = wanted*3;
while(freshnodes > 0 && gossipcount < wanted && maxiterations--) { while(freshnodes > 0 && gossipcount < wanted && maxiterations--) {
dictEntry *de = dictGetRandomKey(server.cluster->nodes); 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 /* Don't include this node: the whole packet header is about us
* already, so we just gossip about other nodes. */ * already, so we just gossip about other nodes. */
if (this == myself) continue; if (thisNode == myself) continue;
/* PFAIL nodes will be added later. */ /* 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: /* In the gossip section don't include:
* 1) Nodes in HANDSHAKE state. * 1) Nodes in HANDSHAKE state.
* 3) Nodes with the NOADDR flag set. * 3) Nodes with the NOADDR flag set.
* 4) Disconnected nodes if they don't have configured slots. * 4) Disconnected nodes if they don't have configured slots.
*/ */
if (this->flags & (CLUSTER_NODE_HANDSHAKE|CLUSTER_NODE_NOADDR) || if (thisNode->flags & (CLUSTER_NODE_HANDSHAKE|CLUSTER_NODE_NOADDR) ||
(this->link == NULL && this->numslots == 0)) (thisNode->link == NULL && thisNode->numslots == 0))
{ {
freshnodes--; /* Tecnically not correct, but saves CPU. */ freshnodes--; /* Tecnically not correct, but saves CPU. */
continue; continue;
} }
/* Do not add a node we already have. */ /* Do not add a node we already have. */
if (clusterNodeIsInGossipSection(hdr,gossipcount,this)) continue; if (clusterNodeIsInGossipSection(hdr,gossipcount,thisNode)) continue;
/* Add it */ /* Add it */
clusterSetGossipEntry(hdr,gossipcount,this); clusterSetGossipEntry(hdr,gossipcount,thisNode);
freshnodes--; freshnodes--;
gossipcount++; gossipcount++;
} }
@ -2471,7 +2471,7 @@ void clusterSendPing(clusterLink *link, int type) {
di = dictGetSafeIterator(server.cluster->nodes); di = dictGetSafeIterator(server.cluster->nodes);
while((de = dictNext(di)) != NULL && pfail_wanted > 0) { 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_HANDSHAKE) continue;
if (node->flags & CLUSTER_NODE_NOADDR) continue; if (node->flags & CLUSTER_NODE_NOADDR) continue;
if (!(node->flags & CLUSTER_NODE_PFAIL)) continue; if (!(node->flags & CLUSTER_NODE_PFAIL)) continue;
@ -2518,7 +2518,7 @@ void clusterBroadcastPong(int target) {
di = dictGetSafeIterator(server.cluster->nodes); di = dictGetSafeIterator(server.cluster->nodes);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = (clusterNode*)dictGetVal(de);
if (!node->link) continue; if (!node->link) continue;
if (node == myself || nodeInHandshake(node)) continue; if (node == myself || nodeInHandshake(node)) continue;
@ -2544,8 +2544,8 @@ void clusterSendPublish(clusterLink *link, robj *channel, robj *message) {
channel = getDecodedObject(channel); channel = getDecodedObject(channel);
message = getDecodedObject(message); message = getDecodedObject(message);
channel_len = sdslen(ptrFromObj(channel)); channel_len = sdslen(szFromObj(channel));
message_len = sdslen(ptrFromObj(message)); message_len = sdslen(szFromObj(message));
clusterBuildMessageHdr(hdr,CLUSTERMSG_TYPE_PUBLISH); clusterBuildMessageHdr(hdr,CLUSTERMSG_TYPE_PUBLISH);
totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData); totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData);
@ -2559,13 +2559,13 @@ void clusterSendPublish(clusterLink *link, robj *channel, robj *message) {
if (totlen < sizeof(buf)) { if (totlen < sizeof(buf)) {
payload = buf; payload = buf;
} else { } else {
payload = zmalloc(totlen, MALLOC_LOCAL); payload = (unsigned char*)zmalloc(totlen, MALLOC_LOCAL);
memcpy(payload,hdr,sizeof(*hdr)); memcpy(payload,hdr,sizeof(*hdr));
hdr = (clusterMsg*) payload; hdr = (clusterMsg*) payload;
} }
memcpy(hdr->data.publish.msg.bulk_data,ptrFromObj(channel),sdslen(ptrFromObj(channel))); memcpy(hdr->data.publish.msg.bulk_data,ptrFromObj(channel),sdslen(szFromObj(channel)));
memcpy(hdr->data.publish.msg.bulk_data+sdslen(ptrFromObj(channel)), memcpy(hdr->data.publish.msg.bulk_data+sdslen(szFromObj(channel)),
ptrFromObj(message),sdslen(ptrFromObj(message))); ptrFromObj(message),sdslen(szFromObj(message)));
if (link) if (link)
clusterSendMessage(link,payload,totlen); clusterSendMessage(link,payload,totlen);
@ -2628,7 +2628,7 @@ void clusterSendModule(clusterLink *link, uint64_t module_id, uint8_t type,
if (totlen < sizeof(buf)) { if (totlen < sizeof(buf)) {
heapbuf = buf; heapbuf = buf;
} else { } else {
heapbuf = zmalloc(totlen, MALLOC_LOCAL); heapbuf = (unsigned char*)zmalloc(totlen, MALLOC_LOCAL);
memcpy(heapbuf,hdr,sizeof(*hdr)); memcpy(heapbuf,hdr,sizeof(*hdr));
hdr = (clusterMsg*) heapbuf; hdr = (clusterMsg*) heapbuf;
} }
@ -2879,7 +2879,7 @@ int clusterGetSlaveRank(void) {
* *
* The function is guaranteed to be called only if 'myself' is a slave. */ * The function is guaranteed to be called only if 'myself' is a slave. */
void clusterLogCantFailover(int reason) { void clusterLogCantFailover(int reason) {
char *msg; const char *msg;
static time_t lastlog_time = 0; static time_t lastlog_time = 0;
mstime_t nolog_fail_time = server.cluster_node_timeout + 5000; mstime_t nolog_fail_time = server.cluster_node_timeout + 5000;
@ -3192,7 +3192,7 @@ void clusterHandleSlaveMigration(int max_slaves) {
candidate = myself; candidate = myself;
di = dictGetSafeIterator(server.cluster->nodes); di = dictGetSafeIterator(server.cluster->nodes);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = (clusterNode*)dictGetVal(de);
int okslaves = 0, is_orphaned = 1; int okslaves = 0, is_orphaned = 1;
/* We want to migrate only if this master is working, orphaned, and /* We want to migrate only if this master is working, orphaned, and
@ -3386,7 +3386,7 @@ void clusterCron(void) {
di = dictGetSafeIterator(server.cluster->nodes); di = dictGetSafeIterator(server.cluster->nodes);
server.cluster->stats_pfail_nodes = 0; server.cluster->stats_pfail_nodes = 0;
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = (clusterNode*)dictGetVal(de);
/* Not interested in reconnecting the link with myself or nodes /* Not interested in reconnecting the link with myself or nodes
* for which we have no address. */ * for which we have no address. */
@ -3463,15 +3463,15 @@ void clusterCron(void) {
* pong_received time. */ * pong_received time. */
for (j = 0; j < 5; j++) { for (j = 0; j < 5; j++) {
de = dictGetRandomKey(server.cluster->nodes); 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. */ /* Don't ping nodes disconnected or with a ping currently active. */
if (this->link == NULL || this->ping_sent != 0) continue; if (thisNode->link == NULL || thisNode->ping_sent != 0) continue;
if (this->flags & (CLUSTER_NODE_MYSELF|CLUSTER_NODE_HANDSHAKE)) if (thisNode->flags & (CLUSTER_NODE_MYSELF|CLUSTER_NODE_HANDSHAKE))
continue; continue;
if (min_pong_node == NULL || min_pong > this->pong_received) { if (min_pong_node == NULL || min_pong > thisNode->pong_received) {
min_pong_node = this; min_pong_node = thisNode;
min_pong = this->pong_received; min_pong = thisNode->pong_received;
} }
} }
if (min_pong_node) { if (min_pong_node) {
@ -3491,7 +3491,7 @@ void clusterCron(void) {
this_slaves = 0; this_slaves = 0;
di = dictGetSafeIterator(server.cluster->nodes); di = dictGetSafeIterator(server.cluster->nodes);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = (clusterNode*)dictGetVal(de);
now = mstime(); /* Use an updated time at every iteration. */ now = mstime(); /* Use an updated time at every iteration. */
mstime_t delay; mstime_t delay;
@ -3672,7 +3672,7 @@ int clusterMastersHaveSlaves(void) {
dictEntry *de; dictEntry *de;
int slaves = 0; int slaves = 0;
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = (clusterNode*)dictGetVal(de);
if (nodeIsSlave(node)) continue; if (nodeIsSlave(node)) continue;
slaves += node->numslaves; slaves += node->numslaves;
@ -3824,7 +3824,7 @@ void clusterUpdateState(void) {
server.cluster->size = 0; server.cluster->size = 0;
di = dictGetSafeIterator(server.cluster->nodes); di = dictGetSafeIterator(server.cluster->nodes);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = (clusterNode*)dictGetVal(de);
if (nodeIsMaster(node) && node->numslots) { if (nodeIsMaster(node) && node->numslots) {
server.cluster->size++; server.cluster->size++;
@ -3974,7 +3974,7 @@ void clusterSetMaster(clusterNode *n) {
struct redisNodeFlags { struct redisNodeFlags {
uint16_t flag; uint16_t flag;
char *name; const char *name;
}; };
static struct redisNodeFlags redisNodeFlagsTable[] = { static struct redisNodeFlags redisNodeFlagsTable[] = {
@ -4091,7 +4091,7 @@ sds clusterGenNodesDescription(int filter) {
di = dictGetSafeIterator(server.cluster->nodes); di = dictGetSafeIterator(server.cluster->nodes);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = (clusterNode*)dictGetVal(de);
if (node->flags & filter) continue; if (node->flags & filter) continue;
ni = clusterGenNodeDescription(node); ni = clusterGenNodeDescription(node);
@ -4153,7 +4153,7 @@ void clusterReplyMultiBulkSlots(client *c) {
dictEntry *de; dictEntry *de;
dictIterator *di = dictGetSafeIterator(server.cluster->nodes); dictIterator *di = dictGetSafeIterator(server.cluster->nodes);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
clusterNode *node = dictGetVal(de); clusterNode *node = (clusterNode*)dictGetVal(de);
int j = 0, start = -1; int j = 0, start = -1;
/* Skip slaves (that are iterated when producing the output of their /* Skip slaves (that are iterated when producing the output of their
@ -4215,7 +4215,7 @@ void clusterCommand(client *c) {
return; return;
} }
if (c->argc == 2 && !strcasecmp(ptrFromObj(c->argv[1]),"help")) { if (c->argc == 2 && !strcasecmp(szFromObj(c->argv[1]),"help")) {
const char *help[] = { const char *help[] = {
"ADDSLOTS <slot> [slot ...] -- Assign slots to current node.", "ADDSLOTS <slot> [slot ...] -- Assign slots to current node.",
"BUMPEPOCH -- Advance the cluster config epoch.", "BUMPEPOCH -- Advance the cluster config epoch.",
@ -4242,7 +4242,7 @@ void clusterCommand(client *c) {
NULL NULL
}; };
addReplyHelp(c, help); 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 <ip> <port> [cport] */ /* CLUSTER MEET <ip> <port> [cport] */
long long port, cport; long long port, cport;
@ -4262,7 +4262,7 @@ NULL
cport = port + CLUSTER_PORT_INCR; 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) errno == EINVAL)
{ {
addReplyErrorFormat(c,"Invalid node address specified: %s:%s", addReplyErrorFormat(c,"Invalid node address specified: %s:%s",
@ -4270,7 +4270,7 @@ NULL
} else { } else {
addReply(c,shared.ok); 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 */ /* CLUSTER NODES */
robj *o; robj *o;
sds ci = clusterGenNodesDescription(0); sds ci = clusterGenNodesDescription(0);
@ -4278,13 +4278,13 @@ NULL
o = createObject(OBJ_STRING,ci); o = createObject(OBJ_STRING,ci);
addReplyBulk(c,o); addReplyBulk(c,o);
decrRefCount(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 */ /* CLUSTER MYID */
addReplyBulkCBuffer(c,myself->name, CLUSTER_NAMELEN); 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 */ /* CLUSTER SLOTS */
clusterReplyMultiBulkSlots(c); 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 */ /* CLUSTER FLUSHSLOTS */
if (dictSize(server.db[0].pdict) != 0) { if (dictSize(server.db[0].pdict) != 0) {
addReplyError(c,"DB must be empty to perform CLUSTER FLUSHSLOTS."); addReplyError(c,"DB must be empty to perform CLUSTER FLUSHSLOTS.");
@ -4293,14 +4293,14 @@ NULL
clusterDelNodeSlots(myself); clusterDelNodeSlots(myself);
clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG);
addReply(c,shared.ok); addReply(c,shared.ok);
} else if ((!strcasecmp(ptrFromObj(c->argv[1]),"addslots") || } else if ((!strcasecmp(szFromObj(c->argv[1]),"addslots") ||
!strcasecmp(ptrFromObj(c->argv[1]),"delslots")) && c->argc >= 3) !strcasecmp(szFromObj(c->argv[1]),"delslots")) && c->argc >= 3)
{ {
/* CLUSTER ADDSLOTS <slot> [slot] ... */ /* CLUSTER ADDSLOTS <slot> [slot] ... */
/* CLUSTER DELSLOTS <slot> [slot] ... */ /* CLUSTER DELSLOTS <slot> [slot] ... */
int j, slot; int j, slot;
unsigned char *slots = zmalloc(CLUSTER_SLOTS, MALLOC_LOCAL); unsigned char *slots = (unsigned char*)zmalloc(CLUSTER_SLOTS, MALLOC_LOCAL);
int del = !strcasecmp(ptrFromObj(c->argv[1]),"delslots"); int del = !strcasecmp(szFromObj(c->argv[1]),"delslots");
memset(slots,0,CLUSTER_SLOTS); memset(slots,0,CLUSTER_SLOTS);
/* Check that all the arguments are parseable and that all the /* Check that all the arguments are parseable and that all the
@ -4343,7 +4343,7 @@ NULL
zfree(slots); zfree(slots);
clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG);
addReply(c,shared.ok); 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 <node ID> */ /* SETSLOT 10 MIGRATING <node ID> */
/* SETSLOT 10 IMPORTING <node ID> */ /* SETSLOT 10 IMPORTING <node ID> */
/* SETSLOT 10 STABLE */ /* SETSLOT 10 STABLE */
@ -4358,36 +4358,36 @@ NULL
if ((slot = getSlotOrReply(c,c->argv[2])) == -1) return; 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) { if (server.cluster->slots[slot] != myself) {
addReplyErrorFormat(c,"I'm not the owner of hash slot %u",slot); addReplyErrorFormat(c,"I'm not the owner of hash slot %u",slot);
return; 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", addReplyErrorFormat(c,"I don't know about node %s",
(char*)ptrFromObj(c->argv[4])); (char*)ptrFromObj(c->argv[4]));
return; return;
} }
server.cluster->migrating_slots_to[slot] = n; 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) { if (server.cluster->slots[slot] == myself) {
addReplyErrorFormat(c, addReplyErrorFormat(c,
"I'm already the owner of hash slot %u",slot); "I'm already the owner of hash slot %u",slot);
return; 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", addReplyErrorFormat(c,"I don't know about node %s",
(char*)ptrFromObj(c->argv[4])); (char*)ptrFromObj(c->argv[4]));
return; return;
} }
server.cluster->importing_slots_from[slot] = n; 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 <SLOT> STABLE */ /* CLUSTER SETSLOT <SLOT> STABLE */
server.cluster->importing_slots_from[slot] = NULL; server.cluster->importing_slots_from[slot] = NULL;
server.cluster->migrating_slots_to[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 <SLOT> NODE <NODE ID> */ /* CLUSTER SETSLOT <SLOT> NODE <NODE ID> */
clusterNode *n = clusterLookupNode(ptrFromObj(c->argv[4])); clusterNode *n = clusterLookupNode(szFromObj(c->argv[4]));
if (!n) { if (!n) {
addReplyErrorFormat(c,"Unknown node %s", addReplyErrorFormat(c,"Unknown node %s",
@ -4440,16 +4440,16 @@ NULL
} }
clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_UPDATE_STATE); clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|CLUSTER_TODO_UPDATE_STATE);
addReply(c,shared.ok); 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 */ /* CLUSTER BUMPEPOCH */
int retval = clusterBumpConfigEpochWithoutConsensus(); int retval = clusterBumpConfigEpochWithoutConsensus();
sds reply = sdscatprintf(sdsempty(),"+%s %llu\r\n", sds reply = sdscatprintf(sdsempty(),"+%s %llu\r\n",
(retval == C_OK) ? "BUMPED" : "STILL", (retval == C_OK) ? "BUMPED" : "STILL",
(unsigned long long) myself->configEpoch); (unsigned long long) myself->configEpoch);
addReplySds(c,reply); 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 */ /* 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; int slots_assigned = 0, slots_ok = 0, slots_pfail = 0, slots_fail = 0;
uint64_t myepoch; uint64_t myepoch;
int j; int j;
@ -4523,7 +4523,7 @@ NULL
(unsigned long)sdslen(info))); (unsigned long)sdslen(info)));
addReplySds(c,info); addReplySds(c,info);
addReply(c,shared.crlf); 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); int retval = clusterSaveConfig(1);
if (retval == 0) if (retval == 0)
@ -4531,12 +4531,12 @@ NULL
else else
addReplyErrorFormat(c,"error saving the cluster node config: %s", addReplyErrorFormat(c,"error saving the cluster node config: %s",
strerror(errno)); 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 <key> */ /* CLUSTER KEYSLOT <key> */
sds key = ptrFromObj(c->argv[2]); sds key = szFromObj(c->argv[2]);
addReplyLongLong(c,keyHashSlot(key,sdslen(key))); 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 <slot> */ /* CLUSTER COUNTKEYSINSLOT <slot> */
long long slot; long long slot;
@ -4547,7 +4547,7 @@ NULL
return; return;
} }
addReplyLongLong(c,countKeysInSlot(slot)); 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 <slot> <count> */ /* CLUSTER GETKEYSINSLOT <slot> <count> */
long long maxkeys, slot; long long maxkeys, slot;
unsigned int numkeys, j; unsigned int numkeys, j;
@ -4568,7 +4568,7 @@ NULL
unsigned int keys_in_slot = countKeysInSlot(slot); unsigned int keys_in_slot = countKeysInSlot(slot);
if (maxkeys > keys_in_slot) maxkeys = keys_in_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); numkeys = getKeysInSlot(slot, keys, maxkeys);
addReplyArrayLen(c,numkeys); addReplyArrayLen(c,numkeys);
for (j = 0; j < numkeys; j++) { for (j = 0; j < numkeys; j++) {
@ -4576,9 +4576,9 @@ NULL
decrRefCount(keys[j]); decrRefCount(keys[j]);
} }
zfree(keys); 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 <NODE ID> */ /* CLUSTER FORGET <NODE ID> */
clusterNode *n = clusterLookupNode(ptrFromObj(c->argv[2])); clusterNode *n = clusterLookupNode(szFromObj(c->argv[2]));
if (!n) { if (!n) {
addReplyErrorFormat(c,"Unknown node %s", (char*)ptrFromObj(c->argv[2])); addReplyErrorFormat(c,"Unknown node %s", (char*)ptrFromObj(c->argv[2]));
@ -4595,9 +4595,9 @@ NULL
clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE| clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|
CLUSTER_TODO_SAVE_CONFIG); CLUSTER_TODO_SAVE_CONFIG);
addReply(c,shared.ok); 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 <NODE ID> */ /* CLUSTER REPLICATE <NODE ID> */
clusterNode *n = clusterLookupNode(ptrFromObj(c->argv[2])); clusterNode *n = clusterLookupNode(szFromObj(c->argv[2]));
/* Lookup the specified node in our table. */ /* Lookup the specified node in our table. */
if (!n) { if (!n) {
@ -4632,10 +4632,10 @@ NULL
clusterSetMaster(n); clusterSetMaster(n);
clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG); clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG);
addReply(c,shared.ok); addReply(c,shared.ok);
} else if ((!strcasecmp(ptrFromObj(c->argv[1]),"slaves") || } else if ((!strcasecmp(szFromObj(c->argv[1]),"slaves") ||
!strcasecmp(ptrFromObj(c->argv[1]),"replicas")) && c->argc == 3) { !strcasecmp(szFromObj(c->argv[1]),"replicas")) && c->argc == 3) {
/* CLUSTER SLAVES <NODE ID> */ /* CLUSTER SLAVES <NODE ID> */
clusterNode *n = clusterLookupNode(ptrFromObj(c->argv[2])); clusterNode *n = clusterLookupNode(szFromObj(c->argv[2]));
int j; int j;
/* Lookup the specified node in our table. */ /* Lookup the specified node in our table. */
@ -4655,11 +4655,11 @@ NULL
addReplyBulkCString(c,ni); addReplyBulkCString(c,ni);
sdsfree(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) c->argc == 3)
{ {
/* CLUSTER COUNT-FAILURE-REPORTS <NODE ID> */ /* CLUSTER COUNT-FAILURE-REPORTS <NODE ID> */
clusterNode *n = clusterLookupNode(ptrFromObj(c->argv[2])); clusterNode *n = clusterLookupNode(szFromObj(c->argv[2]));
if (!n) { if (!n) {
addReplyErrorFormat(c,"Unknown node %s", (char*)ptrFromObj(c->argv[2])); addReplyErrorFormat(c,"Unknown node %s", (char*)ptrFromObj(c->argv[2]));
@ -4667,16 +4667,16 @@ NULL
} else { } else {
addReplyLongLong(c,clusterNodeFailureReportsCount(n)); 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)) (c->argc == 2 || c->argc == 3))
{ {
/* CLUSTER FAILOVER [FORCE|TAKEOVER] */ /* CLUSTER FAILOVER [FORCE|TAKEOVER] */
int force = 0, takeover = 0; int force = 0, takeover = 0;
if (c->argc == 3) { if (c->argc == 3) {
if (!strcasecmp(ptrFromObj(c->argv[2]),"force")) { if (!strcasecmp(szFromObj(c->argv[2]),"force")) {
force = 1; force = 1;
} else if (!strcasecmp(ptrFromObj(c->argv[2]),"takeover")) { } else if (!strcasecmp(szFromObj(c->argv[2]),"takeover")) {
takeover = 1; takeover = 1;
force = 1; /* Takeover also implies force. */ force = 1; /* Takeover also implies force. */
} else { } else {
@ -4722,7 +4722,7 @@ NULL
clusterSendMFStart(myself->slaveof); clusterSendMFStart(myself->slaveof);
} }
addReply(c,shared.ok); 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 <epoch> /* CLUSTER SET-CONFIG-EPOCH <epoch>
* *
@ -4758,7 +4758,7 @@ NULL
CLUSTER_TODO_SAVE_CONFIG); CLUSTER_TODO_SAVE_CONFIG);
addReply(c,shared.ok); 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)) (c->argc == 2 || c->argc == 3))
{ {
/* CLUSTER RESET [SOFT|HARD] */ /* CLUSTER RESET [SOFT|HARD] */
@ -4766,9 +4766,9 @@ NULL
/* Parse soft/hard argument. Default is soft. */ /* Parse soft/hard argument. Default is soft. */
if (c->argc == 3) { if (c->argc == 3) {
if (!strcasecmp(ptrFromObj(c->argv[2]),"hard")) { if (!strcasecmp(szFromObj(c->argv[2]),"hard")) {
hard = 1; hard = 1;
} else if (!strcasecmp(ptrFromObj(c->argv[2]),"soft")) { } else if (!strcasecmp(szFromObj(c->argv[2]),"soft")) {
hard = 0; hard = 0;
} else { } else {
addReply(c,shared.syntaxerr); addReply(c,shared.syntaxerr);
@ -4882,11 +4882,11 @@ void restoreCommand(client *c) {
/* Parse additional options */ /* Parse additional options */
for (j = 4; j < c->argc; j++) { for (j = 4; j < c->argc; j++) {
int additional = c->argc-j-1; int additional = c->argc-j-1;
if (!strcasecmp(ptrFromObj(c->argv[j]),"replace")) { if (!strcasecmp(szFromObj(c->argv[j]),"replace")) {
replace = 1; replace = 1;
} else if (!strcasecmp(ptrFromObj(c->argv[j]),"absttl")) { } else if (!strcasecmp(szFromObj(c->argv[j]),"absttl")) {
absttl = 1; 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) lfu_freq == -1)
{ {
if (getLongLongFromObjectOrReply(c,c->argv[j+1],&lru_idle,NULL) if (getLongLongFromObjectOrReply(c,c->argv[j+1],&lru_idle,NULL)
@ -4897,7 +4897,7 @@ void restoreCommand(client *c) {
} }
lru_clock = LRU_CLOCK(); lru_clock = LRU_CLOCK();
j++; /* Consume additional arg. */ 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) lru_idle == -1)
{ {
if (getLongLongFromObjectOrReply(c,c->argv[j+1],&lfu_freq,NULL) if (getLongLongFromObjectOrReply(c,c->argv[j+1],&lfu_freq,NULL)
@ -4928,13 +4928,13 @@ void restoreCommand(client *c) {
} }
/* Verify RDB version and data checksum. */ /* 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"); addReplyError(c,"DUMP payload version or checksum are wrong");
return; return;
} }
rioInitWithBuffer(&payload,ptrFromObj(c->argv[3])); rioInitWithBuffer(&payload,szFromObj(c->argv[3]));
if (((type = rdbLoadObjectType(&payload)) == -1) || if (((type = rdbLoadObjectType(&payload)) == -1) ||
((obj = rdbLoadObject(type,&payload,c->argv[1])) == NULL)) ((obj = rdbLoadObject(type,&payload,c->argv[1])) == NULL))
{ {
@ -4989,10 +4989,10 @@ migrateCachedSocket* migrateGetSocket(client *c, robj *host, robj *port, long ti
migrateCachedSocket *cs; migrateCachedSocket *cs;
/* Check if we have an already cached socket for this ip:port pair. */ /* 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,":",1);
name = sdscatlen(name,ptrFromObj(port),sdslen(ptrFromObj(port))); name = sdscatlen(name,ptrFromObj(port),sdslen(szFromObj(port)));
cs = dictFetchValue(server.migrate_cached_sockets,name); cs = (migrateCachedSocket*)dictFetchValue(server.migrate_cached_sockets,name);
if (cs) { if (cs) {
sdsfree(name); sdsfree(name);
cs->last_use_time = server.unixtime; 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) { if (dictSize(server.migrate_cached_sockets) == MIGRATE_SOCKET_CACHE_ITEMS) {
/* Too many items, drop one at random. */ /* Too many items, drop one at random. */
dictEntry *de = dictGetRandomKey(server.migrate_cached_sockets); dictEntry *de = dictGetRandomKey(server.migrate_cached_sockets);
cs = dictGetVal(de); cs = (migrateCachedSocket*)dictGetVal(de);
close(cs->fd); close(cs->fd);
zfree(cs); zfree(cs);
dictDelete(server.migrate_cached_sockets,dictGetKey(de)); dictDelete(server.migrate_cached_sockets,dictGetKey(de));
} }
/* Create the socket */ /* Create the socket */
fd = anetTcpNonBlockConnect(server.neterr,ptrFromObj(c->argv[1]), fd = anetTcpNonBlockConnect(server.neterr,szFromObj(c->argv[1]),
atoi(ptrFromObj(c->argv[2]))); atoi(szFromObj(c->argv[2])));
if (fd == -1) { if (fd == -1) {
sdsfree(name); sdsfree(name);
addReplyErrorFormat(c,"Can't connect to target node: %s", 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. */ /* 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->fd = fd;
cs->last_dbid = -1; cs->last_dbid = -1;
cs->last_use_time = server.unixtime; cs->last_use_time = server.unixtime;
@ -5043,10 +5043,10 @@ void migrateCloseSocket(robj *host, robj *port) {
sds name = sdsempty(); sds name = sdsempty();
migrateCachedSocket *cs; 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,":",1);
name = sdscatlen(name,ptrFromObj(port),sdslen(ptrFromObj(port))); name = sdscatlen(name,ptrFromObj(port),sdslen(szFromObj(port)));
cs = dictFetchValue(server.migrate_cached_sockets,name); cs = (migrateCachedSocket*)dictFetchValue(server.migrate_cached_sockets,name);
if (!cs) { if (!cs) {
sdsfree(name); sdsfree(name);
return; return;
@ -5063,7 +5063,7 @@ void migrateCloseTimedoutSockets(void) {
dictEntry *de; dictEntry *de;
while((de = dictNext(di)) != NULL) { 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) { if ((server.unixtime - cs->last_use_time) > MIGRATE_SOCKET_CACHE_TTL) {
close(cs->fd); close(cs->fd);
@ -5101,19 +5101,19 @@ void migrateCommand(client *c) {
/* Parse additional options */ /* Parse additional options */
for (j = 6; j < c->argc; j++) { for (j = 6; j < c->argc; j++) {
int moreargs = j < c->argc-1; int moreargs = j < c->argc-1;
if (!strcasecmp(ptrFromObj(c->argv[j]),"copy")) { if (!strcasecmp(szFromObj(c->argv[j]),"copy")) {
copy = 1; copy = 1;
} else if (!strcasecmp(ptrFromObj(c->argv[j]),"replace")) { } else if (!strcasecmp(szFromObj(c->argv[j]),"replace")) {
replace = 1; replace = 1;
} else if (!strcasecmp(ptrFromObj(c->argv[j]),"auth")) { } else if (!strcasecmp(szFromObj(c->argv[j]),"auth")) {
if (!moreargs) { if (!moreargs) {
addReply(c,shared.syntaxerr); addReply(c,shared.syntaxerr);
return; return;
} }
j++; j++;
password = ptrFromObj(c->argv[j]); password = szFromObj(c->argv[j]);
} else if (!strcasecmp(ptrFromObj(c->argv[j]),"keys")) { } else if (!strcasecmp(szFromObj(c->argv[j]),"keys")) {
if (sdslen(ptrFromObj(c->argv[3])) != 0) { if (sdslen(szFromObj(c->argv[3])) != 0) {
addReplyError(c, addReplyError(c,
"When using MIGRATE KEYS option, the key argument" "When using MIGRATE KEYS option, the key argument"
" must be set to the empty string"); " 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 * 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 * this case, since often this is due to a normal condition like the key
* expiring in the meantime. */ * expiring in the meantime. */
ov = zrealloc(ov,sizeof(robj*)*num_keys, MALLOC_LOCAL); ov = (robj**)zrealloc(ov,sizeof(robj*)*num_keys, MALLOC_LOCAL);
kv = zrealloc(kv,sizeof(robj*)*num_keys, MALLOC_LOCAL); kv = (robj**)zrealloc(kv,sizeof(robj*)*num_keys, MALLOC_LOCAL);
int oi = 0; int oi = 0;
for (j = 0; j < num_keys; j++) { for (j = 0; j < num_keys; j++) {
@ -5218,8 +5218,8 @@ try_again:
else else
serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"RESTORE",7)); serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"RESTORE",7));
serverAssertWithInfo(c,NULL,sdsEncodedObject(kv[j])); serverAssertWithInfo(c,NULL,sdsEncodedObject(kv[j]));
serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,ptrFromObj(kv[j]), serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,szFromObj(kv[j]),
sdslen(ptrFromObj(kv[j])))); sdslen(szFromObj(kv[j]))));
serverAssertWithInfo(c,NULL,rioWriteBulkLongLong(&cmd,ttl)); serverAssertWithInfo(c,NULL,rioWriteBulkLongLong(&cmd,ttl));
/* Emit the payload argument, that is the serialized object using /* 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. */ /* Fix the actual number of keys we are migrating. */
num_keys = non_expired; 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. */ /* Transfer the query to the other node in 64K chunks. */
errno = 0; 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. */ /* Read the AUTH reply if needed. */
if (password && syncReadLine(cs->fd, buf0, sizeof(buf0), timeout) <= 0) 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) if (select && syncReadLine(cs->fd, buf1, sizeof(buf1), timeout) <= 0)
goto socket_err; 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, /* 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). * 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" * We allocate num_keys+1 because the additional argument is for "DEL"
* command name itself. */ * 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++) { for (j = 0; j < num_keys; j++) {
if (syncReadLine(cs->fd, buf2, sizeof(buf2), timeout) <= 0) { if (syncReadLine(cs->fd, buf2, sizeof(buf2), timeout) <= 0) {
socket_error = 1; socket_error = 1;
@ -5531,7 +5531,7 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in
for (j = 0; j < numkeys; j++) { for (j = 0; j < numkeys; j++) {
robj *thiskey = margv[keyindex[j]]; robj *thiskey = margv[keyindex[j]];
int thisslot = keyHashSlot((char*)ptrFromObj(thiskey), int thisslot = keyHashSlot((char*)ptrFromObj(thiskey),
sdslen(ptrFromObj(thiskey))); sdslen(szFromObj(thiskey)));
if (firstkey == NULL) { if (firstkey == NULL) {
/* This is the first key we see. Check what is the slot /* 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. */ /* All keys must belong to the same slot, so check first key only. */
di = dictGetIterator(c->bpop.keys); di = dictGetIterator(c->bpop.keys);
if ((de = dictNext(di)) != NULL) { if ((de = dictNext(di)) != NULL) {
robj *key = dictGetKey(de); robj *key = (robj*)dictGetKey(de);
int slot = keyHashSlot((char*)ptrFromObj(key), sdslen(ptrFromObj(key))); int slot = keyHashSlot((char*)ptrFromObj(key), sdslen(szFromObj(key)));
clusterNode *node = server.cluster->slots[slot]; clusterNode *node = server.cluster->slots[slot];
/* We send an error and unblock the client if: /* We send an error and unblock the client if:

View File

@ -143,7 +143,7 @@ int yesnotoi(char *s) {
} }
void appendServerSaveParams(time_t seconds, int changes) { 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].seconds = seconds;
server.saveparams[server.saveparamslen].changes = changes; server.saveparams[server.saveparamslen].changes = changes;
server.saveparamslen++; server.saveparamslen++;
@ -159,8 +159,8 @@ void queueLoadModule(sds path, sds *argv, int argc) {
int i; int i;
struct moduleLoadQueueEntry *loadmod; struct moduleLoadQueueEntry *loadmod;
loadmod = zmalloc(sizeof(struct moduleLoadQueueEntry), MALLOC_LOCAL); loadmod = (moduleLoadQueueEntry*)zmalloc(sizeof(struct moduleLoadQueueEntry), MALLOC_LOCAL);
loadmod->argv = zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL); loadmod->argv = (robj**)zmalloc(sizeof(robj*)*argc, MALLOC_LOCAL);
loadmod->path = sdsnew(path); loadmod->path = sdsnew(path);
loadmod->argc = argc; loadmod->argc = argc;
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
@ -170,7 +170,7 @@ void queueLoadModule(sds path, sds *argv, int argc) {
} }
void loadServerConfigFromString(char *config) { void loadServerConfigFromString(char *config) {
char *err = NULL; const char *err = NULL;
int linenum = 0, totlines, i; int linenum = 0, totlines, i;
int slaveof_linenum = 0; int slaveof_linenum = 0;
sds *lines; sds *lines;
@ -216,10 +216,6 @@ void loadServerConfigFromString(char *config) {
if ((server.protected_mode = yesnotoi(argv[1])) == -1) { if ((server.protected_mode = yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr; 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) { } else if (!strcasecmp(argv[0],"port") && argc == 2) {
server.port = atoi(argv[1]); server.port = atoi(argv[1]);
if (server.port < 0 || server.port > 65535) { if (server.port < 0 || server.port > 65535) {
@ -729,11 +725,11 @@ void loadServerConfigFromString(char *config) {
} else if (!strcasecmp(argv[0],"client-output-buffer-limit") && } else if (!strcasecmp(argv[0],"client-output-buffer-limit") &&
argc == 5) argc == 5)
{ {
int class = getClientTypeByName(argv[1]); int type = getClientTypeByName(argv[1]);
unsigned long long hard, soft; unsigned long long hard, soft;
int soft_seconds; 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 " err = "Unrecognized client limit class: the user specified "
"an invalid one, or 'master' which has no buffer limits."; "an invalid one, or 'master' which has no buffer limits.";
goto loaderr; goto loaderr;
@ -745,9 +741,9 @@ void loadServerConfigFromString(char *config) {
err = "Negative number of seconds in soft limit is invalid"; err = "Negative number of seconds in soft limit is invalid";
goto loaderr; goto loaderr;
} }
server.client_obuf_limits[class].hard_limit_bytes = hard; server.client_obuf_limits[type].hard_limit_bytes = hard;
server.client_obuf_limits[class].soft_limit_bytes = soft; server.client_obuf_limits[type].soft_limit_bytes = soft;
server.client_obuf_limits[class].soft_limit_seconds = soft_seconds; server.client_obuf_limits[type].soft_limit_seconds = soft_seconds;
} else if (!strcasecmp(argv[0],"stop-writes-on-bgsave-error") && } else if (!strcasecmp(argv[0],"stop-writes-on-bgsave-error") &&
argc == 2) { argc == 2) {
if ((server.stop_writes_on_bgsave_err = yesnotoi(argv[1])) == -1) { if ((server.stop_writes_on_bgsave_err = yesnotoi(argv[1])) == -1) {
@ -806,7 +802,7 @@ void loadServerConfigFromString(char *config) {
int argc_err; int argc_err;
if (ACLAppendUserForLoading(argv,argc,&argc_err) == C_ERR) { if (ACLAppendUserForLoading(argv,argc,&argc_err) == C_ERR) {
char buf[1024]; char buf[1024];
char *errmsg = ACLSetUserStringError(); const char *errmsg = ACLSetUserStringError();
snprintf(buf,sizeof(buf),"Error in user declaration '%s': %s", snprintf(buf,sizeof(buf),"Error in user declaration '%s': %s",
argv[argc_err],errmsg); argv[argc_err],errmsg);
err = buf; err = buf;
@ -928,36 +924,36 @@ void loadServerConfig(char *filename, char *options) {
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#define config_set_bool_field(_name,_var) \ #define config_set_bool_field(_name,_var) \
} else if (!strcasecmp(ptrFromObj(c->argv[2]),_name)) { \ } else if (!strcasecmp(szFromObj(c->argv[2]),_name)) { \
int yn = yesnotoi(ptrFromObj(o)); \ int yn = yesnotoi(szFromObj(o)); \
if (yn == -1) goto badfmt; \ if (yn == -1) goto badfmt; \
_var = yn; _var = yn;
#define config_set_numerical_field(_name,_var,min,max) \ #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 (getLongLongFromObject(o,&ll) == C_ERR) goto badfmt; \
if (min != LLONG_MIN && ll < min) goto badfmt; \ if (min != LLONG_MIN && ll < min) goto badfmt; \
if (max != LLONG_MAX && ll > max) goto badfmt; \ if (max != LLONG_MAX && ll > max) goto badfmt; \
_var = ll; _var = ll;
#define config_set_memory_field(_name,_var) \ #define config_set_memory_field(_name,_var) \
} else if (!strcasecmp(ptrFromObj(c->argv[2]),_name)) { \ } else if (!strcasecmp(szFromObj(c->argv[2]),_name)) { \
ll = memtoll(ptrFromObj(o),&err); \ ll = memtoll(szFromObj(o),&err); \
if (err || ll < 0) goto badfmt; \ if (err || ll < 0) goto badfmt; \
_var = ll; _var = ll;
#define config_set_enum_field(_name,_var,_enumvar) \ #define config_set_enum_field(_name,_var,_enumvar) \
} else if (!strcasecmp(ptrFromObj(c->argv[2]),_name)) { \ } else if (!strcasecmp(szFromObj(c->argv[2]),_name)) { \
int enumval = configEnumGetValue(_enumvar,ptrFromObj(o)); \ int enumval = configEnumGetValue(_enumvar,szFromObj(o)); \
if (enumval == INT_MIN) goto badfmt; \ if (enumval == INT_MIN) goto badfmt; \
_var = enumval; _var = enumval;
#define config_set_special_field(_name) \ #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) \ #define config_set_special_field_with_alias(_name1,_name2) \
} else if (!strcasecmp(ptrFromObj(c->argv[2]),_name1) || \ } else if (!strcasecmp(szFromObj(c->argv[2]),_name1) || \
!strcasecmp(ptrFromObj(c->argv[2]),_name2)) { !strcasecmp(szFromObj(c->argv[2]),_name2)) {
#define config_set_else } else #define config_set_else } else
@ -973,14 +969,14 @@ void configSetCommand(client *c) {
/* Special fields that can't be handled with general macros. */ /* Special fields that can't be handled with general macros. */
config_set_special_field("dbfilename") { config_set_special_field("dbfilename") {
if (!pathIsBaseName(ptrFromObj(o))) { if (!pathIsBaseName(szFromObj(o))) {
addReplyError(c, "dbfilename can't be a path, just a filename"); addReplyError(c, "dbfilename can't be a path, just a filename");
return; return;
} }
zfree(server.rdb_filename); zfree(server.rdb_filename);
server.rdb_filename = zstrdup(ptrFromObj(o)); server.rdb_filename = zstrdup(szFromObj(o));
} config_set_special_field("requirepass") { } 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 /* The old "requirepass" directive just translates to setting
* a password to the default user. */ * a password to the default user. */
ACLSetUser(DefaultUser,"resetpass",-1); ACLSetUser(DefaultUser,"resetpass",-1);
@ -989,13 +985,13 @@ void configSetCommand(client *c) {
sdsfree(aclop); sdsfree(aclop);
} config_set_special_field("masteruser") { } config_set_special_field("masteruser") {
zfree(server.default_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") { } config_set_special_field("masterauth") {
zfree(server.default_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") { } config_set_special_field("cluster-announce-ip") {
zfree(server.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") { } config_set_special_field("maxclients") {
int orig_value = server.maxclients; int orig_value = server.maxclients;
@ -1027,7 +1023,7 @@ void configSetCommand(client *c) {
} }
} }
} config_set_special_field("appendonly") { } config_set_special_field("appendonly") {
int enable = yesnotoi(ptrFromObj(o)); int enable = yesnotoi(szFromObj(o));
if (enable == -1) goto badfmt; if (enable == -1) goto badfmt;
if (enable == 0 && server.aof_state != AOF_OFF) { if (enable == 0 && server.aof_state != AOF_OFF) {
@ -1041,7 +1037,7 @@ void configSetCommand(client *c) {
} }
} config_set_special_field("save") { } config_set_special_field("save") {
int vlen, j; 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: /* Perform sanity check before setting the new config:
* - Even number of args * - Even number of args
@ -1080,7 +1076,7 @@ void configSetCommand(client *c) {
} }
} config_set_special_field("client-output-buffer-limit") { } config_set_special_field("client-output-buffer-limit") {
int vlen, j; 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: <class> <hard> <soft> <soft_seconds> */ /* We need a multiple of 4: <class> <hard> <soft> <soft_seconds> */
if (vlen % 4) { if (vlen % 4) {
@ -1095,8 +1091,8 @@ void configSetCommand(client *c) {
long val; long val;
if ((j % 4) == 0) { if ((j % 4) == 0) {
int class = getClientTypeByName(v[j]); int type = getClientTypeByName(v[j]);
if (class == -1 || class == CLIENT_TYPE_MASTER) { if (type == -1 || type == CLIENT_TYPE_MASTER) {
sdsfreesplitres(v,vlen); sdsfreesplitres(v,vlen);
goto badfmt; goto badfmt;
} }
@ -1110,22 +1106,21 @@ void configSetCommand(client *c) {
} }
/* Finally set the new config */ /* Finally set the new config */
for (j = 0; j < vlen; j += 4) { for (j = 0; j < vlen; j += 4) {
int class;
unsigned long long hard, soft; unsigned long long hard, soft;
int soft_seconds; int soft_seconds;
class = getClientTypeByName(v[j]); int type = getClientTypeByName(v[j]);
hard = memtoll(v[j+1],NULL); hard = memtoll(v[j+1],NULL);
soft = memtoll(v[j+2],NULL); soft = memtoll(v[j+2],NULL);
soft_seconds = strtoll(v[j+3],NULL,10); soft_seconds = strtoll(v[j+3],NULL,10);
server.client_obuf_limits[class].hard_limit_bytes = hard; server.client_obuf_limits[type].hard_limit_bytes = hard;
server.client_obuf_limits[class].soft_limit_bytes = soft; server.client_obuf_limits[type].soft_limit_bytes = soft;
server.client_obuf_limits[class].soft_limit_seconds = soft_seconds; server.client_obuf_limits[type].soft_limit_seconds = soft_seconds;
} }
sdsfreesplitres(v,vlen); sdsfreesplitres(v,vlen);
} config_set_special_field("notify-keyspace-events") { } config_set_special_field("notify-keyspace-events") {
int flags = keyspaceEventsStringToFlags(ptrFromObj(o)); int flags = keyspaceEventsStringToFlags(szFromObj(o));
if (flags == -1) goto badfmt; if (flags == -1) goto badfmt;
server.notify_keyspace_events = flags; server.notify_keyspace_events = flags;
@ -1133,7 +1128,7 @@ void configSetCommand(client *c) {
"replica-announce-ip") "replica-announce-ip")
{ {
zfree(server.slave_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. /* Boolean fields.
* config_set_bool_field(name,var). */ * config_set_bool_field(name,var). */
@ -1186,8 +1181,6 @@ void configSetCommand(client *c) {
#endif #endif
} config_set_bool_field( } config_set_bool_field(
"protected-mode",server.protected_mode) { "protected-mode",server.protected_mode) {
} config_set_bool_field(
"gopher-enabled",server.gopher_enabled) {
} config_set_bool_field( } config_set_bool_field(
"stop-writes-on-bgsave-error",server.stop_writes_on_bgsave_err) { "stop-writes-on-bgsave-error",server.stop_writes_on_bgsave_err) {
} config_set_bool_field( } config_set_bool_field(
@ -1402,7 +1395,7 @@ badfmt: /* Bad format errors */
void configGetCommand(client *c) { void configGetCommand(client *c) {
robj *o = c->argv[2]; robj *o = c->argv[2];
void *replylen = addReplyDeferredLen(c); void *replylen = addReplyDeferredLen(c);
char *pattern = ptrFromObj(o); char *pattern = szFromObj(o);
char buf[128]; char buf[128];
int matches = 0; int matches = 0;
serverAssertWithInfo(c,o,sdsEncodedObject(o)); serverAssertWithInfo(c,o,sdsEncodedObject(o));
@ -1521,7 +1514,6 @@ void configGetCommand(client *c) {
config_get_bool_field("activerehashing", server.activerehashing); config_get_bool_field("activerehashing", server.activerehashing);
config_get_bool_field("activedefrag", server.active_defrag_enabled); config_get_bool_field("activedefrag", server.active_defrag_enabled);
config_get_bool_field("protected-mode", server.protected_mode); 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", config_get_bool_field("repl-disable-tcp-nodelay",
server.repl_disable_tcp_nodelay); server.repl_disable_tcp_nodelay);
config_get_bool_field("repl-diskless-sync", config_get_bool_field("repl-diskless-sync",
@ -1620,7 +1612,7 @@ void configGetCommand(client *c) {
if (stringmatch(pattern,"slaveof",1) || if (stringmatch(pattern,"slaveof",1) ||
stringmatch(pattern,"replicaof",1)) stringmatch(pattern,"replicaof",1))
{ {
char *optname = stringmatch(pattern,"slaveof",1) ? const char *optname = stringmatch(pattern,"slaveof",1) ?
"slaveof" : "replicaof"; "slaveof" : "replicaof";
char buf[256]; char buf[256];
addReplyBulkCString(c,optname); addReplyBulkCString(c,optname);
@ -1722,13 +1714,13 @@ struct rewriteConfigState {
/* Append the new line to the current configuration state. */ /* Append the new line to the current configuration state. */
void rewriteConfigAppendLine(struct rewriteConfigState *state, sds line) { 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; state->lines[state->numlines++] = line;
} }
/* Populate the option -> list of line numbers map. */ /* Populate the option -> list of line numbers map. */
void rewriteConfigAddLineNumberToOption(struct rewriteConfigState *state, sds option, int linenum) { 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) { if (l == NULL) {
l = listCreate(); 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. */ * If the old file does not exist at all, an empty state is returned. */
struct rewriteConfigState *rewriteConfigReadOldFile(char *path) { struct rewriteConfigState *rewriteConfigReadOldFile(char *path) {
FILE *fp = fopen(path,"r"); 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]; char buf[CONFIG_MAX_LINE+1];
int linenum = -1; int linenum = -1;
@ -1839,7 +1831,7 @@ struct rewriteConfigState *rewriteConfigReadOldFile(char *path) {
* in any way. */ * in any way. */
void rewriteConfigRewriteLine(struct rewriteConfigState *state, const char *option, sds line, int force) { void rewriteConfigRewriteLine(struct rewriteConfigState *state, const char *option, sds line, int force) {
sds o = sdsnew(option); sds o = sdsnew(option);
list *l = dictFetchValue(state->option_to_line,o); list *l = (list*)dictFetchValue(state->option_to_line,o);
rewriteConfigMarkAsProcessed(state,option); rewriteConfigMarkAsProcessed(state,option);
@ -1891,7 +1883,7 @@ int rewriteConfigFormatMemory(char *buf, size_t len, long long bytes) {
} }
/* Rewrite a simple "option-name <bytes>" configuration option. */ /* Rewrite a simple "option-name <bytes>" 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]; char buf[64];
int force = value != defvalue; int force = value != defvalue;
sds line; sds line;
@ -1902,7 +1894,7 @@ void rewriteConfigBytesOption(struct rewriteConfigState *state, char *option, lo
} }
/* Rewrite a yes/no option. */ /* 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; int force = value != defvalue;
sds line = sdscatprintf(sdsempty(),"%s %s",option, sds line = sdscatprintf(sdsempty(),"%s %s",option,
value ? "yes" : "no"); value ? "yes" : "no");
@ -1911,7 +1903,7 @@ void rewriteConfigYesNoOption(struct rewriteConfigState *state, char *option, in
} }
/* Rewrite a string option. */ /* 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; int force = 1;
sds line; sds line;
@ -1933,7 +1925,7 @@ void rewriteConfigStringOption(struct rewriteConfigState *state, char *option, c
} }
/* Rewrite a numerical (long long range) option. */ /* 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; int force = value != defvalue;
sds line = sdscatprintf(sdsempty(),"%s %lld",option,value); sds line = sdscatprintf(sdsempty(),"%s %lld",option,value);
@ -1941,7 +1933,7 @@ void rewriteConfigNumericalOption(struct rewriteConfigState *state, char *option
} }
/* Rewrite a octal 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; int force = value != defvalue;
sds line = sdscatprintf(sdsempty(),"%s %o",option,value); 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, /* Rewrite an enumeration option. It takes as usually state and option name,
* and in addition the enumeration array and the default value for the * and in addition the enumeration array and the default value for the
* option. */ * 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; sds line;
const char *name = configEnumGetNameOrUnknown(ce,value); const char *name = configEnumGetNameOrUnknown(ce,value);
int force = value != defval; int force = value != defval;
@ -2006,7 +1998,7 @@ void rewriteConfigUserOption(struct rewriteConfigState *state) {
raxStart(&ri,Users); raxStart(&ri,Users);
raxSeek(&ri,"^",NULL,0); raxSeek(&ri,"^",NULL,0);
while(raxNext(&ri)) { while(raxNext(&ri)) {
user *u = ri.data; user *u = (user*)ri.data;
sds line = sdsnew("user "); sds line = sdsnew("user ");
line = sdscatsds(line,u->name); line = sdscatsds(line,u->name);
line = sdscatlen(line," ",1); line = sdscatlen(line," ",1);
@ -2033,7 +2025,7 @@ void rewriteConfigDirOption(struct rewriteConfigState *state) {
} }
/* Rewrite the slaveof option. */ /* 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 /* 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 * in the file to be removed. Note that if this is a cluster instance
* we don't want a slaveof directive inside redis.conf. */ * 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. */ /* Rewrite the notify-keyspace-events option. */
void rewriteConfigNotifykeyspaceeventsOption(struct rewriteConfigState *state) { void rewriteConfigNotifykeyspaceeventsOption(struct rewriteConfigState *state) {
int force = server.notify_keyspace_events != 0; int force = server.notify_keyspace_events != 0;
char *option = "notify-keyspace-events"; const char *option = "notify-keyspace-events";
sds line, flags; sds line, flags;
flags = keyspaceEventsFlagsToString(server.notify_keyspace_events); flags = keyspaceEventsFlagsToString(server.notify_keyspace_events);
@ -2073,7 +2065,7 @@ void rewriteConfigNotifykeyspaceeventsOption(struct rewriteConfigState *state) {
/* Rewrite the client-output-buffer-limit option. */ /* Rewrite the client-output-buffer-limit option. */
void rewriteConfigClientoutputbufferlimitOption(struct rewriteConfigState *state) { void rewriteConfigClientoutputbufferlimitOption(struct rewriteConfigState *state) {
int j; int j;
char *option = "client-output-buffer-limit"; const char *option = "client-output-buffer-limit";
for (j = 0; j < CLIENT_TYPE_OBUF_COUNT; j++) { for (j = 0; j < CLIENT_TYPE_OBUF_COUNT; j++) {
int force = (server.client_obuf_limits[j].hard_limit_bytes != int force = (server.client_obuf_limits[j].hard_limit_bytes !=
@ -2090,10 +2082,10 @@ void rewriteConfigClientoutputbufferlimitOption(struct rewriteConfigState *state
rewriteConfigFormatMemory(soft,sizeof(soft), rewriteConfigFormatMemory(soft,sizeof(soft),
server.client_obuf_limits[j].soft_limit_bytes); server.client_obuf_limits[j].soft_limit_bytes);
const char *typename = getClientTypeName(j); const char *tname = getClientTypeName(j);
if (!strcmp(typename,"slave")) typename = "replica"; if (!strcmp(tname,"slave")) tname = "replica";
line = sdscatprintf(sdsempty(),"%s %s %s %s %ld", 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); (long) server.client_obuf_limits[j].soft_limit_seconds);
rewriteConfigRewriteLine(state,option,line,force); rewriteConfigRewriteLine(state,option,line,force);
} }
@ -2103,7 +2095,7 @@ void rewriteConfigClientoutputbufferlimitOption(struct rewriteConfigState *state
void rewriteConfigBindOption(struct rewriteConfigState *state) { void rewriteConfigBindOption(struct rewriteConfigState *state) {
int force = 1; int force = 1;
sds line, addresses; sds line, addresses;
char *option = "bind"; const char *option = "bind";
/* Nothing to rewrite if we don't have bind addresses. */ /* Nothing to rewrite if we don't have bind addresses. */
if (server.bindaddr_count == 0) { if (server.bindaddr_count == 0) {
@ -2122,7 +2114,7 @@ void rewriteConfigBindOption(struct rewriteConfigState *state) {
} }
/* Rewrite the requirepass option. */ /* Rewrite the requirepass option. */
void rewriteConfigRequirepassOption(struct rewriteConfigState *state, char *option) { void rewriteConfigRequirepassOption(struct rewriteConfigState *state, const char *option) {
int force = 1; int force = 1;
sds line; sds line;
sds password = ACLDefaultUserFirstPassword(); sds password = ACLDefaultUserFirstPassword();
@ -2182,8 +2174,8 @@ void rewriteConfigRemoveOrphaned(struct rewriteConfigState *state) {
dictEntry *de; dictEntry *de;
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
list *l = dictGetVal(de); list *l = (list*)dictGetVal(de);
sds option = dictGetKey(de); sds option = (sds)dictGetKey(de);
/* Don't blank lines about options the rewrite process /* Don't blank lines about options the rewrite process
* don't understand. */ * don't understand. */
@ -2370,7 +2362,6 @@ int rewriteConfig(char *path) {
rewriteConfigYesNoOption(state,"activerehashing",server.activerehashing,CONFIG_DEFAULT_ACTIVE_REHASHING); rewriteConfigYesNoOption(state,"activerehashing",server.activerehashing,CONFIG_DEFAULT_ACTIVE_REHASHING);
rewriteConfigYesNoOption(state,"activedefrag",server.active_defrag_enabled,CONFIG_DEFAULT_ACTIVE_DEFRAG); rewriteConfigYesNoOption(state,"activedefrag",server.active_defrag_enabled,CONFIG_DEFAULT_ACTIVE_DEFRAG);
rewriteConfigYesNoOption(state,"protected-mode",server.protected_mode,CONFIG_DEFAULT_PROTECTED_MODE); rewriteConfigYesNoOption(state,"protected-mode",server.protected_mode,CONFIG_DEFAULT_PROTECTED_MODE);
rewriteConfigYesNoOption(state,"gopher-enabled",server.gopher_enabled,CONFIG_DEFAULT_GOPHER_ENABLED);
rewriteConfigClientoutputbufferlimitOption(state); rewriteConfigClientoutputbufferlimitOption(state);
rewriteConfigNumericalOption(state,"hz",server.config_hz,CONFIG_DEFAULT_HZ); 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); 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) { void configCommand(client *c) {
/* Only allow CONFIG GET while loading. */ /* 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"); addReplyError(c,"Only CONFIG GET is allowed during loading");
return; return;
} }
if (c->argc == 2 && !strcasecmp(ptrFromObj(c->argv[1]),"help")) { if (c->argc == 2 && !strcasecmp(szFromObj(c->argv[1]),"help")) {
const char *help[] = { const char *help[] = {
"GET <pattern> -- Return parameters matching the glob-like <pattern> and their values.", "GET <pattern> -- Return parameters matching the glob-like <pattern> and their values.",
"SET <parameter> <value> -- Set parameter to value.", "SET <parameter> <value> -- Set parameter to value.",
@ -2424,15 +2415,15 @@ void configCommand(client *c) {
NULL NULL
}; };
addReplyHelp(c, help); 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); 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); 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(); resetServerStats();
resetCommandTableStats(); resetCommandTableStats();
addReply(c,shared.ok); 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) { if (server.configfile == NULL) {
addReplyError(c,"The server is running without a config file"); addReplyError(c,"The server is running without a config file");
return; return;

View File

@ -1,5 +1,3 @@
#include "server.h"
/* /*
* Copyright 2001-2010 Georges Menie (www.menie.org) * Copyright 2001-2010 Georges Menie (www.menie.org)
* Copyright 2010-2012 Salvatore Sanfilippo (adapted to Redis coding style) * Copyright 2010-2012 Salvatore Sanfilippo (adapted to Redis coding style)
@ -29,6 +27,8 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <inttypes.h>
/* CRC16 implementation according to CCITT standards. /* CRC16 implementation according to CCITT standards.
* *
* Note by @antirez: this is actually the XMODEM CRC 16 algorithm, using the * Note by @antirez: this is actually the XMODEM CRC 16 algorithm, using the

View File

@ -61,9 +61,10 @@ typedef ucontext_t sigcontext_t;
* "add" digests relative to unordered elements. * "add" digests relative to unordered elements.
* *
* So digest(a,b,c,d) will be the same of digest(b,a,c,d) */ * 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; SHA1_CTX ctx;
unsigned char hash[20], *s = ptr; unsigned char hash[20];
const unsigned char *s = (const unsigned char*)ptr;
int j; int j;
SHA1Init(&ctx); SHA1Init(&ctx);
@ -76,7 +77,7 @@ void xorDigest(unsigned char *digest, void *ptr, size_t len) {
void xorStringObjectDigest(unsigned char *digest, robj *o) { void xorStringObjectDigest(unsigned char *digest, robj *o) {
o = getDecodedObject(o); o = getDecodedObject(o);
xorDigest(digest,ptrFromObj(o),sdslen(ptrFromObj(o))); xorDigest(digest,(const unsigned char*)ptrFromObj(o),sdslen(szFromObj(o)));
decrRefCount(o); decrRefCount(o);
} }
@ -96,7 +97,7 @@ void xorStringObjectDigest(unsigned char *digest, robj *o) {
*/ */
void mixDigest(unsigned char *digest, void *ptr, size_t len) { void mixDigest(unsigned char *digest, void *ptr, size_t len) {
SHA1_CTX ctx; SHA1_CTX ctx;
char *s = ptr; char *s = (char*)ptr;
xorDigest(digest,s,len); xorDigest(digest,s,len);
SHA1Init(&ctx); SHA1Init(&ctx);
@ -106,7 +107,7 @@ void mixDigest(unsigned char *digest, void *ptr, size_t len) {
void mixStringObjectDigest(unsigned char *digest, robj *o) { void mixStringObjectDigest(unsigned char *digest, robj *o) {
o = getDecodedObject(o); o = getDecodedObject(o);
mixDigest(digest,ptrFromObj(o),sdslen(ptrFromObj(o))); mixDigest(digest,ptrFromObj(o),sdslen(szFromObj(o)));
decrRefCount(o); decrRefCount(o);
} }
@ -148,7 +149,7 @@ void xorObjectDigest(redisDb *db, robj *keyobj, unsigned char *digest, robj *o)
unsigned char eledigest[20]; unsigned char eledigest[20];
if (o->encoding == OBJ_ENCODING_ZIPLIST) { if (o->encoding == OBJ_ENCODING_ZIPLIST) {
unsigned char *zl = ptrFromObj(o); unsigned char *zl = (unsigned char*)ptrFromObj(o);
unsigned char *eptr, *sptr; unsigned char *eptr, *sptr;
unsigned char *vstr; unsigned char *vstr;
unsigned int vlen; unsigned int vlen;
@ -178,13 +179,13 @@ void xorObjectDigest(redisDb *db, robj *keyobj, unsigned char *digest, robj *o)
zzlNext(zl,&eptr,&sptr); zzlNext(zl,&eptr,&sptr);
} }
} else if (o->encoding == OBJ_ENCODING_SKIPLIST) { } else if (o->encoding == OBJ_ENCODING_SKIPLIST) {
zset *zs = ptrFromObj(o); zset *zs = (zset*)ptrFromObj(o);
dictIterator *di = dictGetIterator(zs->pdict); dictIterator *di = dictGetIterator(zs->pdict);
dictEntry *de; dictEntry *de;
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sds sdsele = dictGetKey(de); sds sdsele = (sds)dictGetKey(de);
double *score = dictGetVal(de); double *score = (double*)dictGetVal(de);
snprintf(buf,sizeof(buf),"%.17g",*score); snprintf(buf,sizeof(buf),"%.17g",*score);
memset(eledigest,0,20); memset(eledigest,0,20);
@ -214,7 +215,7 @@ void xorObjectDigest(redisDb *db, robj *keyobj, unsigned char *digest, robj *o)
hashTypeReleaseIterator(hi); hashTypeReleaseIterator(hi);
} else if (o->type == OBJ_STREAM) { } else if (o->type == OBJ_STREAM) {
streamIterator si; streamIterator si;
streamIteratorStart(&si,ptrFromObj(o),NULL,NULL,0); streamIteratorStart(&si,(stream*)ptrFromObj(o),NULL,NULL,0);
streamID id; streamID id;
int64_t numfields; int64_t numfields;
@ -235,7 +236,7 @@ void xorObjectDigest(redisDb *db, robj *keyobj, unsigned char *digest, robj *o)
streamIteratorStop(&si); streamIteratorStop(&si);
} else if (o->type == OBJ_MODULE) { } else if (o->type == OBJ_MODULE) {
RedisModuleDigest md; RedisModuleDigest md;
moduleValue *mv = ptrFromObj(o); moduleValue *mv = (moduleValue*)ptrFromObj(o);
moduleType *mt = mv->type; moduleType *mt = mv->type;
moduleInitDigestContext(md); moduleInitDigestContext(md);
if (mt->digest) { if (mt->digest) {
@ -281,12 +282,12 @@ void computeDatasetDigest(unsigned char *final) {
robj *keyobj, *o; robj *keyobj, *o;
memset(digest,0,20); /* This key-val digest */ memset(digest,0,20); /* This key-val digest */
key = dictGetKey(de); key = (sds)dictGetKey(de);
keyobj = createStringObject(key,sdslen(key)); keyobj = createStringObject(key,sdslen(key));
mixDigest(digest,key,sdslen(key)); mixDigest(digest,key,sdslen(key));
o = dictGetVal(de); o = (robj*)dictGetVal(de);
xorObjectDigest(db,keyobj,digest,o); xorObjectDigest(db,keyobj,digest,o);
/* We can finally xor the key-val digest to the final digest */ /* 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) { 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[] = { const char *help[] = {
"ASSERT -- Crash by assertion failed.", "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.", "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 NULL
}; };
addReplyHelp(c, help); addReplyHelp(c, help);
} else if (!strcasecmp(ptrFromObj(c->argv[1]),"segfault")) { } else if (!strcasecmp(szFromObj(c->argv[1]),"segfault")) {
*((char*)-1) = 'x'; *((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)); serverPanic("DEBUG PANIC called at Unix time %ld", time(NULL));
} else if (!strcasecmp(ptrFromObj(c->argv[1]),"restart") || } else if (!strcasecmp(szFromObj(c->argv[1]),"restart") ||
!strcasecmp(ptrFromObj(c->argv[1]),"crash-and-recover")) !strcasecmp(szFromObj(c->argv[1]),"crash-and-recover"))
{ {
long long delay = 0; long long delay = 0;
if (c->argc >= 3) { if (c->argc >= 3) {
@ -339,21 +340,21 @@ NULL
!= C_OK) return; != C_OK) return;
if (delay < 0) delay = 0; 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_GRACEFULLY|RESTART_SERVER_CONFIG_REWRITE) :
RESTART_SERVER_NONE; RESTART_SERVER_NONE;
restartServer(flags,delay); restartServer(flags,delay);
addReplyError(c,"failed to restart the server. Check server logs."); 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. */ void *ptr = zmalloc(ULONG_MAX, MALLOC_LOCAL); /* Should trigger an out of memory. */
zfree(ptr); zfree(ptr);
addReply(c,shared.ok); 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); 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])); serverLog(LL_WARNING, "DEBUG LOG: %s", (char*)ptrFromObj(c->argv[2]));
addReply(c,shared.ok); addReply(c,shared.ok);
} else if (!strcasecmp(ptrFromObj(c->argv[1]),"reload")) { } else if (!strcasecmp(szFromObj(c->argv[1]),"reload")) {
rdbSaveInfo rsi, *rsiptr; rdbSaveInfo rsi, *rsiptr;
rsiptr = rdbPopulateSaveInfo(&rsi); rsiptr = rdbPopulateSaveInfo(&rsi);
if (rdbSave(rsiptr) != C_OK) { if (rdbSave(rsiptr) != C_OK) {
@ -371,7 +372,7 @@ NULL
} }
serverLog(LL_WARNING,"DB reloaded by DEBUG RELOAD"); serverLog(LL_WARNING,"DB reloaded by DEBUG RELOAD");
addReply(c,shared.ok); 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); if (server.aof_state != AOF_OFF) flushAppendOnlyFile(1);
emptyDb(-1,EMPTYDB_NO_FLAGS,NULL); emptyDb(-1,EMPTYDB_NO_FLAGS,NULL);
protectClient(c); protectClient(c);
@ -384,23 +385,23 @@ NULL
server.dirty = 0; /* Prevent AOF / replication */ server.dirty = 0; /* Prevent AOF / replication */
serverLog(LL_WARNING,"Append Only File loaded by DEBUG LOADAOF"); serverLog(LL_WARNING,"Append Only File loaded by DEBUG LOADAOF");
addReply(c,shared.ok); 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; dictEntry *de;
robj *val; robj *val;
char *strenc; const char *strenc;
if ((de = dictFind(c->db->pdict,ptrFromObj(c->argv[2]))) == NULL) { if ((de = dictFind(c->db->pdict,ptrFromObj(c->argv[2]))) == NULL) {
addReply(c,shared.nokeyerr); addReply(c,shared.nokeyerr);
return; return;
} }
val = dictGetVal(de); val = (robj*)dictGetVal(de);
strenc = strEncoding(val->encoding); strenc = strEncoding(val->encoding);
char extra[138] = {0}; char extra[138] = {0};
if (val->encoding == OBJ_ENCODING_QUICKLIST) { if (val->encoding == OBJ_ENCODING_QUICKLIST) {
char *nextra = extra; char *nextra = extra;
int remaining = sizeof(extra); int remaining = sizeof(extra);
quicklist *ql = val->m_ptr; quicklist *ql = (quicklist*)val->m_ptr;
/* Add number of quicklist nodes */ /* Add number of quicklist nodes */
int used = snprintf(nextra, remaining, " ql_nodes:%lu", ql->len); int used = snprintf(nextra, remaining, " ql_nodes:%lu", ql->len);
nextra += used; nextra += used;
@ -436,7 +437,7 @@ NULL
(void*)val, val->refcount, (void*)val, val->refcount,
strenc, rdbSavedObjectLen(val), strenc, rdbSavedObjectLen(val),
val->lru, estimateObjectIdleTime(val)/1000, extra); 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; dictEntry *de;
robj *val; robj *val;
sds key; sds key;
@ -445,8 +446,8 @@ NULL
addReply(c,shared.nokeyerr); addReply(c,shared.nokeyerr);
return; return;
} }
val = dictGetVal(de); val = (robj*)dictGetVal(de);
key = dictGetKey(de); key = (sds)dictGetKey(de);
if (val->type != OBJ_STRING || !sdsEncodedObject(val)) { if (val->type != OBJ_STRING || !sdsEncodedObject(val)) {
addReplyError(c,"Not an sds encoded string."); addReplyError(c,"Not an sds encoded string.");
@ -457,11 +458,11 @@ NULL
(long long) sdslen(key), (long long) sdslen(key),
(long long) sdsavail(key), (long long) sdsavail(key),
(long long) sdsZmallocSize(key), (long long) sdsZmallocSize(key),
(long long) sdslen(ptrFromObj(val)), (long long) sdslen(szFromObj(val)),
(long long) sdsavail(ptrFromObj(val)), (long long) sdsavail(szFromObj(val)),
(long long) getStringObjectSdsUsedMemory(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; robj *o;
if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nokeyerr)) if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nokeyerr))
@ -470,10 +471,10 @@ NULL
if (o->encoding != OBJ_ENCODING_ZIPLIST) { if (o->encoding != OBJ_ENCODING_ZIPLIST) {
addReplyError(c,"Not an sds encoded string."); addReplyError(c,"Not an sds encoded string.");
} else { } else {
ziplistRepr(ptrFromObj(o)); ziplistRepr((unsigned char*)ptrFromObj(o));
addReplyStatus(c,"Ziplist structure printed on stdout"); 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) { c->argc >= 3 && c->argc <= 5) {
long keys, j; long keys, j;
robj *key, *val; robj *key, *val;
@ -507,7 +508,7 @@ NULL
decrRefCount(key); decrRefCount(key);
} }
addReply(c,shared.ok); 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) */ /* DEBUG DIGEST (form without keys specified) */
unsigned char digest[20]; unsigned char digest[20];
sds d = sdsempty(); sds d = sdsempty();
@ -516,7 +517,7 @@ NULL
for (int i = 0; i < 20; i++) d = sdscatprintf(d, "%02x",digest[i]); for (int i = 0; i < 20; i++) d = sdscatprintf(d, "%02x",digest[i]);
addReplyStatus(c,d); addReplyStatus(c,d);
sdsfree(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. */ /* DEBUG DIGEST-VALUE key key key ... key. */
addReplyArrayLen(c,c->argc-2); addReplyArrayLen(c,c->argc-2);
for (int j = 2; j < c->argc; j++) { for (int j = 2; j < c->argc; j++) {
@ -530,10 +531,10 @@ NULL
addReplyStatus(c,d); addReplyStatus(c,d);
sdsfree(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| /* DEBUG PROTOCOL [string|integer|double|bignum|null|array|set|map|
* attrib|push|verbatim|true|false|state|err|bloberr] */ * attrib|push|verbatim|true|false|state|err|bloberr] */
char *name = ptrFromObj(c->argv[2]); char *name = szFromObj(c->argv[2]);
if (!strcasecmp(name,"string")) { if (!strcasecmp(name,"string")) {
addReplyBulkCString(c,"Hello World"); addReplyBulkCString(c,"Hello World");
} else if (!strcasecmp(name,"integer")) { } else if (!strcasecmp(name,"integer")) {
@ -582,8 +583,8 @@ NULL
} else { } 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"); 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) { } else if (!strcasecmp(szFromObj(c->argv[1]),"sleep") && c->argc == 3) {
double dtime = strtod(ptrFromObj(c->argv[2]),NULL); double dtime = strtod(szFromObj(c->argv[2]),NULL);
long long utime = dtime*1000000; long long utime = dtime*1000000;
struct timespec tv; struct timespec tv;
@ -591,24 +592,24 @@ NULL
tv.tv_nsec = (utime % 1000000) * 1000; tv.tv_nsec = (utime % 1000000) * 1000;
nanosleep(&tv, NULL); nanosleep(&tv, NULL);
addReply(c,shared.ok); 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) 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); 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) 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); 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); 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 = sdsmapchars(errstr,"\n\r"," ",2); /* no newlines in errors. */
errstr = sdscatlen(errstr,"\r\n",2); errstr = sdscatlen(errstr,"\r\n",2);
addReplySds(c,errstr); 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(); sds sizes = sdsempty();
sizes = sdscatprintf(sizes,"bits:%d ",(sizeof(void*) == 8)?64:32); sizes = sdscatprintf(sizes,"bits:%d ",(sizeof(void*) == 8)?64:32);
sizes = sdscatprintf(sizes,"robj:%d ",(int)sizeof(robj)); 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,"sdshdr32:%d ",(int)sizeof(struct sdshdr32));
sizes = sdscatprintf(sizes,"sdshdr64:%d ",(int)sizeof(struct sdshdr64)); sizes = sdscatprintf(sizes,"sdshdr64:%d ",(int)sizeof(struct sdshdr64));
addReplyBulkSds(c,sizes); 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; long dbid;
sds stats = sdsempty(); sds stats = sdsempty();
char buf[4096]; char buf[4096];
@ -640,7 +641,7 @@ NULL
stats = sdscat(stats,buf); stats = sdscat(stats,buf);
addReplyBulkSds(c,stats); 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; robj *o;
dict *ht = NULL; dict *ht = NULL;
@ -651,12 +652,12 @@ NULL
switch (o->encoding) { switch (o->encoding) {
case OBJ_ENCODING_SKIPLIST: case OBJ_ENCODING_SKIPLIST:
{ {
zset *zs = ptrFromObj(o); zset *zs = (zset*)ptrFromObj(o);
ht = zs->pdict; ht = zs->pdict;
} }
break; break;
case OBJ_ENCODING_HT: case OBJ_ENCODING_HT:
ht = ptrFromObj(o); ht = (dict*)ptrFromObj(o);
break; break;
} }
@ -668,12 +669,12 @@ NULL
dictGetStats(buf,sizeof(buf),ht); dictGetStats(buf,sizeof(buf),ht);
addReplyBulkCString(c,buf); 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"); serverLog(LL_WARNING,"Changing replication IDs after receiving DEBUG change-repl-id");
changeReplicationId(); changeReplicationId();
clearReplicationId2(); clearReplicationId2();
addReply(c,shared.ok); 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(); stringmatchlen_fuzz_test();
addReplyStatus(c,"Apparently Redis did not crash: test passed"); 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 encoding: %d", o->encoding);
serverLog(LL_WARNING,"Object refcount: %d", o->refcount); serverLog(LL_WARNING,"Object refcount: %d", o->refcount);
if (o->type == OBJ_STRING && sdsEncodedObject(o)) { if (o->type == OBJ_STRING && sdsEncodedObject(o)) {
serverLog(LL_WARNING,"Object raw string len: %zu", sdslen(ptrFromObj(o))); serverLog(LL_WARNING,"Object raw string len: %zu", sdslen(szFromObj(o)));
if (sdslen(ptrFromObj(o)) < 4096) { if (sdslen(szFromObj(o)) < 4096) {
sds repr = sdscatrepr(sdsempty(),ptrFromObj(o),sdslen(ptrFromObj(o))); sds repr = sdscatrepr(sdsempty(),szFromObj(o),sdslen(szFromObj(o)));
serverLog(LL_WARNING,"Object raw string content: %s", repr); serverLog(LL_WARNING,"Object raw string content: %s", repr);
sdsfree(repr); sdsfree(repr);
} }
@ -1149,8 +1150,8 @@ void logStackTrace(ucontext_t *uc) {
trace_size = backtrace(trace+1, 100); trace_size = backtrace(trace+1, 100);
if (getMcontextEip(uc) != NULL) { if (getMcontextEip(uc) != NULL) {
char *msg1 = "EIP:\n"; const char *msg1 = "EIP:\n";
char *msg2 = "\nBacktrace:\n"; const char *msg2 = "\nBacktrace:\n";
if (write(fd,msg1,strlen(msg1)) == -1) {/* Avoid warning. */}; if (write(fd,msg1,strlen(msg1)) == -1) {/* Avoid warning. */};
trace[0] = getMcontextEip(uc); trace[0] = getMcontextEip(uc);
backtrace_symbols_fd(trace, 1, fd); backtrace_symbols_fd(trace, 1, fd);
@ -1195,7 +1196,7 @@ void logCurrentClient(void) {
key = getDecodedObject(cc->argv[1]); key = getDecodedObject(cc->argv[1]);
de = dictFind(cc->db->pdict, ptrFromObj(key)); de = dictFind(cc->db->pdict, ptrFromObj(key));
if (de) { if (de) {
val = dictGetVal(de); val = (robj*)dictGetVal(de);
serverLog(LL_WARNING,"key '%s' found in DB containing the following object:", (char*)ptrFromObj(key)); serverLog(LL_WARNING,"key '%s' found in DB containing the following object:", (char*)ptrFromObj(key));
serverLogObjectDebugInfo(val); serverLogObjectDebugInfo(val);
} }
@ -1256,7 +1257,7 @@ int memtest_test_linux_anonymous_maps(void) {
int errors = 0; int errors = 0;
for (j = 0; j < regions; j++) { for (j = 0; j < regions; j++) {
if (write(fd,".",1) == -1) { /* Nothing to do. */ } 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, errors ? "E" : "O",1) == -1) { /* Nothing to do. */ }
} }
if (write(fd,"\n",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. */ * and the call offset if they appear to be valid. */
void dumpX86Calls(void *addr, size_t len) { void dumpX86Calls(void *addr, size_t len) {
size_t j; size_t j;
unsigned char *p = addr; unsigned char *p = (unsigned char*)addr;
Dl_info info; Dl_info info;
/* Hash table to best-effort avoid printing the same symbol /* Hash table to best-effort avoid printing the same symbol
* multiple times. */ * 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) { void serverLogHexDump(int level, const char *descr, void *value, size_t len) {
char buf[65], *b; char buf[65], *b;
unsigned char *v = value; unsigned char *v = (unsigned char*)value;
char charset[] = "0123456789abcdef"; char charset[] = "0123456789abcdef";
serverLog(level,"%s (hexdump of %zu bytes):", descr, len); serverLog(level,"%s (hexdump of %zu bytes):", descr, len);

View File

@ -43,7 +43,7 @@
/* this method was added to jemalloc in order to help us understand which /* this method was added to jemalloc in order to help us understand which
* pointers are worthwhile moving and which aren't */ * 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*/ /* forward declarations*/
void defragDictBucketCallback(void *privdata, dictEntry **bucketref); 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). */ /* try to defrag robj (only if not an EMBSTR type (handled below). */
if (ob->type!=OBJ_STRING || ob->encoding!=OBJ_ENCODING_EMBSTR) { if (ob->type!=OBJ_STRING || ob->encoding!=OBJ_ENCODING_EMBSTR) {
if ((ret = activeDefragAlloc(ob))) { if ((ret = (robj*)activeDefragAlloc(ob))) {
ob = ret; ob = ret;
(*defragged)++; (*defragged)++;
} }
@ -124,7 +124,7 @@ robj *activeDefragStringOb(robj* ob, long *defragged) {
} else if (ob->encoding==OBJ_ENCODING_EMBSTR) { } else if (ob->encoding==OBJ_ENCODING_EMBSTR) {
/* The sds is embedded in the object allocation, calculate the /* The sds is embedded in the object allocation, calculate the
* offset and update the pointer in the new allocation. */ * offset and update the pointer in the new allocation. */
if ((ret = activeDefragAlloc(ob))) { if ((ret = (robj*)activeDefragAlloc(ob))) {
(*defragged)++; (*defragged)++;
} }
} else if (ob->encoding!=OBJ_ENCODING_INT) { } 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 /* Handle the next entry (if there is one), and update the pointer in the
* current entry. */ * current entry. */
if (iter->nextEntry) { if (iter->nextEntry) {
dictEntry *newde = activeDefragAlloc(iter->nextEntry); dictEntry *newde = (dictEntry*)activeDefragAlloc(iter->nextEntry);
if (newde) { if (newde) {
defragged++; defragged++;
iter->nextEntry = newde; iter->nextEntry = newde;
@ -155,7 +155,7 @@ long dictIterDefragEntry(dictIterator *iter) {
/* handle the case of the first entry in the hash bucket. */ /* handle the case of the first entry in the hash bucket. */
ht = &iter->d->ht[iter->table]; ht = &iter->d->ht[iter->table];
if (ht->table[iter->index] == iter->entry) { if (ht->table[iter->index] == iter->entry) {
dictEntry *newde = activeDefragAlloc(iter->entry); dictEntry *newde = (dictEntry*)activeDefragAlloc(iter->entry);
if (newde) { if (newde) {
iter->entry = newde; iter->entry = newde;
ht->table[iter->index] = newde; ht->table[iter->index] = newde;
@ -172,12 +172,12 @@ long dictDefragTables(dict* d) {
dictEntry **newtable; dictEntry **newtable;
long defragged = 0; long defragged = 0;
/* handle the first hash table */ /* handle the first hash table */
newtable = activeDefragAlloc(d->ht[0].table); newtable = (dictEntry**)activeDefragAlloc(d->ht[0].table);
if (newtable) if (newtable)
defragged++, d->ht[0].table = newtable; defragged++, d->ht[0].table = newtable;
/* handle the second hash table */ /* handle the second hash table */
if (d->ht[1].table) { if (d->ht[1].table) {
newtable = activeDefragAlloc(d->ht[1].table); newtable = (dictEntry**)activeDefragAlloc(d->ht[1].table);
if (newtable) if (newtable)
defragged++, d->ht[1].table = 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) { void zslUpdateNode(zskiplist *zsl, zskiplistNode *oldnode, zskiplistNode *newnode, zskiplistNode **update) {
int i; int i;
for (i = 0; i < zsl->level; i++) { for (i = 0; i < zsl->level; i++) {
if (update[i]->level[i].forward == oldnode) if (update[i]->level(i)->forward == oldnode)
update[i]->level[i].forward = newnode; update[i]->level(i)->forward = newnode;
} }
serverAssert(zsl->header!=oldnode); serverAssert(zsl->header!=oldnode);
if (newnode->level[0].forward) { if (newnode->level(0)->forward) {
serverAssert(newnode->level[0].forward->backward==oldnode); serverAssert(newnode->level(0)->forward->backward==oldnode);
newnode->level[0].forward->backward = newnode; newnode->level(0)->forward->backward = newnode;
} else { } else {
serverAssert(zsl->tail==oldnode); serverAssert(zsl->tail==oldnode);
zsl->tail = newnode; 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. */ * and all pointers that need to be updated if we'll end up moving the skiplist node. */
x = zsl->header; x = zsl->header;
for (i = zsl->level-1; i >= 0; i--) { for (i = zsl->level-1; i >= 0; i--) {
while (x->level[i].forward && while (x->level(i)->forward &&
x->level[i].forward->ele != oldele && /* make sure not to access the x->level(i)->forward->ele != oldele && /* make sure not to access the
->obj pointer if it matches ->obj pointer if it matches
oldele */ oldele */
(x->level[i].forward->score < score || (x->level(i)->forward->score < score ||
(x->level[i].forward->score == score && (x->level(i)->forward->score == score &&
sdscmp(x->level[i].forward->ele,ele) < 0))) sdscmp(x->level(i)->forward->ele,ele) < 0)))
x = x->level[i].forward; x = x->level(i)->forward;
update[i] = x; update[i] = x;
} }
/* update the robj pointer inside the skip list record. */ /* 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); serverAssert(x && score == x->score && x->ele==oldele);
if (newele) if (newele)
x->ele = newele; x->ele = newele;
/* try to defrag the skiplist record itself */ /* try to defrag the skiplist record itself */
newx = activeDefragAlloc(x); newx = (zskiplistNode*)activeDefragAlloc(x);
if (newx) { if (newx) {
zslUpdateNode(zsl, x, newx, update); zslUpdateNode(zsl, x, newx, update);
return &newx->score; return &newx->score;
@ -249,7 +249,7 @@ long activeDefragZsetEntry(zset *zs, dictEntry *de) {
sds newsds; sds newsds;
double* newscore; double* newscore;
long defragged = 0; long defragged = 0;
sds sdsele = dictGetKey(de); sds sdsele = (sds)dictGetKey(de);
if ((newsds = activeDefragSds(sdsele))) if ((newsds = activeDefragSds(sdsele)))
defragged++, de->key = newsds; defragged++, de->key = newsds;
newscore = zslDefrag(zs->zsl, *(double*)dictGetVal(de), sdsele, newsds); newscore = zslDefrag(zs->zsl, *(double*)dictGetVal(de), sdsele, newsds);
@ -272,16 +272,16 @@ long activeDefragSdsDict(dict* d, int val_type) {
long defragged = 0; long defragged = 0;
di = dictGetIterator(d); di = dictGetIterator(d);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sds sdsele = dictGetKey(de), newsds; sds sdsele = (sds)dictGetKey(de), newsds;
if ((newsds = activeDefragSds(sdsele))) if ((newsds = activeDefragSds(sdsele)))
de->key = newsds, defragged++; de->key = newsds, defragged++;
/* defrag the value */ /* defrag the value */
if (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) { if (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) {
sdsele = dictGetVal(de); sdsele = (sds)dictGetVal(de);
if ((newsds = activeDefragSds(sdsele))) if ((newsds = activeDefragSds(sdsele)))
de->v.val = newsds, defragged++; de->v.val = newsds, defragged++;
} else if (val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) { } 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))) if ((newele = activeDefragStringOb(ele, &defragged)))
de->v.val = newele; de->v.val = newele;
} else if (val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) { } else if (val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) {
@ -300,7 +300,7 @@ long activeDefragList(list *l, int val_type) {
long defragged = 0; long defragged = 0;
listNode *ln, *newln; listNode *ln, *newln;
for (ln = l->head; ln; ln = ln->next) { for (ln = l->head; ln; ln = ln->next) {
if ((newln = activeDefragAlloc(ln))) { if ((newln = (listNode*)activeDefragAlloc(ln))) {
if (newln->prev) if (newln->prev)
newln->prev->next = newln; newln->prev->next = newln;
else else
@ -313,11 +313,11 @@ long activeDefragList(list *l, int val_type) {
defragged++; defragged++;
} }
if (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) { if (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) {
sds newsds, sdsele = ln->value; sds newsds, sdsele = (sds)ln->value;
if ((newsds = activeDefragSds(sdsele))) if ((newsds = activeDefragSds(sdsele)))
ln->value = newsds, defragged++; ln->value = newsds, defragged++;
} else if (val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) { } 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))) if ((newele = activeDefragStringOb(ele, &defragged)))
ln->value = newele; ln->value = newele;
} else if (val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) { } 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; dictEntry *de;
/* Defrag the list and it's sds values */ /* Defrag the list and it's sds values */
for (ln = l->head; ln; ln = ln->next) { for (ln = l->head; ln; ln = ln->next) {
if ((newln = activeDefragAlloc(ln))) { if ((newln = (listNode*)activeDefragAlloc(ln))) {
if (newln->prev) if (newln->prev)
newln->prev->next = newln; newln->prev->next = newln;
else else
@ -350,7 +350,7 @@ long activeDefragSdsListAndDict(list *l, dict *d, int dict_val_type) {
ln = newln; ln = newln;
defragged++; defragged++;
} }
sdsele = ln->value; sdsele = (sds)ln->value;
if ((newsds = activeDefragSds(sdsele))) { if ((newsds = activeDefragSds(sdsele))) {
/* When defragging an sds value, we need to update the dict key */ /* When defragging an sds value, we need to update the dict key */
unsigned int hash = dictGetHash(d, sdsele); unsigned int hash = dictGetHash(d, sdsele);
@ -364,11 +364,11 @@ long activeDefragSdsListAndDict(list *l, dict *d, int dict_val_type) {
di = dictGetIterator(d); di = dictGetIterator(d);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
if (dict_val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) { 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))) if ((newsds = activeDefragSds(sdsele)))
de->v.val = newsds, defragged++; de->v.val = newsds, defragged++;
} else if (dict_val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) { } 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))) if ((newele = activeDefragStringOb(ele, &defragged)))
de->v.val = newele, defragged++; de->v.val = newele, defragged++;
} else if (dict_val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) { } 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); dictEntry **deref = dictFindEntryRefByPtrAndHash(d, oldkey, hash);
if (deref) { if (deref) {
dictEntry *de = *deref; dictEntry *de = *deref;
dictEntry *newde = activeDefragAlloc(de); dictEntry *newde = (dictEntry*)activeDefragAlloc(de);
if (newde) { if (newde) {
de = *deref = newde; de = *deref = newde;
(*defragged)++; (*defragged)++;
@ -411,7 +411,7 @@ long activeDefragQuickListNodes(quicklist *ql) {
long defragged = 0; long defragged = 0;
unsigned char *newzl; unsigned char *newzl;
while (node) { while (node) {
if ((newnode = activeDefragAlloc(node))) { if ((newnode = (quicklistNode*)activeDefragAlloc(node))) {
if (newnode->prev) if (newnode->prev)
newnode->prev->next = newnode; newnode->prev->next = newnode;
else else
@ -423,7 +423,7 @@ long activeDefragQuickListNodes(quicklist *ql) {
node = newnode; node = newnode;
defragged++; defragged++;
} }
if ((newzl = activeDefragAlloc(node->zl))) if ((newzl = (unsigned char*)activeDefragAlloc(node->zl)))
defragged++, node->zl = newzl; defragged++, node->zl = newzl;
node = node->next; 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 * oart of the main dictionary scan. this is needed in order to prevent latency
* spikes when handling large items */ * spikes when handling large items */
void defragLater(redisDb *db, dictEntry *kde) { void defragLater(redisDb *db, dictEntry *kde) {
sds key = sdsdup(dictGetKey(kde)); sds key = sdsdup((sds)dictGetKey(kde));
listAddNodeTail(db->defrag_later, key); listAddNodeTail(db->defrag_later, key);
} }
long scanLaterList(robj *ob) { long scanLaterList(robj *ob) {
quicklist *ql = ptrFromObj(ob); quicklist *ql = (quicklist*)ptrFromObj(ob);
if (ob->type != OBJ_LIST || ob->encoding != OBJ_ENCODING_QUICKLIST) if (ob->type != OBJ_LIST || ob->encoding != OBJ_ENCODING_QUICKLIST)
return 0; return 0;
server.stat_active_defrag_scanned+=ql->len; server.stat_active_defrag_scanned+=ql->len;
@ -453,7 +453,7 @@ typedef struct {
void scanLaterZsetCallback(void *privdata, const dictEntry *_de) { void scanLaterZsetCallback(void *privdata, const dictEntry *_de) {
dictEntry *de = (dictEntry*)_de; dictEntry *de = (dictEntry*)_de;
scanLaterZsetData *data = privdata; scanLaterZsetData *data = (scanLaterZsetData*)privdata;
data->defragged += activeDefragZsetEntry(data->zs, de); data->defragged += activeDefragZsetEntry(data->zs, de);
server.stat_active_defrag_scanned++; server.stat_active_defrag_scanned++;
} }
@ -470,8 +470,8 @@ long scanLaterZset(robj *ob, unsigned long *cursor) {
void scanLaterSetCallback(void *privdata, const dictEntry *_de) { void scanLaterSetCallback(void *privdata, const dictEntry *_de) {
dictEntry *de = (dictEntry*)_de; dictEntry *de = (dictEntry*)_de;
long *defragged = privdata; long *defragged = (long*)privdata;
sds sdsele = dictGetKey(de), newsds; sds sdsele = (sds)dictGetKey(de), newsds;
if ((newsds = activeDefragSds(sdsele))) if ((newsds = activeDefragSds(sdsele)))
(*defragged)++, de->key = newsds; (*defragged)++, de->key = newsds;
server.stat_active_defrag_scanned++; server.stat_active_defrag_scanned++;
@ -481,18 +481,18 @@ long scanLaterSet(robj *ob, unsigned long *cursor) {
long defragged = 0; long defragged = 0;
if (ob->type != OBJ_SET || ob->encoding != OBJ_ENCODING_HT) if (ob->type != OBJ_SET || ob->encoding != OBJ_ENCODING_HT)
return 0; return 0;
dict *d = ptrFromObj(ob); dict *d = (dict*)ptrFromObj(ob);
*cursor = dictScan(d, *cursor, scanLaterSetCallback, defragDictBucketCallback, &defragged); *cursor = dictScan(d, *cursor, scanLaterSetCallback, defragDictBucketCallback, &defragged);
return defragged; return defragged;
} }
void scanLaterHashCallback(void *privdata, const dictEntry *_de) { void scanLaterHashCallback(void *privdata, const dictEntry *_de) {
dictEntry *de = (dictEntry*)_de; dictEntry *de = (dictEntry*)_de;
long *defragged = privdata; long *defragged = (long*)privdata;
sds sdsele = dictGetKey(de), newsds; sds sdsele = (sds)dictGetKey(de), newsds;
if ((newsds = activeDefragSds(sdsele))) if ((newsds = activeDefragSds(sdsele)))
(*defragged)++, de->key = newsds; (*defragged)++, de->key = newsds;
sdsele = dictGetVal(de); sdsele = (sds)dictGetVal(de);
if ((newsds = activeDefragSds(sdsele))) if ((newsds = activeDefragSds(sdsele)))
(*defragged)++, de->v.val = newsds; (*defragged)++, de->v.val = newsds;
server.stat_active_defrag_scanned++; server.stat_active_defrag_scanned++;
@ -502,17 +502,17 @@ long scanLaterHash(robj *ob, unsigned long *cursor) {
long defragged = 0; long defragged = 0;
if (ob->type != OBJ_HASH || ob->encoding != OBJ_ENCODING_HT) if (ob->type != OBJ_HASH || ob->encoding != OBJ_ENCODING_HT)
return 0; return 0;
dict *d = ptrFromObj(ob); dict *d = (dict*)ptrFromObj(ob);
*cursor = dictScan(d, *cursor, scanLaterHashCallback, defragDictBucketCallback, &defragged); *cursor = dictScan(d, *cursor, scanLaterHashCallback, defragDictBucketCallback, &defragged);
return defragged; return defragged;
} }
long defragQuicklist(redisDb *db, dictEntry *kde) { long defragQuicklist(redisDb *db, dictEntry *kde) {
robj *ob = dictGetVal(kde); robj *ob = (robj*)dictGetVal(kde);
long defragged = 0; long defragged = 0;
quicklist *ql = ptrFromObj(ob), *newql; quicklist *ql = (quicklist*)ptrFromObj(ob), *newql;
serverAssert(ob->type == OBJ_LIST && ob->encoding == OBJ_ENCODING_QUICKLIST); 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; defragged++, ob->m_ptr = ql = newql;
if (ql->len > server.active_defrag_max_scan_fields) if (ql->len > server.active_defrag_max_scan_fields)
defragLater(db, kde); defragLater(db, kde);
@ -522,7 +522,7 @@ long defragQuicklist(redisDb *db, dictEntry *kde) {
} }
long defragZsetSkiplist(redisDb *db, dictEntry *kde) { long defragZsetSkiplist(redisDb *db, dictEntry *kde) {
robj *ob = dictGetVal(kde); robj *ob = (robj*)dictGetVal(kde);
long defragged = 0; long defragged = 0;
zset *zs = (zset*)ptrFromObj(ob); zset *zs = (zset*)ptrFromObj(ob);
zset *newzs; zset *newzs;
@ -531,11 +531,11 @@ long defragZsetSkiplist(redisDb *db, dictEntry *kde) {
dictEntry *de; dictEntry *de;
struct zskiplistNode *newheader; struct zskiplistNode *newheader;
serverAssert(ob->type == OBJ_ZSET && ob->encoding == OBJ_ENCODING_SKIPLIST); 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; defragged++, ob->m_ptr = zs = newzs;
if ((newzsl = activeDefragAlloc(zs->zsl))) if ((newzsl = (zskiplist*)activeDefragAlloc(zs->zsl)))
defragged++, zs->zsl = newzsl; defragged++, zs->zsl = newzsl;
if ((newheader = activeDefragAlloc(zs->zsl->header))) if ((newheader = (zskiplistNode*)activeDefragAlloc(zs->zsl->header)))
defragged++, zs->zsl->header = newheader; defragged++, zs->zsl->header = newheader;
if (dictSize(zs->pdict) > server.active_defrag_max_scan_fields) if (dictSize(zs->pdict) > server.active_defrag_max_scan_fields)
defragLater(db, kde); defragLater(db, kde);
@ -547,7 +547,7 @@ long defragZsetSkiplist(redisDb *db, dictEntry *kde) {
dictReleaseIterator(di); dictReleaseIterator(di);
} }
/* handle the dict struct */ /* handle the dict struct */
if ((newdict = activeDefragAlloc(zs->pdict))) if ((newdict = (dict*)activeDefragAlloc(zs->pdict)))
defragged++, zs->pdict = newdict; defragged++, zs->pdict = newdict;
/* defrag the dict tables */ /* defrag the dict tables */
defragged += dictDefragTables(zs->pdict); defragged += dictDefragTables(zs->pdict);
@ -556,44 +556,44 @@ long defragZsetSkiplist(redisDb *db, dictEntry *kde) {
long defragHash(redisDb *db, dictEntry *kde) { long defragHash(redisDb *db, dictEntry *kde) {
long defragged = 0; long defragged = 0;
robj *ob = dictGetVal(kde); robj *ob = (robj*)dictGetVal(kde);
dict *d, *newd; dict *d, *newd;
serverAssert(ob->type == OBJ_HASH && ob->encoding == OBJ_ENCODING_HT); 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) if (dictSize(d) > server.active_defrag_max_scan_fields)
defragLater(db, kde); defragLater(db, kde);
else else
defragged += activeDefragSdsDict(d, DEFRAG_SDS_DICT_VAL_IS_SDS); defragged += activeDefragSdsDict(d, DEFRAG_SDS_DICT_VAL_IS_SDS);
/* handle the dict struct */ /* handle the dict struct */
if ((newd = activeDefragAlloc(ptrFromObj(ob)))) if ((newd = (dict*)activeDefragAlloc(ptrFromObj(ob))))
defragged++, ob->m_ptr = newd; defragged++, ob->m_ptr = newd;
/* defrag the dict tables */ /* defrag the dict tables */
defragged += dictDefragTables(ptrFromObj(ob)); defragged += dictDefragTables((dict*)ptrFromObj(ob));
return defragged; return defragged;
} }
long defragSet(redisDb *db, dictEntry *kde) { long defragSet(redisDb *db, dictEntry *kde) {
long defragged = 0; long defragged = 0;
robj *ob = dictGetVal(kde); robj *ob = (robj*)dictGetVal(kde);
dict *d, *newd; dict *d, *newd;
serverAssert(ob->type == OBJ_SET && ob->encoding == OBJ_ENCODING_HT); 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) if (dictSize(d) > server.active_defrag_max_scan_fields)
defragLater(db, kde); defragLater(db, kde);
else else
defragged += activeDefragSdsDict(d, DEFRAG_SDS_DICT_NO_VAL); defragged += activeDefragSdsDict(d, DEFRAG_SDS_DICT_NO_VAL);
/* handle the dict struct */ /* handle the dict struct */
if ((newd = activeDefragAlloc(ptrFromObj(ob)))) if ((newd = (dict*)activeDefragAlloc(ptrFromObj(ob))))
defragged++, ob->m_ptr = newd; defragged++, ob->m_ptr = newd;
/* defrag the dict tables */ /* defrag the dict tables */
defragged += dictDefragTables(ptrFromObj(ob)); defragged += dictDefragTables((dict*)ptrFromObj(ob));
return defragged; return defragged;
} }
/* Defrag callback for radix tree iterator, called for each node, /* Defrag callback for radix tree iterator, called for each node,
* used in order to defrag the nodes allocations. */ * used in order to defrag the nodes allocations. */
int defragRaxNode(raxNode **noderef) { int defragRaxNode(raxNode **noderef) {
raxNode *newnode = activeDefragAlloc(*noderef); raxNode *newnode = (raxNode*)activeDefragAlloc(*noderef);
if (newnode) { if (newnode) {
*noderef = newnode; *noderef = newnode;
return 1; return 1;
@ -611,7 +611,7 @@ int scanLaterStraemListpacks(robj *ob, unsigned long *cursor, long long endtime,
return 0; return 0;
} }
stream *s = ptrFromObj(ob); stream *s = (stream*)ptrFromObj(ob);
raxStart(&ri,s->prax); raxStart(&ri,s->prax);
if (*cursor == 0) { if (*cursor == 0) {
/* if cursor is 0, we start new iteration */ /* 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 defragRadixTree(rax **raxref, int defrag_data, raxDefragFunction *element_cb, void *element_cb_data) {
long defragged = 0; long defragged = 0;
raxIterator ri; raxIterator ri;
rax* rax; ::rax* rax;
if ((rax = activeDefragAlloc(*raxref))) if ((rax = (::rax*)activeDefragAlloc(*raxref)))
defragged++, *raxref = rax; defragged++, *raxref = rax;
rax = *raxref; rax = *raxref;
raxStart(&ri,rax); raxStart(&ri,rax);
@ -690,10 +690,10 @@ typedef struct {
void* defragStreamConsumerPendingEntry(raxIterator *ri, void *privdata, long *defragged) { void* defragStreamConsumerPendingEntry(raxIterator *ri, void *privdata, long *defragged) {
UNUSED(defragged); UNUSED(defragged);
PendingEntryContext *ctx = privdata; PendingEntryContext *ctx = (PendingEntryContext*)privdata;
streamNACK *nack = ri->data, *newnack; streamNACK *nack = (streamNACK*)ri->data, *newnack;
nack->consumer = ctx->c; /* update nack pointer to consumer */ nack->consumer = ctx->c; /* update nack pointer to consumer */
newnack = activeDefragAlloc(nack); newnack = (streamNACK*)activeDefragAlloc(nack);
if (newnack) { if (newnack) {
/* update consumer group pointer to the nack */ /* update consumer group pointer to the nack */
void *prev; void *prev;
@ -705,12 +705,12 @@ void* defragStreamConsumerPendingEntry(raxIterator *ri, void *privdata, long *de
} }
void* defragStreamConsumer(raxIterator *ri, void *privdata, long *defragged) { void* defragStreamConsumer(raxIterator *ri, void *privdata, long *defragged) {
streamConsumer *c = ri->data; streamConsumer *c = (streamConsumer*)ri->data;
streamCG *cg = privdata; streamCG *cg = (streamCG*)privdata;
void *newc = activeDefragAlloc(c); void *newc = activeDefragAlloc(c);
if (newc) { if (newc) {
/* note: we don't increment 'defragged' that's done by the caller */ /* note: we don't increment 'defragged' that's done by the caller */
c = newc; c = (streamConsumer*)newc;
} }
sds newsds = activeDefragSds(c->name); sds newsds = activeDefragSds(c->name);
if (newsds) if (newsds)
@ -723,7 +723,7 @@ void* defragStreamConsumer(raxIterator *ri, void *privdata, long *defragged) {
} }
void* defragStreamConsumerGroup(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); UNUSED(privdata);
if (cg->consumers) if (cg->consumers)
*defragged += defragRadixTree(&cg->consumers, 0, defragStreamConsumer, cg); *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 defragStream(redisDb *db, dictEntry *kde) {
long defragged = 0; long defragged = 0;
robj *ob = dictGetVal(kde); robj *ob = (robj*)dictGetVal(kde);
serverAssert(ob->type == OBJ_STREAM && ob->encoding == OBJ_ENCODING_STREAM); 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 */ /* handle the main struct */
if ((news = activeDefragAlloc(s))) if ((news = (stream*)activeDefragAlloc(s)))
defragged++, ob->m_ptr = s = news; defragged++, ob->m_ptr = s = news;
if (raxSize(s->prax) > server.active_defrag_max_scan_fields) { if (raxSize(s->prax) > server.active_defrag_max_scan_fields) {
rax *newrax = activeDefragAlloc(s->prax); rax *newrax = (rax*)activeDefragAlloc(s->prax);
if (newrax) if (newrax)
defragged++, s->prax = newrax; defragged++, s->prax = newrax;
defragLater(db, kde); 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 * all the various pointers it has. Returns a stat of how many pointers were
* moved. */ * moved. */
long defragKey(redisDb *db, dictEntry *de) { long defragKey(redisDb *db, dictEntry *de) {
sds keysds = dictGetKey(de); sds keysds = (sds)dictGetKey(de);
robj *newob, *ob; robj *newob, *ob;
unsigned char *newzl; unsigned char *newzl;
long defragged = 0; long defragged = 0;
@ -778,7 +778,7 @@ long defragKey(redisDb *db, dictEntry *de) {
} }
/* Try to defrag robj and / or string value. */ /* Try to defrag robj and / or string value. */
ob = dictGetVal(de); ob = (robj*)dictGetVal(de);
if ((newob = activeDefragStringOb(ob, &defragged))) { if ((newob = activeDefragStringOb(ob, &defragged))) {
de->v.val = newob; de->v.val = newob;
ob = newob; ob = newob;
@ -790,7 +790,7 @@ long defragKey(redisDb *db, dictEntry *de) {
if (ob->encoding == OBJ_ENCODING_QUICKLIST) { if (ob->encoding == OBJ_ENCODING_QUICKLIST) {
defragged += defragQuicklist(db, de); defragged += defragQuicklist(db, de);
} else if (ob->encoding == OBJ_ENCODING_ZIPLIST) { } else if (ob->encoding == OBJ_ENCODING_ZIPLIST) {
if ((newzl = activeDefragAlloc(ptrFromObj(ob)))) if ((newzl = (unsigned char*)activeDefragAlloc(ptrFromObj(ob))))
defragged++, ob->m_ptr = newzl; defragged++, ob->m_ptr = newzl;
} else { } else {
serverPanic("Unknown list encoding"); serverPanic("Unknown list encoding");
@ -799,15 +799,15 @@ long defragKey(redisDb *db, dictEntry *de) {
if (ob->encoding == OBJ_ENCODING_HT) { if (ob->encoding == OBJ_ENCODING_HT) {
defragged += defragSet(db, de); defragged += defragSet(db, de);
} else if (ob->encoding == OBJ_ENCODING_INTSET) { } else if (ob->encoding == OBJ_ENCODING_INTSET) {
intset *newis, *is = ptrFromObj(ob); intset *newis, *is = (intset*)ptrFromObj(ob);
if ((newis = activeDefragAlloc(is))) if ((newis = (intset*)activeDefragAlloc(is)))
defragged++, ob->m_ptr = newis; defragged++, ob->m_ptr = newis;
} else { } else {
serverPanic("Unknown set encoding"); serverPanic("Unknown set encoding");
} }
} else if (ob->type == OBJ_ZSET) { } else if (ob->type == OBJ_ZSET) {
if (ob->encoding == OBJ_ENCODING_ZIPLIST) { if (ob->encoding == OBJ_ENCODING_ZIPLIST) {
if ((newzl = activeDefragAlloc(ptrFromObj(ob)))) if ((newzl = (unsigned char*)activeDefragAlloc(ptrFromObj(ob))))
defragged++, ob->m_ptr = newzl; defragged++, ob->m_ptr = newzl;
} else if (ob->encoding == OBJ_ENCODING_SKIPLIST) { } else if (ob->encoding == OBJ_ENCODING_SKIPLIST) {
defragged += defragZsetSkiplist(db, de); defragged += defragZsetSkiplist(db, de);
@ -816,7 +816,7 @@ long defragKey(redisDb *db, dictEntry *de) {
} }
} else if (ob->type == OBJ_HASH) { } else if (ob->type == OBJ_HASH) {
if (ob->encoding == OBJ_ENCODING_ZIPLIST) { if (ob->encoding == OBJ_ENCODING_ZIPLIST) {
if ((newzl = activeDefragAlloc(ptrFromObj(ob)))) if ((newzl = (unsigned char*)activeDefragAlloc(ptrFromObj(ob))))
defragged++, ob->m_ptr = newzl; defragged++, ob->m_ptr = newzl;
} else if (ob->encoding == OBJ_ENCODING_HT) { } else if (ob->encoding == OBJ_ENCODING_HT) {
defragged += defragHash(db, de); 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 */ UNUSED(privdata); /* NOTE: this function is also used by both activeDefragCycle and scanLaterHash, etc. don't use privdata */
while(*bucketref) { while(*bucketref) {
dictEntry *de = *bucketref, *newde; dictEntry *de = *bucketref, *newde;
if ((newde = activeDefragAlloc(de))) { if ((newde = (dictEntry*)activeDefragAlloc(de))) {
*bucketref = newde; *bucketref = newde;
} }
bucketref = &(*bucketref)->next; bucketref = &(*bucketref)->next;
@ -896,7 +896,7 @@ long defragOtherGlobals() {
* and 1 if time is up and more work is needed. */ * and 1 if time is up and more work is needed. */
int defragLaterItem(dictEntry *de, unsigned long *cursor, long long endtime) { int defragLaterItem(dictEntry *de, unsigned long *cursor, long long endtime) {
if (de) { if (de) {
robj *ob = dictGetVal(de); robj *ob = (robj*)dictGetVal(de);
if (ob->type == OBJ_LIST) { if (ob->type == OBJ_LIST) {
server.stat_active_defrag_hits += scanLaterList(ob); server.stat_active_defrag_hits += scanLaterList(ob);
*cursor = 0; /* list has no scan, we must finish it in one go */ *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 */ /* Move on to next key */
if (current_key) { if (current_key) {
serverAssert(current_key == head->value); serverAssert(current_key == head->value);
sdsfree(head->value); sdsfree((sds)head->value);
listDelNode(db->defrag_later, head); listDelNode(db->defrag_later, head);
cursor = 0; cursor = 0;
current_key = NULL; current_key = NULL;
@ -946,7 +946,7 @@ int defragLaterStep(redisDb *db, long long endtime) {
return 0; return 0;
/* start a new key */ /* start a new key */
current_key = head->value; current_key = (sds)head->value;
cursor = 0; cursor = 0;
} }

View File

@ -39,6 +39,10 @@
extern "C" { extern "C" {
#endif #endif
#ifndef __cplusplus
#error "C++ Only"
#endif
#ifndef __DICT_H #ifndef __DICT_H
#define __DICT_H #define __DICT_H

View File

@ -140,7 +140,7 @@ void evictionPoolAlloc(void) {
struct evictionPoolEntry *ep; struct evictionPoolEntry *ep;
int j; 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++) { for (j = 0; j < EVPOOL_SIZE; j++) {
ep[j].idle = 0; ep[j].idle = 0;
ep[j].key = NULL; ep[j].key = NULL;
@ -161,7 +161,7 @@ void evictionPoolAlloc(void) {
void evictionPoolPopulate(int dbid, dict *sampledict, dict *keydict, struct evictionPoolEntry *pool) { void evictionPoolPopulate(int dbid, dict *sampledict, dict *keydict, struct evictionPoolEntry *pool) {
int j, k, count; 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); count = dictGetSomeKeys(sampledict,samples,server.maxmemory_samples);
for (j = 0; j < count; j++) { for (j = 0; j < count; j++) {
@ -171,14 +171,14 @@ void evictionPoolPopulate(int dbid, dict *sampledict, dict *keydict, struct evic
dictEntry *de; dictEntry *de;
de = samples[j]; de = samples[j];
key = dictGetKey(de); key = (sds)dictGetKey(de);
/* If the dictionary we are sampling from is not the main /* If the dictionary we are sampling from is not the main
* dictionary (but the expires one) we need to lookup the key * dictionary (but the expires one) we need to lookup the key
* again in the key dictionary to obtain the value object. */ * again in the key dictionary to obtain the value object. */
if (server.maxmemory_policy != MAXMEMORY_VOLATILE_TTL) { if (server.maxmemory_policy != MAXMEMORY_VOLATILE_TTL) {
if (sampledict != keydict) de = dictFind(keydict, key); 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 /* Calculate the idle time according to the policy. This is called
@ -360,7 +360,7 @@ size_t freeMemoryGetNotCountedMemory(void) {
listRewind(server.slaves,&li); listRewind(server.slaves,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
client *slave = listNodeValue(ln); client *slave = (client*)listNodeValue(ln);
overhead += getClientOutputBufferMemoryUsage(slave); overhead += getClientOutputBufferMemoryUsage(slave);
} }
} }
@ -521,7 +521,7 @@ int freeMemoryIfNeeded(void) {
/* If the key exists, is our pick. Otherwise it is /* If the key exists, is our pick. Otherwise it is
* a ghost and we need to try the next element. */ * a ghost and we need to try the next element. */
if (de) { if (de) {
bestkey = dictGetKey(de); bestkey = (sds)dictGetKey(de);
break; break;
} else { } else {
/* Ghost... Iterate again. */ /* Ghost... Iterate again. */
@ -544,7 +544,7 @@ int freeMemoryIfNeeded(void) {
db->pdict : db->expires; db->pdict : db->expires;
if (dictSize(dict) != 0) { if (dictSize(dict) != 0) {
de = dictGetRandomKey(dict); de = dictGetRandomKey(dict);
bestkey = dictGetKey(de); bestkey = (sds)dictGetKey(de);
bestdbid = j; bestdbid = j;
break; break;
} }

View File

@ -54,7 +54,7 @@
int activeExpireCycleTryExpire(redisDb *db, dictEntry *de, long long now) { int activeExpireCycleTryExpire(redisDb *db, dictEntry *de, long long now) {
long long t = dictGetSignedIntegerVal(de); long long t = dictGetSignedIntegerVal(de);
if (now > t) { if (now > t) {
sds key = dictGetKey(de); sds key = (sds)dictGetKey(de);
robj *keyobj = createStringObject(key,sdslen(key)); robj *keyobj = createStringObject(key,sdslen(key));
propagateExpire(db,keyobj,server.lazyfree_lazy_expire); propagateExpire(db,keyobj,server.lazyfree_lazy_expire);
@ -290,7 +290,7 @@ void expireSlaveKeys(void) {
mstime_t start = mstime(); mstime_t start = mstime();
while(1) { while(1) {
dictEntry *de = dictGetRandomKey(slaveKeysWithExpire); dictEntry *de = dictGetRandomKey(slaveKeysWithExpire);
sds keyname = dictGetKey(de); sds keyname = (sds)dictGetKey(de);
uint64_t dbids = dictGetUnsignedIntegerVal(de); uint64_t dbids = dictGetUnsignedIntegerVal(de);
uint64_t new_dbids = 0; 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() * in sync with the main DB. The keys will be removed by expireSlaveKeys()
* as it scans to find keys to remove. */ * as it scans to find keys to remove. */
if (de->key == ptrFromObj(key)) { if (de->key == ptrFromObj(key)) {
de->key = sdsdup(ptrFromObj(key)); de->key = sdsdup(szFromObj(key));
dictSetUnsignedIntegerVal(de,0); dictSetUnsignedIntegerVal(de,0);
} }

View File

@ -51,7 +51,7 @@ int zslValueLteMax(double value, zrangespec *spec);
/* Create a new array of geoPoints. */ /* Create a new array of geoPoints. */
geoArray *geoArrayCreate(void) { 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. */ /* It gets allocated on first geoArrayAppend() call. */
ga->array = NULL; ga->array = NULL;
ga->buckets = 0; ga->buckets = 0;
@ -64,7 +64,7 @@ geoArray *geoArrayCreate(void) {
geoPoint *geoArrayAppend(geoArray *ga) { geoPoint *geoArrayAppend(geoArray *ga) {
if (ga->used == ga->buckets) { if (ga->used == ga->buckets) {
ga->buckets = (ga->buckets == 0) ? 8 : ga->buckets*2; 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; geoPoint *gp = ga->array+ga->used;
ga->used++; ga->used++;
@ -83,7 +83,7 @@ void geoArrayFree(geoArray *ga) {
* Helpers * Helpers
* ==================================================================== */ * ==================================================================== */
int decodeGeohash(double bits, double *xy) { 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); return geohashDecodeToLongLatWGS84(hash, xy);
} }
@ -113,7 +113,7 @@ int extractLongLatOrReply(client *c, robj **argv, double *xy) {
int longLatFromMember(robj *zobj, robj *member, double *xy) { int longLatFromMember(robj *zobj, robj *member, double *xy) {
double score = 0; 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; if (!decodeGeohash(score, xy)) return C_ERR;
return C_OK; 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 * If the unit is not valid, an error is reported to the client, and a value
* less than zero is returned. */ * less than zero is returned. */
double extractUnitOrReply(client *c, robj *unit) { double extractUnitOrReply(client *c, robj *unit) {
char *u = ptrFromObj(unit); char *u = szFromObj(unit);
if (!strcmp(u, "m")) { if (!strcmp(u, "m")) {
return 1; 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) { 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 */ /* minex 0 = include min in range; maxex 1 = exclude max in range */
/* That's: min <= val < max */ /* 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; size_t origincount = ga->used;
sds member; sds member;
if (zobj->encoding == OBJ_ENCODING_ZIPLIST) { 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 *eptr, *sptr;
unsigned char *vstr = NULL; unsigned char *vstr = NULL;
unsigned int vlen = 0; unsigned int vlen = 0;
@ -259,7 +259,7 @@ int geoGetPointsInRange(robj *zobj, double min, double max, double lon, double l
zzlNext(zl, &eptr, &sptr); zzlNext(zl, &eptr, &sptr);
} }
} else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) {
zset *zs = zobj->m_ptr; zset *zs = (zset*)zobj->m_ptr;
zskiplist *zsl = zs->zsl; zskiplist *zsl = zs->zsl;
zskiplistNode *ln; zskiplistNode *ln;
@ -277,7 +277,7 @@ int geoGetPointsInRange(robj *zobj, double min, double max, double lon, double l
ele = sdsdup(ele); ele = sdsdup(ele);
if (geoAppendIfWithinRadius(ga,lon,lat,radius,ln->score,ele) if (geoAppendIfWithinRadius(ga,lon,lat,radius,ln->score,ele)
== C_ERR) sdsfree(ele); == C_ERR) sdsfree(ele);
ln = ln->level[0].forward; ln = ln->level(0)->forward;
} }
} }
return ga->used - origincount; return ga->used - origincount;
@ -382,7 +382,7 @@ int membersOfAllNeighbors(robj *zobj, GeoHashRadius n, double lon, double lat, d
/* Sort comparators for qsort() */ /* Sort comparators for qsort() */
static int sort_gp_asc(const void *a, const void *b) { 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 /* We can't do adist - bdist because they are doubles and
* the comparator returns an int. */ * the comparator returns an int. */
if (gpa->dist > gpb->dist) if (gpa->dist > gpb->dist)
@ -413,7 +413,7 @@ void geoaddCommand(client *c) {
int elements = (c->argc - 2) / 3; int elements = (c->argc - 2) / 3;
int argc = 2+elements*2; /* ZADD key score ele ... */ 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[0] = createRawStringObject("zadd",4);
argv[1] = c->argv[1]; /* key */ argv[1] = c->argv[1]; /* key */
incrRefCount(argv[1]); incrRefCount(argv[1]);
@ -504,7 +504,7 @@ void georadiusGeneric(client *c, int flags) {
if (c->argc > base_args) { if (c->argc > base_args) {
int remaining = c->argc - base_args; int remaining = c->argc - base_args;
for (int i = 0; i < remaining; i++) { 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")) { if (!strcasecmp(arg, "withdist")) {
withdist = 1; withdist = 1;
} else if (!strcasecmp(arg, "withhash")) { } else if (!strcasecmp(arg, "withhash")) {
@ -639,7 +639,7 @@ void georadiusGeneric(client *c, int flags) {
if (returned_items) { if (returned_items) {
zobj = createZsetObject(); zobj = createZsetObject();
zs = zobj->m_ptr; zs = (zset*)zobj->m_ptr;
} }
for (i = 0; i < returned_items; i++) { 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 * Returns an array with an 11 characters geohash representation of the
* position of the specified elements. */ * position of the specified elements. */
void geohashCommand(client *c) { void geohashCommand(client *c) {
char *geoalphabet= "0123456789bcdefghjkmnpqrstuvwxyz"; const char *geoalphabet= "0123456789bcdefghjkmnpqrstuvwxyz";
int j; int j;
/* Look up the requested zset */ /* Look up the requested zset */
@ -709,7 +709,7 @@ void geohashCommand(client *c) {
addReplyArrayLen(c,c->argc-2); addReplyArrayLen(c,c->argc-2);
for (j = 2; j < c->argc; j++) { for (j = 2; j < c->argc; j++) {
double score; 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); addReplyNull(c);
} else { } else {
/* The internal format we use for geocoding is a bit different /* The internal format we use for geocoding is a bit different
@ -762,7 +762,7 @@ void geoposCommand(client *c) {
addReplyArrayLen(c,c->argc-2); addReplyArrayLen(c,c->argc-2);
for (j = 2; j < c->argc; j++) { for (j = 2; j < c->argc; j++) {
double score; 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); addReplyNullArray(c);
} else { } else {
/* Decode... */ /* Decode... */
@ -802,8 +802,8 @@ void geodistCommand(client *c) {
/* Get the scores. We need both otherwise NULL is returned. */ /* Get the scores. We need both otherwise NULL is returned. */
double score1, score2, xyxy[4]; double score1, score2, xyxy[4];
if (zsetScore(zobj, ptrFromObj(c->argv[2]), &score1) == C_ERR || if (zsetScore(zobj, szFromObj(c->argv[2]), &score1) == C_ERR ||
zsetScore(zobj, ptrFromObj(c->argv[3]), &score2) == C_ERR) zsetScore(zobj, szFromObj(c->argv[3]), &score2) == C_ERR)
{ {
addReplyNull(c); addReplyNull(c);
return; return;

View File

@ -1,97 +0,0 @@
/*
* Copyright (c) 2019, Salvatore Sanfilippo <antirez at gmail dot com>
* 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:
* <type><descr><TAB><selector><TAB><hostname><TAB><port>
* 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
* ".<CR><LF>" (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 .<CR><LF> 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 ".<CR><LF>" 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.
*/
}

View File

@ -184,7 +184,9 @@ struct hllhdr {
uint8_t encoding; /* HLL_DENSE or HLL_SPARSE. */ uint8_t encoding; /* HLL_DENSE or HLL_SPARSE. */
uint8_t notused[3]; /* Reserved for future use, must be zero. */ uint8_t notused[3]; /* Reserved for future use, must be zero. */
uint8_t card[8]; /* Cached cardinality, little endian. */ uint8_t card[8]; /* Cached cardinality, little endian. */
uint8_t registers[]; /* Data bytes. */ uint8_t *registers() { /* Data bytes. */
return reinterpret_cast<uint8_t*>(this+1);
}
}; };
/* The cached cardinality MSB is used to signal validity of the cached value. */ /* 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_RAW 255 /* Only used internally, never exposed. */
#define HLL_MAX_ENCODING 1 #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 ========================= */ /* =========================== 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, * The function returns C_OK if the sparse representation was valid,
* otherwise C_ERR is returned if the representation was corrupted. */ * otherwise C_ERR is returned if the representation was corrupted. */
int hllSparseToDense(robj *o) { int hllSparseToDense(robj *o) {
sds sparse = ptrFromObj(o), dense; sds sparse = szFromObj(o), dense;
struct hllhdr *hdr, *oldhdr = (struct hllhdr*)sparse; struct hllhdr *hdr, *oldhdr = (struct hllhdr*)sparse;
int idx = 0, runlen, regval; int idx = 0, runlen, regval;
uint8_t *p = (uint8_t*)sparse, *end = p+sdslen(sparse); uint8_t *p = (uint8_t*)sparse, *end = p+sdslen(sparse);
@ -616,7 +618,7 @@ int hllSparseToDense(robj *o) {
regval = HLL_SPARSE_VAL_VALUE(p); regval = HLL_SPARSE_VAL_VALUE(p);
if ((runlen + idx) > HLL_REGISTERS) break; /* Overflow. */ if ((runlen + idx) > HLL_REGISTERS) break; /* Overflow. */
while(runlen--) { while(runlen--) {
HLL_DENSE_SET_REGISTER(hdr->registers,idx,regval); HLL_DENSE_SET_REGISTER(hdr->registers(),idx,regval);
idx++; idx++;
} }
p++; p++;
@ -631,7 +633,7 @@ int hllSparseToDense(robj *o) {
} }
/* Free the old representation and set the new one. */ /* Free the old representation and set the new one. */
sdsfree(ptrFromObj(o)); sdsfree(szFromObj(o));
o->m_ptr = dense; o->m_ptr = dense;
return C_OK; return C_OK;
} }
@ -656,6 +658,13 @@ int hllSparseSet(robj *o, long index, uint8_t count) {
uint8_t oldcount, *sparse, *end, *p, *prev, *next; uint8_t oldcount, *sparse, *end, *p, *prev, *next;
long first, span; long first, span;
long is_zero = 0, is_xzero = 0, is_val = 0, runlen = 0; 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 /* If the count is too big to be representable by the sparse representation
* switch to dense 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 * into XZERO-VAL-XZERO). Make sure there is enough space right now
* so that the pointers we take during the execution of the function * so that the pointers we take during the execution of the function
* will be valid all the time. */ * 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 /* Step 1: we need to locate the opcode we need to modify to check
* if a value update is actually needed. */ * if a value update is actually needed. */
sparse = p = ((uint8_t*)ptrFromObj(o)) + HLL_HDR_SIZE; 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; first = 0;
prev = NULL; /* Points to previous opcode at the end of the loop. */ 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 * 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 * of the old one, possibly moving what is on the right a few bytes
* if the new sequence is longer than the older one. */ * if the new sequence is longer than the older one. */
uint8_t seq[5], *n = seq; n = seq;
int last = first+span-1; /* Last register covered by the sequence. */ last = first+span-1; /* Last register covered by the sequence. */
int len;
if (is_zero || is_xzero) { if (is_zero || is_xzero) {
/* Handle splitting of ZERO / 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 * Note that we already allocated space on the sds string
* calling sdsMakeRoomFor(). */ * calling sdsMakeRoomFor(). */
int seqlen = n-seq; seqlen = n-seq;
int oldlen = is_xzero ? 2 : 1; oldlen = is_xzero ? 2 : 1;
int deltalen = seqlen-oldlen; deltalen = seqlen-oldlen;
if (deltalen > 0 && 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); if (deltalen && next) memmove(next+deltalen,next,end-next);
sdsIncrLen(ptrFromObj(o),deltalen); sdsIncrLen(szFromObj(o),deltalen);
memcpy(p,seq,seqlen); memcpy(p,seq,seqlen);
end += deltalen; end += deltalen;
@ -842,7 +850,7 @@ updated:
* may not be optimal: adjacent VAL opcodes can sometimes be merged into * may not be optimal: adjacent VAL opcodes can sometimes be merged into
* a single one. */ * a single one. */
p = prev ? prev : sparse; 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--) { while (p < end && scanlen--) {
if (HLL_SPARSE_IS_XZERO(p)) { if (HLL_SPARSE_IS_XZERO(p)) {
p += 2; p += 2;
@ -861,7 +869,7 @@ updated:
if (len <= HLL_SPARSE_VAL_MAX_LEN) { if (len <= HLL_SPARSE_VAL_MAX_LEN) {
HLL_SPARSE_VAL_SET(p+1,v1,len); HLL_SPARSE_VAL_SET(p+1,v1,len);
memmove(p,p+1,end-p); memmove(p,p+1,end-p);
sdsIncrLen(ptrFromObj(o),-1); sdsIncrLen(szFromObj(o),-1);
end--; end--;
/* After a merge we reiterate without incrementing 'p' /* After a merge we reiterate without incrementing 'p'
* in order to try to merge the just merged value with * in order to try to merge the just merged value with
@ -874,13 +882,13 @@ updated:
} }
/* Invalidate the cached cardinality. */ /* Invalidate the cached cardinality. */
hdr = ptrFromObj(o); hdr = (hllhdr*)ptrFromObj(o);
HLL_INVALIDATE_CACHE(hdr); HLL_INVALIDATE_CACHE(hdr);
return 1; return 1;
promote: /* Promote to dense representation. */ promote: /* Promote to dense representation. */
if (hllSparseToDense(o) == C_ERR) return -1; /* Corrupted HLL. */ 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 /* We need to call hllDenseAdd() to perform the operation after the
* conversion. However the result must be 1, since if we need to * 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 * 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 * is propagated to slaves / AOF, so if there is a sparse -> dense
* conversion, it will be performed in all the slaves as well. */ * 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); serverAssert(dense_retval == 1);
return dense_retval; return dense_retval;
} }
@ -1007,7 +1015,7 @@ double hllTau(double x) {
* pointed by 'invalid' is set to non-zero, otherwise it is left untouched. * pointed by 'invalid' is set to non-zero, otherwise it is left untouched.
* *
* hllCount() supports a special internal-only encoding of HLL_RAW, that * 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 * This is useful in order to speedup PFCOUNT when called against multiple
* keys (no need to work with 6-bit integers encoding). */ * keys (no need to work with 6-bit integers encoding). */
uint64_t hllCount(struct hllhdr *hdr, int *invalid) { uint64_t hllCount(struct hllhdr *hdr, int *invalid) {
@ -1023,12 +1031,12 @@ uint64_t hllCount(struct hllhdr *hdr, int *invalid) {
/* Compute register histogram */ /* Compute register histogram */
if (hdr->encoding == HLL_DENSE) { if (hdr->encoding == HLL_DENSE) {
hllDenseRegHisto(hdr->registers,reghisto); hllDenseRegHisto(hdr->registers(),reghisto);
} else if (hdr->encoding == HLL_SPARSE) { } else if (hdr->encoding == HLL_SPARSE) {
hllSparseRegHisto(hdr->registers, hllSparseRegHisto(hdr->registers(),
sdslen((sds)hdr)-HLL_HDR_SIZE,invalid,reghisto); sdslen((sds)hdr)-HLL_HDR_SIZE,invalid,reghisto);
} else if (hdr->encoding == HLL_RAW) { } else if (hdr->encoding == HLL_RAW) {
hllRawRegHisto(hdr->registers,reghisto); hllRawRegHisto(hdr->registers(),reghisto);
} else { } else {
serverPanic("Unknown HyperLogLog encoding in hllCount()"); 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. */ /* Call hllDenseAdd() or hllSparseAdd() according to the HLL encoding. */
int hllAdd(robj *o, unsigned char *ele, size_t elesize) { int hllAdd(robj *o, unsigned char *ele, size_t elesize) {
struct hllhdr *hdr = ptrFromObj(o); struct hllhdr *hdr = (hllhdr*)ptrFromObj(o);
switch(hdr->encoding) { 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); case HLL_SPARSE: return hllSparseAdd(o,ele,elesize);
default: return -1; /* Invalid representation. */ 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 * If the HyperLogLog is sparse and is found to be invalid, C_ERR
* is returned, otherwise the function always succeeds. */ * is returned, otherwise the function always succeeds. */
int hllMerge(uint8_t *max, size_t cmax, robj *hll) { int hllMerge(uint8_t *max, size_t cmax, robj *hll) {
struct hllhdr *hdr = ptrFromObj(hll); struct hllhdr *hdr = (hllhdr*)ptrFromObj(hll);
int i; int i;
if (hdr->encoding == HLL_DENSE) { if (hdr->encoding == HLL_DENSE) {
uint8_t val; uint8_t val;
for (i = 0; i < HLL_REGISTERS; i++) { 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; if (val > max[i]) max[i] = val;
} }
} else { } 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; long runlen, regval;
p += HLL_HDR_SIZE; p += HLL_HDR_SIZE;
@ -1139,7 +1147,7 @@ robj *createHLLObject(void) {
/* Create the actual object. */ /* Create the actual object. */
o = createObject(OBJ_STRING,s); o = createObject(OBJ_STRING,s);
hdr = ptrFromObj(o); hdr = (hllhdr*)ptrFromObj(o);
memcpy(hdr->magic,"HYLL",4); memcpy(hdr->magic,"HYLL",4);
hdr->encoding = HLL_SPARSE; hdr->encoding = HLL_SPARSE;
return o; return o;
@ -1157,7 +1165,7 @@ int isHLLObjectOrReply(client *c, robj *o) {
if (!sdsEncodedObject(o)) goto invalid; if (!sdsEncodedObject(o)) goto invalid;
if (stringObjectLen(o) < sizeof(*hdr)) goto invalid; if (stringObjectLen(o) < sizeof(*hdr)) goto invalid;
hdr = ptrFromObj(o); hdr = (hllhdr*)ptrFromObj(o);
/* Magic should be "HYLL". */ /* Magic should be "HYLL". */
if (hdr->magic[0] != 'H' || hdr->magic[1] != 'Y' || 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. */ /* Perform the low level ADD operation for every element. */
for (j = 2; j < c->argc; j++) { for (j = 2; j < c->argc; j++) {
int retval = hllAdd(o, (unsigned char*)ptrFromObj(c->argv[j]), int retval = hllAdd(o, (unsigned char*)ptrFromObj(c->argv[j]),
sdslen(ptrFromObj(c->argv[j]))); sdslen(szFromObj(c->argv[j])));
switch(retval) { switch(retval) {
case 1: case 1:
updated++; updated++;
@ -1209,7 +1217,7 @@ void pfaddCommand(client *c) {
return; return;
} }
} }
hdr = ptrFromObj(o); hdr = (hllhdr*)ptrFromObj(o);
if (updated) { if (updated) {
signalModifiedKey(c->db,c->argv[1]); signalModifiedKey(c->db,c->argv[1]);
notifyKeyspaceEvent(NOTIFY_STRING,"pfadd",c->argv[1],c->db->id); 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); o = dbUnshareStringValue(c->db,c->argv[1],o);
/* Check if the cached cardinality is valid. */ /* Check if the cached cardinality is valid. */
hdr = ptrFromObj(o); hdr = (hllhdr*)ptrFromObj(o);
if (HLL_VALID_CACHE(hdr)) { if (HLL_VALID_CACHE(hdr)) {
/* Just return the cached value. */ /* Just return the cached value. */
card = (uint64_t)hdr->card[0]; 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 /* If at least one involved HLL is dense, use the dense representation
* as target ASAP to save time and avoid the conversion step. */ * 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; if (hdr->encoding == HLL_DENSE) use_dense = 1;
/* Merge with this HLL with our 'max' HHL by setting max[i] /* Merge with this HLL with our 'max' HHL by setting max[i]
@ -1365,13 +1373,13 @@ void pfmergeCommand(client *c) {
* invalidate the cached value. */ * invalidate the cached value. */
for (j = 0; j < HLL_REGISTERS; j++) { for (j = 0; j < HLL_REGISTERS; j++) {
if (max[j] == 0) continue; if (max[j] == 0) continue;
hdr = ptrFromObj(o); hdr = (hllhdr*)ptrFromObj(o);
switch(hdr->encoding) { 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; 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. */ last hllSparseSet() call. */
HLL_INVALIDATE_CACHE(hdr); HLL_INVALIDATE_CACHE(hdr);
@ -1395,6 +1403,10 @@ void pfselftestCommand(client *c) {
struct hllhdr *hdr = (struct hllhdr*) bitcounters, *hdr2; struct hllhdr *hdr = (struct hllhdr*) bitcounters, *hdr2;
robj *o = NULL; robj *o = NULL;
uint8_t bytecounters[HLL_REGISTERS]; uint8_t bytecounters[HLL_REGISTERS];
int64_t checkpoint = 1;
uint64_t seed = 0;
uint64_t ele;
double relerr = 0;
/* Test 1: access registers. /* Test 1: access registers.
* The test is conceived to test that the different counters of our data * 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; unsigned int r = rand() & HLL_REGISTER_MAX;
bytecounters[i] = r; 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. */ /* Check that we are able to retrieve the same values. */
for (i = 0; i < HLL_REGISTERS; i++) { for (i = 0; i < HLL_REGISTERS; i++) {
unsigned int val; unsigned int val;
HLL_DENSE_GET_REGISTER(val,hdr->registers,i); HLL_DENSE_GET_REGISTER(val,hdr->registers(),i);
if (val != bytecounters[i]) { if (val != bytecounters[i]) {
addReplyErrorFormat(c, addReplyErrorFormat(c,
"TESTFAILED Register %d should be %d but is %d", "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 * The test is performed with both dense and sparse HLLs at the same
* time also verifying that the computed cardinality is 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(); o = createHLLObject();
double relerr = 1.04/sqrt(HLL_REGISTERS); relerr = 1.04/sqrt(HLL_REGISTERS);
int64_t checkpoint = 1; checkpoint = 1;
uint64_t seed = (uint64_t)rand() | (uint64_t)rand() << 32; seed = (uint64_t)rand() | (uint64_t)rand() << 32;
uint64_t ele;
for (j = 1; j <= 10000000; j++) { for (j = 1; j <= 10000000; j++) {
ele = j ^ seed; 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)); hllAdd(o,(unsigned char*)&ele,sizeof(ele));
/* Make sure that for small cardinalities we use sparse /* Make sure that for small cardinalities we use sparse
* encoding. */ * encoding. */
if (j == checkpoint && j < server.hll_sparse_max_bytes/2) { if (j == checkpoint && j < server.hll_sparse_max_bytes/2) {
hdr2 = ptrFromObj(o); hdr2 = (hllhdr*)ptrFromObj(o);
if (hdr2->encoding != HLL_SPARSE) { if (hdr2->encoding != HLL_SPARSE) {
addReplyError(c, "TESTFAILED sparse encoding not used"); addReplyError(c, "TESTFAILED sparse encoding not used");
goto cleanup; goto cleanup;
@ -1455,7 +1466,7 @@ void pfselftestCommand(client *c) {
} }
/* Check that dense and sparse representations agree. */ /* 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"); addReplyError(c, "TESTFAILED dense/sparse disagree");
goto cleanup; goto cleanup;
} }
@ -1494,7 +1505,7 @@ cleanup:
/* PFDEBUG <subcommand> <key> ... args ... /* PFDEBUG <subcommand> <key> ... args ...
* Different debugging related operations about the HLL implementation. */ * Different debugging related operations about the HLL implementation. */
void pfdebugCommand(client *c) { void pfdebugCommand(client *c) {
char *cmd = ptrFromObj(c->argv[1]); char *cmd = szFromObj(c->argv[1]);
struct hllhdr *hdr; struct hllhdr *hdr;
robj *o; robj *o;
int j; int j;
@ -1506,7 +1517,7 @@ void pfdebugCommand(client *c) {
} }
if (isHLLObjectOrReply(c,o) != C_OK) return; if (isHLLObjectOrReply(c,o) != C_OK) return;
o = dbUnshareStringValue(c->db,c->argv[2],o); o = dbUnshareStringValue(c->db,c->argv[2],o);
hdr = ptrFromObj(o); hdr = (hllhdr*)ptrFromObj(o);
/* PFDEBUG GETREG <key> */ /* PFDEBUG GETREG <key> */
if (!strcasecmp(cmd,"getreg")) { if (!strcasecmp(cmd,"getreg")) {
@ -1520,12 +1531,12 @@ void pfdebugCommand(client *c) {
server.dirty++; /* Force propagation on encoding change. */ server.dirty++; /* Force propagation on encoding change. */
} }
hdr = ptrFromObj(o); hdr = (hllhdr*)ptrFromObj(o);
addReplyArrayLen(c,HLL_REGISTERS); addReplyArrayLen(c,HLL_REGISTERS);
for (j = 0; j < HLL_REGISTERS; j++) { for (j = 0; j < HLL_REGISTERS; j++) {
uint8_t val; uint8_t val;
HLL_DENSE_GET_REGISTER(val,hdr->registers,j); HLL_DENSE_GET_REGISTER(val,hdr->registers(),j);
addReplyLongLong(c,val); addReplyLongLong(c,val);
} }
} }
@ -1533,7 +1544,7 @@ void pfdebugCommand(client *c) {
else if (!strcasecmp(cmd,"decode")) { else if (!strcasecmp(cmd,"decode")) {
if (c->argc != 3) goto arityerr; 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(); sds decoded = sdsempty();
if (hdr->encoding != HLL_SPARSE) { if (hdr->encoding != HLL_SPARSE) {
@ -1566,7 +1577,7 @@ void pfdebugCommand(client *c) {
} }
/* PFDEBUG ENCODING <key> */ /* PFDEBUG ENCODING <key> */
else if (!strcasecmp(cmd,"encoding")) { else if (!strcasecmp(cmd,"encoding")) {
char *encodingstr[2] = {"dense","sparse"}; const char *encodingstr[2] = {"dense","sparse"};
if (c->argc != 3) goto arityerr; if (c->argc != 3) goto arityerr;
addReplyStatus(c,encodingstr[hdr->encoding]); addReplyStatus(c,encodingstr[hdr->encoding]);

View File

@ -38,11 +38,11 @@
/* Dictionary type for latency events. */ /* Dictionary type for latency events. */
int dictStringKeyCompare(void *privdata, const void *key1, const void *key2) { int dictStringKeyCompare(void *privdata, const void *key1, const void *key2) {
UNUSED(privdata); UNUSED(privdata);
return strcmp(key1,key2) == 0; return strcmp((const char*)key1,(const char*)key2) == 0;
} }
uint64_t dictStringHash(const void *key) { uint64_t dictStringHash(const void *key) {
return dictGenHashFunction(key, strlen(key)); return dictGenHashFunction(key, strlen((const char*)key));
} }
void dictVanillaFree(void *privdata, void *val); 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 * is a macro that only adds the sample if the latency is higher than
* server.latency_monitor_threshold. */ * server.latency_monitor_threshold. */
void latencyAddSample(const char *event, mstime_t latency) { 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); time_t now = time(NULL);
int prev; int prev;
/* Create the time series if it does not exist. */ /* Create the time series if it does not exist. */
if (ts == NULL) { if (ts == NULL) {
ts = zmalloc(sizeof(*ts), MALLOC_SHARED); ts = (latencyTimeSeries*)zmalloc(sizeof(*ts), MALLOC_SHARED);
ts->idx = 0; ts->idx = 0;
ts->max = 0; ts->max = 0;
memset(ts->samples,0,sizeof(ts->samples)); memset(ts->samples,0,sizeof(ts->samples));
@ -139,7 +139,7 @@ int latencyResetEvent(char *event_to_reset) {
di = dictGetSafeIterator(server.latency_events); di = dictGetSafeIterator(server.latency_events);
while((de = dictNext(di)) != NULL) { 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) { if (event_to_reset == NULL || strcasecmp(event,event_to_reset) == 0) {
dictDelete(server.latency_events, event); 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 * If the specified event has no elements the structure is populate with
* zero values. */ * zero values. */
void analyzeLatencyForEvent(char *event, struct latencyStats *ls) { 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; int j;
uint64_t sum; uint64_t sum;
@ -251,8 +251,8 @@ sds createLatencyReport(void) {
di = dictGetSafeIterator(server.latency_events); di = dictGetSafeIterator(server.latency_events);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
char *event = dictGetKey(de); char *event = (char*)dictGetKey(de);
struct latencyTimeSeries *ts = dictGetVal(de); struct latencyTimeSeries *ts = (latencyTimeSeries*)dictGetVal(de);
struct latencyStats ls; struct latencyStats ls;
if (ts == NULL) continue; if (ts == NULL) continue;
@ -273,7 +273,7 @@ sds createLatencyReport(void) {
/* Fork */ /* Fork */
if (!strcasecmp(event,"fork")) { if (!strcasecmp(event,"fork")) {
char *fork_quality; const char *fork_quality;
if (server.stat_fork_rate < 10) { if (server.stat_fork_rate < 10) {
fork_quality = "terrible"; fork_quality = "terrible";
advise_better_vm = 1; advise_better_vm = 1;
@ -500,8 +500,8 @@ void latencyCommandReplyWithLatestEvents(client *c) {
addReplyArrayLen(c,dictSize(server.latency_events)); addReplyArrayLen(c,dictSize(server.latency_events));
di = dictGetIterator(server.latency_events); di = dictGetIterator(server.latency_events);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
char *event = dictGetKey(de); char *event = (char*)dictGetKey(de);
struct latencyTimeSeries *ts = dictGetVal(de); struct latencyTimeSeries *ts = (latencyTimeSeries*)dictGetVal(de);
int last = (ts->idx + LATENCY_TS_LEN - 1) % LATENCY_TS_LEN; int last = (ts->idx + LATENCY_TS_LEN - 1) % LATENCY_TS_LEN;
addReplyArrayLen(c,4); addReplyArrayLen(c,4);
@ -579,15 +579,15 @@ NULL
}; };
struct latencyTimeSeries *ts; 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 <event> */ /* LATENCY HISTORY <event> */
ts = dictFetchValue(server.latency_events,ptrFromObj(c->argv[2])); ts = (latencyTimeSeries*)dictFetchValue(server.latency_events,ptrFromObj(c->argv[2]));
if (ts == NULL) { if (ts == NULL) {
addReplyArrayLen(c,0); addReplyArrayLen(c,0);
} else { } else {
latencyCommandReplyWithSamples(c,ts); 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 <event> */ /* LATENCY GRAPH <event> */
sds graph; sds graph;
dictEntry *de; dictEntry *de;
@ -595,22 +595,22 @@ NULL
de = dictFind(server.latency_events,ptrFromObj(c->argv[2])); de = dictFind(server.latency_events,ptrFromObj(c->argv[2]));
if (de == NULL) goto nodataerr; if (de == NULL) goto nodataerr;
ts = dictGetVal(de); ts = (latencyTimeSeries*)dictGetVal(de);
event = dictGetKey(de); event = (char*)dictGetKey(de);
graph = latencyCommandGenSparkeline(event,ts); graph = latencyCommandGenSparkeline(event,ts);
addReplyBulkCString(c,graph); addReplyBulkCString(c,graph);
sdsfree(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 */ /* LATENCY LATEST */
latencyCommandReplyWithLatestEvents(c); 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 */ /* LATENCY DOCTOR */
sds report = createLatencyReport(); sds report = createLatencyReport();
addReplyBulkCBuffer(c,report,sdslen(report)); addReplyBulkCBuffer(c,report,sdslen(report));
sdsfree(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 */ /* LATENCY RESET */
if (c->argc == 2) { if (c->argc == 2) {
addReplyLongLong(c,latencyResetEvent(NULL)); addReplyLongLong(c,latencyResetEvent(NULL));
@ -618,10 +618,10 @@ NULL
int j, resets = 0; int j, resets = 0;
for (j = 2; j < c->argc; j++) for (j = 2; j < c->argc; j++)
resets += latencyResetEvent(ptrFromObj(c->argv[j])); resets += latencyResetEvent(szFromObj(c->argv[j]));
addReplyLongLong(c,resets); 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); addReplyHelp(c, help);
} else { } else {
addReplySubcommandSyntaxError(c); addReplySubcommandSyntaxError(c);

View File

@ -30,16 +30,16 @@ size_t lazyfreeGetPendingObjectsCount(void) {
* representing the list. */ * representing the list. */
size_t lazyfreeGetFreeEffort(robj *obj) { size_t lazyfreeGetFreeEffort(robj *obj) {
if (obj->type == OBJ_LIST) { if (obj->type == OBJ_LIST) {
quicklist *ql = ptrFromObj(obj); quicklist *ql = (quicklist*)ptrFromObj(obj);
return ql->len; return ql->len;
} else if (obj->type == OBJ_SET && obj->encoding == OBJ_ENCODING_HT) { } else if (obj->type == OBJ_SET && obj->encoding == OBJ_ENCODING_HT) {
dict *ht = ptrFromObj(obj); dict *ht = (dict*)ptrFromObj(obj);
return dictSize(ht); return dictSize(ht);
} else if (obj->type == OBJ_ZSET && obj->encoding == OBJ_ENCODING_SKIPLIST){ } else if (obj->type == OBJ_ZSET && obj->encoding == OBJ_ENCODING_SKIPLIST){
zset *zs = ptrFromObj(obj); zset *zs = (zset*)ptrFromObj(obj);
return zs->zsl->length; return zs->zsl->length;
} else if (obj->type == OBJ_HASH && obj->encoding == OBJ_ENCODING_HT) { } else if (obj->type == OBJ_HASH && obj->encoding == OBJ_ENCODING_HT) {
dict *ht = ptrFromObj(obj); dict *ht = (dict*)ptrFromObj(obj);
return dictSize(ht); return dictSize(ht);
} else { } else {
return 1; /* Everything else is a single allocation. */ return 1; /* Everything else is a single allocation. */
@ -61,7 +61,7 @@ int dbAsyncDelete(redisDb *db, robj *key) {
* the object synchronously. */ * the object synchronously. */
dictEntry *de = dictUnlink(db->pdict,ptrFromObj(key)); dictEntry *de = dictUnlink(db->pdict,ptrFromObj(key));
if (de) { if (de) {
robj *val = dictGetVal(de); robj *val = (robj*)dictGetVal(de);
size_t free_effort = lazyfreeGetFreeEffort(val); size_t free_effort = lazyfreeGetFreeEffort(val);
/* If releasing the object is too much work, do it in the background /* If releasing the object is too much work, do it in the background

View File

@ -1,56 +0,0 @@
/*
* Copyright (c) 2018, Salvatore Sanfilippo <antirez at gmail dot com>
* 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);
}

View File

@ -1,282 +0,0 @@
/*
* Copyright (c) 2018, Salvatore Sanfilippo <antirez at gmail dot com>
* 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 <math.h>
/* 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 <stdio.h>
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);
}

View File

@ -48,6 +48,10 @@
#define LZF_VERSION 0x0105 /* 1.5, API version */ #define LZF_VERSION 0x0105 /* 1.5, API version */
#ifdef __cplusplus
extern "C" {
#endif
/* /*
* Compress in_len bytes stored at the memory block starting at * 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 * 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, lzf_decompress (const void *const in_data, unsigned int in_len,
void *out_data, unsigned int out_len); void *out_data, unsigned int out_len);
#ifdef __cplusplus
}
#endif
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -58,12 +58,12 @@ void queueMultiCommand(client *c) {
multiCmd *mc; multiCmd *mc;
int j; 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); sizeof(multiCmd)*(c->mstate.count+1), MALLOC_LOCAL);
mc = c->mstate.commands+c->mstate.count; mc = c->mstate.commands+c->mstate.count;
mc->cmd = c->cmd; mc->cmd = c->cmd;
mc->argc = c->argc; 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); memcpy(mc->argv,c->argv,sizeof(robj*)*c->argc);
for (j = 0; j < c->argc; j++) for (j = 0; j < c->argc; j++)
incrRefCount(mc->argv[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 * rest was not. We need to make sure to at least terminate the
* backlog with the final EXEC. */ * backlog with the final EXEC. */
if (server.repl_backlog && was_master && !is_master) { 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)); feedReplicationBacklog(execcmd,strlen(execcmd));
} }
} }
@ -243,12 +243,12 @@ void watchForKey(client *c, robj *key) {
/* Check if we are already watching for this key */ /* Check if we are already watching for this key */
listRewind(c->watched_keys,&li); listRewind(c->watched_keys,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
wk = listNodeValue(ln); wk = (watchedKey*)listNodeValue(ln);
if (wk->db == c->db && equalStringObjects(key,wk->key)) if (wk->db == c->db && equalStringObjects(key,wk->key))
return; /* Key already watched */ return; /* Key already watched */
} }
/* This key is not already watched in this DB. Let's add it */ /* 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) { if (!clients) {
clients = listCreate(); clients = listCreate();
dictAdd(c->db->watched_keys,key,clients); dictAdd(c->db->watched_keys,key,clients);
@ -256,7 +256,7 @@ void watchForKey(client *c, robj *key) {
} }
listAddNodeTail(clients,c); listAddNodeTail(clients,c);
/* Add the new key to the list of keys watched by this client */ /* 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->key = key;
wk->db = c->db; wk->db = c->db;
incrRefCount(key); incrRefCount(key);
@ -277,8 +277,8 @@ void unwatchAllKeys(client *c) {
/* Lookup the watched key -> clients list and remove the client /* Lookup the watched key -> clients list and remove the client
* from the list */ * from the list */
wk = listNodeValue(ln); wk = (watchedKey*)listNodeValue(ln);
clients = dictFetchValue(wk->db->watched_keys, wk->key); clients = (decltype(clients))dictFetchValue(wk->db->watched_keys, wk->key);
serverAssertWithInfo(c,NULL,clients != NULL); serverAssertWithInfo(c,NULL,clients != NULL);
listDelNode(clients,listSearchKey(clients,c)); listDelNode(clients,listSearchKey(clients,c));
/* Kill the entry at all if this was the only client */ /* Kill the entry at all if this was the only client */
@ -300,14 +300,14 @@ void touchWatchedKey(redisDb *db, robj *key) {
listNode *ln; listNode *ln;
if (dictSize(db->watched_keys) == 0) return; if (dictSize(db->watched_keys) == 0) return;
clients = dictFetchValue(db->watched_keys, key); clients = (list*)dictFetchValue(db->watched_keys, key);
if (!clients) return; if (!clients) return;
/* Mark all the clients watching this key as CLIENT_DIRTY_CAS */ /* Mark all the clients watching this key as CLIENT_DIRTY_CAS */
/* Check if we are already watching for this key */ /* Check if we are already watching for this key */
listRewind(clients,&li); listRewind(clients,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
client *c = listNodeValue(ln); client *c = (client*)listNodeValue(ln);
c->flags |= CLIENT_DIRTY_CAS; c->flags |= CLIENT_DIRTY_CAS;
} }
@ -325,10 +325,10 @@ void touchWatchedKeysOnFlush(int dbid) {
/* For every client, check all the waited keys */ /* For every client, check all the waited keys */
listRewind(server.clients,&li1); listRewind(server.clients,&li1);
while((ln = listNext(&li1))) { while((ln = listNext(&li1))) {
client *c = listNodeValue(ln); client *c = (client*)listNodeValue(ln);
listRewind(c->watched_keys,&li2); listRewind(c->watched_keys,&li2);
while((ln = listNext(&li2))) { while((ln = listNext(&li2))) {
watchedKey *wk = listNodeValue(ln); watchedKey *wk = (watchedKey*)listNodeValue(ln);
/* For every watched key matching the specified DB, if the /* For every watched key matching the specified DB, if the
* key exists, mark the client as dirty, as the key will be * key exists, mark the client as dirty, as the key will be

View File

@ -1991,17 +1991,6 @@ void processInputBuffer(client *c, int callFlags) {
if (c->reqtype == PROTO_REQ_INLINE) { if (c->reqtype == PROTO_REQ_INLINE) {
if (processInlineBuffer(c) != C_OK) break; 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) { } else if (c->reqtype == PROTO_REQ_MULTIBULK) {
if (processMultibulkBuffer(c) != C_OK) break; if (processMultibulkBuffer(c) != C_OK) break;
} else { } else {

View File

@ -119,7 +119,7 @@ void notifyKeyspaceEvent(int type, const char *event, robj *key, int dbid) {
len = ll2string(buf,sizeof(buf),dbid); len = ll2string(buf,sizeof(buf),dbid);
chan = sdscatlen(chan, buf, len); chan = sdscatlen(chan, buf, len);
chan = sdscatlen(chan, "__:", 3); chan = sdscatlen(chan, "__:", 3);
chan = sdscatsds(chan, ptrFromObj(key)); chan = sdscatsds(chan, szFromObj(key));
chanobj = createObject(OBJ_STRING, chan); chanobj = createObject(OBJ_STRING, chan);
pubsubPublishMessage(chanobj, eventobj); pubsubPublishMessage(chanobj, eventobj);
decrRefCount(chanobj); 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); if (len == -1) len = ll2string(buf,sizeof(buf),dbid);
chan = sdscatlen(chan, buf, len); chan = sdscatlen(chan, buf, len);
chan = sdscatlen(chan, "__:", 3); chan = sdscatlen(chan, "__:", 3);
chan = sdscatsds(chan, ptrFromObj(eventobj)); chan = sdscatsds(chan, szFromObj(eventobj));
chanobj = createObject(OBJ_STRING, chan); chanobj = createObject(OBJ_STRING, chan);
pubsubPublishMessage(chanobj, key); pubsubPublishMessage(chanobj, key);
decrRefCount(chanobj); decrRefCount(chanobj);

View File

@ -39,7 +39,7 @@
/* ===================== Creation and parsing of objects ==================== */ /* ===================== Creation and parsing of objects ==================== */
robj *createObject(int type, void *ptr) { 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->type = type;
o->encoding = OBJ_ENCODING_RAW; o->encoding = OBJ_ENCODING_RAW;
o->m_ptr = ptr; o->m_ptr = ptr;
@ -85,8 +85,8 @@ robj *createEmbeddedStringObject(const char *ptr, size_t len) {
size_t allocsize = sizeof(struct sdshdr8)+len+1; size_t allocsize = sizeof(struct sdshdr8)+len+1;
if (allocsize < sizeof(void*)) if (allocsize < sizeof(void*))
allocsize = sizeof(void*); allocsize = sizeof(void*);
robj *o = zmalloc(sizeof(robj)+allocsize-sizeof(o->m_ptr), MALLOC_SHARED); robj *o = (robj*)zmalloc(sizeof(robj)+allocsize-sizeof(o->m_ptr), MALLOC_SHARED);
struct sdshdr8 *sh = (void*)(&o->m_ptr); struct sdshdr8 *sh = (sdshdr8*)(&o->m_ptr);
o->type = OBJ_STRING; o->type = OBJ_STRING;
o->encoding = OBJ_ENCODING_EMBSTR; o->encoding = OBJ_ENCODING_EMBSTR;
@ -101,12 +101,12 @@ robj *createEmbeddedStringObject(const char *ptr, size_t len) {
sh->alloc = len; sh->alloc = len;
sh->flags = SDS_TYPE_8; sh->flags = SDS_TYPE_8;
if (ptr == SDS_NOINIT) if (ptr == SDS_NOINIT)
sh->buf[len] = '\0'; sh->buf()[len] = '\0';
else if (ptr) { else if (ptr) {
memcpy(sh->buf,ptr,len); memcpy(sh->buf(),ptr,len);
sh->buf[len] = '\0'; sh->buf()[len] = '\0';
} else { } else {
memset(sh->buf,0,len+1); memset(sh->buf(),0,len+1);
} }
return o; return o;
} }
@ -199,9 +199,9 @@ robj *dupStringObject(const robj *o) {
switch(o->encoding) { switch(o->encoding) {
case OBJ_ENCODING_RAW: case OBJ_ENCODING_RAW:
return createRawStringObject(ptrFromObj(o),sdslen(ptrFromObj(o))); return createRawStringObject(szFromObj(o),sdslen(szFromObj(o)));
case OBJ_ENCODING_EMBSTR: case OBJ_ENCODING_EMBSTR:
return createEmbeddedStringObject(ptrFromObj(o),sdslen(ptrFromObj(o))); return createEmbeddedStringObject(szFromObj(o),sdslen(szFromObj(o)));
case OBJ_ENCODING_INT: case OBJ_ENCODING_INT:
d = createObject(OBJ_STRING, NULL); d = createObject(OBJ_STRING, NULL);
d->encoding = OBJ_ENCODING_INT; d->encoding = OBJ_ENCODING_INT;
@ -249,7 +249,7 @@ robj *createHashObject(void) {
} }
robj *createZsetObject(void) { robj *createZsetObject(void) {
zset *zs = zmalloc(sizeof(*zs), MALLOC_SHARED); zset *zs = (zset*)zmalloc(sizeof(*zs), MALLOC_SHARED);
robj *o; robj *o;
zs->pdict = dictCreate(&zsetDictType,NULL); zs->pdict = dictCreate(&zsetDictType,NULL);
@ -274,7 +274,7 @@ robj *createStreamObject(void) {
} }
robj *createModuleObject(moduleType *mt, void *value) { 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->type = mt;
mv->value = value; mv->value = value;
return createObject(OBJ_MODULE,mv); return createObject(OBJ_MODULE,mv);
@ -282,13 +282,13 @@ robj *createModuleObject(moduleType *mt, void *value) {
void freeStringObject(robj *o) { void freeStringObject(robj *o) {
if (o->encoding == OBJ_ENCODING_RAW) { if (o->encoding == OBJ_ENCODING_RAW) {
sdsfree(ptrFromObj(o)); sdsfree(szFromObj(o));
} }
} }
void freeListObject(robj *o) { void freeListObject(robj *o) {
if (o->encoding == OBJ_ENCODING_QUICKLIST) { if (o->encoding == OBJ_ENCODING_QUICKLIST) {
quicklistRelease(ptrFromObj(o)); quicklistRelease((quicklist*)ptrFromObj(o));
} else { } else {
serverPanic("Unknown list encoding type"); serverPanic("Unknown list encoding type");
} }
@ -311,7 +311,7 @@ void freeZsetObject(robj *o) {
zset *zs; zset *zs;
switch (o->encoding) { switch (o->encoding) {
case OBJ_ENCODING_SKIPLIST: case OBJ_ENCODING_SKIPLIST:
zs = ptrFromObj(o); zs = (zset*)ptrFromObj(o);
dictRelease(zs->pdict); dictRelease(zs->pdict);
zslFree(zs->zsl); zslFree(zs->zsl);
zfree(zs); zfree(zs);
@ -339,13 +339,13 @@ void freeHashObject(robj *o) {
} }
void freeModuleObject(robj *o) { void freeModuleObject(robj *o) {
moduleValue *mv = ptrFromObj(o); moduleValue *mv = (moduleValue*)ptrFromObj(o);
mv->type->free(mv->value); mv->type->free(mv->value);
zfree(mv); zfree(mv);
} }
void freeStreamObject(robj *o) { void freeStreamObject(robj *o) {
freeStream(ptrFromObj(o)); freeStream((stream*)ptrFromObj(o));
} }
void incrRefCount(robj *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*)' * as free method in data structures that expect a 'void free_object(void*)'
* prototype for the free method. */ * prototype for the free method. */
void decrRefCountVoid(void *o) { void decrRefCountVoid(void *o) {
decrRefCount(o); decrRefCount((robj*)o);
} }
/* This function set the ref count to zero without freeing the object. /* 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); if (llval) *llval = (long) ptrFromObj(o);
return C_OK; return C_OK;
} else { } 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. */ * wasting too much time in allocations when appending to the string. */
void trimStringObjectIfNeeded(robj *o) { void trimStringObjectIfNeeded(robj *o) {
if (o->encoding == OBJ_ENCODING_RAW && 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 */ /* Try to encode a string object in order to save space */
robj *tryObjectEncoding(robj *o) { robj *tryObjectEncoding(robj *o) {
long value; long value;
sds s = ptrFromObj(o); sds s = szFromObj(o);
size_t len; size_t len;
/* Make sure this is a string object, the only type we encode /* Make sure this is a string object, the only type we encode
@ -469,7 +469,7 @@ robj *tryObjectEncoding(robj *o) {
incrRefCount(shared.integers[value]); incrRefCount(shared.integers[value]);
return shared.integers[value]; return shared.integers[value];
} else { } 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->encoding = OBJ_ENCODING_INT;
o->m_ptr = (void*) value; o->m_ptr = (void*) value;
return o; return o;
@ -542,14 +542,14 @@ int compareStringObjectsWithFlags(robj *a, robj *b, int flags) {
if (a == b) return 0; if (a == b) return 0;
if (sdsEncodedObject(a)) { if (sdsEncodedObject(a)) {
astr = ptrFromObj(a); astr = szFromObj(a);
alen = sdslen(astr); alen = sdslen(astr);
} else { } else {
alen = ll2string(bufa,sizeof(bufa),(long) ptrFromObj(a)); alen = ll2string(bufa,sizeof(bufa),(long) ptrFromObj(a));
astr = bufa; astr = bufa;
} }
if (sdsEncodedObject(b)) { if (sdsEncodedObject(b)) {
bstr = ptrFromObj(b); bstr = szFromObj(b);
blen = sdslen(bstr); blen = sdslen(bstr);
} else { } else {
blen = ll2string(bufb,sizeof(bufb),(long) ptrFromObj(b)); blen = ll2string(bufb,sizeof(bufb),(long) ptrFromObj(b));
@ -595,7 +595,7 @@ int equalStringObjects(robj *a, robj *b) {
size_t stringObjectLen(robj *o) { size_t stringObjectLen(robj *o) {
serverAssertWithInfo(NULL,o,o->type == OBJ_STRING); serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);
if (sdsEncodedObject(o)) { if (sdsEncodedObject(o)) {
return sdslen(ptrFromObj(o)); return sdslen(szFromObj(o));
} else { } else {
return sdigits10((long)ptrFromObj(o)); return sdigits10((long)ptrFromObj(o));
} }
@ -611,10 +611,10 @@ int getDoubleFromObject(const robj *o, double *target) {
serverAssertWithInfo(NULL,o,o->type == OBJ_STRING); serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);
if (sdsEncodedObject(o)) { if (sdsEncodedObject(o)) {
errno = 0; errno = 0;
value = strtod(ptrFromObj(o), &eptr); value = strtod(szFromObj(o), &eptr);
if (sdslen(ptrFromObj(o)) == 0 || if (sdslen(szFromObj(o)) == 0 ||
isspace(((const char*)ptrFromObj(o))[0]) || isspace(((const char*)szFromObj(o))[0]) ||
(size_t)(eptr-(char*)ptrFromObj(o)) != sdslen(ptrFromObj(o)) || (size_t)(eptr-(char*)szFromObj(o)) != sdslen(szFromObj(o)) ||
(errno == ERANGE && (errno == ERANGE &&
(value == HUGE_VAL || value == -HUGE_VAL || value == 0)) || (value == HUGE_VAL || value == -HUGE_VAL || value == 0)) ||
isnan(value)) isnan(value))
@ -653,16 +653,16 @@ int getLongDoubleFromObject(robj *o, long double *target) {
serverAssertWithInfo(NULL,o,o->type == OBJ_STRING); serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);
if (sdsEncodedObject(o)) { if (sdsEncodedObject(o)) {
errno = 0; errno = 0;
value = strtold(ptrFromObj(o), &eptr); value = strtold(szFromObj(o), &eptr);
if (sdslen(ptrFromObj(o)) == 0 || if (sdslen(szFromObj(o)) == 0 ||
isspace(((const char*)ptrFromObj(o))[0]) || isspace(((const char*)szFromObj(o))[0]) ||
(size_t)(eptr-(char*)ptrFromObj(o)) != sdslen(ptrFromObj(o)) || (size_t)(eptr-(char*)szFromObj(o)) != sdslen(szFromObj(o)) ||
(errno == ERANGE && (errno == ERANGE &&
(value == HUGE_VAL || value == -HUGE_VAL || value == 0)) || (value == HUGE_VAL || value == -HUGE_VAL || value == 0)) ||
isnan(value)) isnan(value))
return C_ERR; return C_ERR;
} else if (o->encoding == OBJ_ENCODING_INT) { } else if (o->encoding == OBJ_ENCODING_INT) {
value = (long)ptrFromObj(o); value = (long)szFromObj(o);
} else { } else {
serverPanic("Unknown string encoding"); serverPanic("Unknown string encoding");
} }
@ -693,7 +693,7 @@ int getLongLongFromObject(robj *o, long long *target) {
} else { } else {
serverAssertWithInfo(NULL,o,o->type == OBJ_STRING); serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);
if (sdsEncodedObject(o)) { 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) { } else if (o->encoding == OBJ_ENCODING_INT) {
value = (long)ptrFromObj(o); value = (long)ptrFromObj(o);
} else { } else {
@ -734,7 +734,7 @@ int getLongFromObjectOrReply(client *c, robj *o, long *target, const char *msg)
return C_OK; return C_OK;
} }
char *strEncoding(int encoding) { const char *strEncoding(int encoding) {
switch(encoding) { switch(encoding) {
case OBJ_ENCODING_RAW: return "raw"; case OBJ_ENCODING_RAW: return "raw";
case OBJ_ENCODING_INT: return "int"; 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) { if(o->encoding == OBJ_ENCODING_INT) {
asize = sizeof(*o); asize = sizeof(*o);
} else if(o->encoding == OBJ_ENCODING_RAW) { } 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) { } else if(o->encoding == OBJ_ENCODING_EMBSTR) {
asize = sdslen(ptrFromObj(o))+2+sizeof(*o); asize = sdslen(szFromObj(o))+2+sizeof(*o);
} else { } else {
serverPanic("Unknown string encoding"); serverPanic("Unknown string encoding");
} }
} else if (o->type == OBJ_LIST) { } else if (o->type == OBJ_LIST) {
if (o->encoding == OBJ_ENCODING_QUICKLIST) { if (o->encoding == OBJ_ENCODING_QUICKLIST) {
quicklist *ql = ptrFromObj(o); quicklist *ql = (quicklist*)ptrFromObj(o);
quicklistNode *node = ql->head; quicklistNode *node = ql->head;
asize = sizeof(*o)+sizeof(quicklist); asize = sizeof(*o)+sizeof(quicklist);
do { do {
@ -807,41 +807,41 @@ size_t objectComputeSize(robj *o, size_t sample_size) {
} while ((node = node->next) && samples < sample_size); } while ((node = node->next) && samples < sample_size);
asize += (double)elesize/samples*ql->len; asize += (double)elesize/samples*ql->len;
} else if (o->encoding == OBJ_ENCODING_ZIPLIST) { } else if (o->encoding == OBJ_ENCODING_ZIPLIST) {
asize = sizeof(*o)+ziplistBlobLen(ptrFromObj(o)); asize = sizeof(*o)+ziplistBlobLen((unsigned char*)ptrFromObj(o));
} else { } else {
serverPanic("Unknown list encoding"); serverPanic("Unknown list encoding");
} }
} else if (o->type == OBJ_SET) { } else if (o->type == OBJ_SET) {
if (o->encoding == OBJ_ENCODING_HT) { if (o->encoding == OBJ_ENCODING_HT) {
d = ptrFromObj(o); d = (dict*)ptrFromObj(o);
di = dictGetIterator(d); di = dictGetIterator(d);
asize = sizeof(*o)+sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d)); asize = sizeof(*o)+sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d));
while((de = dictNext(di)) != NULL && samples < sample_size) { while((de = dictNext(di)) != NULL && samples < sample_size) {
ele = dictGetKey(de); ele = (sds)dictGetKey(de);
elesize += sizeof(struct dictEntry) + sdsAllocSize(ele); elesize += sizeof(struct dictEntry) + sdsAllocSize(ele);
samples++; samples++;
} }
dictReleaseIterator(di); dictReleaseIterator(di);
if (samples) asize += (double)elesize/samples*dictSize(d); if (samples) asize += (double)elesize/samples*dictSize(d);
} else if (o->encoding == OBJ_ENCODING_INTSET) { } 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; asize = sizeof(*o)+sizeof(*is)+is->encoding*is->length;
} else { } else {
serverPanic("Unknown set encoding"); serverPanic("Unknown set encoding");
} }
} else if (o->type == OBJ_ZSET) { } else if (o->type == OBJ_ZSET) {
if (o->encoding == OBJ_ENCODING_ZIPLIST) { 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) { } else if (o->encoding == OBJ_ENCODING_SKIPLIST) {
d = ((zset*)ptrFromObj(o))->pdict; d = ((zset*)ptrFromObj(o))->pdict;
zskiplist *zsl = ((zset*)ptrFromObj(o))->zsl; 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)); asize = sizeof(*o)+sizeof(zset)+(sizeof(struct dictEntry*)*dictSlots(d));
while(znode != NULL && samples < sample_size) { while(znode != NULL && samples < sample_size) {
elesize += sdsAllocSize(znode->ele); elesize += sdsAllocSize(znode->ele);
elesize += sizeof(struct dictEntry) + zmalloc_size(znode); elesize += sizeof(struct dictEntry) + zmalloc_size(znode);
samples++; samples++;
znode = znode->level[0].forward; znode = znode->level(0)->forward;
} }
if (samples) asize += (double)elesize/samples*dictSize(d); if (samples) asize += (double)elesize/samples*dictSize(d);
} else { } else {
@ -849,14 +849,14 @@ size_t objectComputeSize(robj *o, size_t sample_size) {
} }
} else if (o->type == OBJ_HASH) { } else if (o->type == OBJ_HASH) {
if (o->encoding == OBJ_ENCODING_ZIPLIST) { 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) { } else if (o->encoding == OBJ_ENCODING_HT) {
d = ptrFromObj(o); d = (dict*)ptrFromObj(o);
di = dictGetIterator(d); di = dictGetIterator(d);
asize = sizeof(*o)+sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d)); asize = sizeof(*o)+sizeof(dict)+(sizeof(struct dictEntry*)*dictSlots(d));
while((de = dictNext(di)) != NULL && samples < sample_size) { while((de = dictNext(di)) != NULL && samples < sample_size) {
ele = dictGetKey(de); ele = (sds)dictGetKey(de);
ele2 = dictGetVal(de); ele2 = (sds)dictGetVal(de);
elesize += sdsAllocSize(ele) + sdsAllocSize(ele2); elesize += sdsAllocSize(ele) + sdsAllocSize(ele2);
elesize += sizeof(struct dictEntry); elesize += sizeof(struct dictEntry);
samples++; samples++;
@ -867,7 +867,7 @@ size_t objectComputeSize(robj *o, size_t sample_size) {
serverPanic("Unknown hash encoding"); serverPanic("Unknown hash encoding");
} }
} else if (o->type == OBJ_STREAM) { } else if (o->type == OBJ_STREAM) {
stream *s = ptrFromObj(o); stream *s = (stream*)ptrFromObj(o);
asize = sizeof(*o); asize = sizeof(*o);
asize += streamRadixTreeMemoryUsage(s->prax); asize += streamRadixTreeMemoryUsage(s->prax);
@ -880,7 +880,7 @@ size_t objectComputeSize(robj *o, size_t sample_size) {
raxSeek(&ri,"^",NULL,0); raxSeek(&ri,"^",NULL,0);
size_t lpsize = 0, samples = 0; size_t lpsize = 0, samples = 0;
while(samples < sample_size && raxNext(&ri)) { while(samples < sample_size && raxNext(&ri)) {
unsigned char *lp = ri.data; unsigned char *lp = (unsigned char*)ri.data;
lpsize += lpBytes(lp); lpsize += lpBytes(lp);
samples++; samples++;
} }
@ -893,7 +893,7 @@ size_t objectComputeSize(robj *o, size_t sample_size) {
* if there are a few elements in the radix tree. */ * if there are a few elements in the radix tree. */
raxSeek(&ri,"$",NULL,0); raxSeek(&ri,"$",NULL,0);
raxNext(&ri); raxNext(&ri);
asize += lpBytes(ri.data); asize += lpBytes((unsigned char*)ri.data);
} }
raxStop(&ri); raxStop(&ri);
@ -905,7 +905,7 @@ size_t objectComputeSize(robj *o, size_t sample_size) {
raxStart(&ri,s->cgroups); raxStart(&ri,s->cgroups);
raxSeek(&ri,"^",NULL,0); raxSeek(&ri,"^",NULL,0);
while(raxNext(&ri)) { while(raxNext(&ri)) {
streamCG *cg = ri.data; streamCG *cg = (streamCG*)ri.data;
asize += sizeof(*cg); asize += sizeof(*cg);
asize += streamRadixTreeMemoryUsage(cg->pel); asize += streamRadixTreeMemoryUsage(cg->pel);
asize += sizeof(streamNACK)*raxSize(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); raxStart(&cri,cg->consumers);
raxSeek(&cri,"^",NULL,0); raxSeek(&cri,"^",NULL,0);
while(raxNext(&cri)) { while(raxNext(&cri)) {
streamConsumer *consumer = cri.data; streamConsumer *consumer = (streamConsumer*)cri.data;
asize += sizeof(*consumer); asize += sizeof(*consumer);
asize += sdslen(consumer->name); asize += sdslen(consumer->name);
asize += streamRadixTreeMemoryUsage(consumer->pel); asize += streamRadixTreeMemoryUsage(consumer->pel);
@ -928,7 +928,7 @@ size_t objectComputeSize(robj *o, size_t sample_size) {
raxStop(&ri); raxStop(&ri);
} }
} else if (o->type == OBJ_MODULE) { } else if (o->type == OBJ_MODULE) {
moduleValue *mv = ptrFromObj(o); moduleValue *mv = (moduleValue*)ptrFromObj(o);
moduleType *mt = mv->type; moduleType *mt = mv->type;
if (mt->mem_usage != NULL) { if (mt->mem_usage != NULL) {
asize = mt->mem_usage(mv->value); asize = mt->mem_usage(mv->value);
@ -956,7 +956,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) {
size_t mem_total = 0; size_t mem_total = 0;
size_t mem = 0; size_t mem = 0;
size_t zmalloc_used = zmalloc_used_memory(); 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->total_allocated = zmalloc_used;
mh->startup_allocated = server.initial_memory_usage; mh->startup_allocated = server.initial_memory_usage;
@ -993,7 +993,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) {
listRewind(server.slaves,&li); listRewind(server.slaves,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
client *c = listNodeValue(ln); client *c = (client*)listNodeValue(ln);
if (c->flags & CLIENT_CLOSE_ASAP) if (c->flags & CLIENT_CLOSE_ASAP)
continue; continue;
mem += getClientOutputBufferMemoryUsage(c); mem += getClientOutputBufferMemoryUsage(c);
@ -1011,7 +1011,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) {
listRewind(server.clients,&li); listRewind(server.clients,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
client *c = listNodeValue(ln); client *c = (client*)listNodeValue(ln);
if (c->flags & CLIENT_SLAVE && !(c->flags & CLIENT_MONITOR)) if (c->flags & CLIENT_SLAVE && !(c->flags & CLIENT_MONITOR))
continue; continue;
mem += getClientOutputBufferMemoryUsage(c); mem += getClientOutputBufferMemoryUsage(c);
@ -1037,7 +1037,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) {
dictSlots(server.repl_scriptcache_dict) * sizeof(dictEntry*); dictSlots(server.repl_scriptcache_dict) * sizeof(dictEntry*);
if (listLength(server.repl_scriptcache_fifo) > 0) { if (listLength(server.repl_scriptcache_fifo) > 0) {
mem += listLength(server.repl_scriptcache_fifo) * (sizeof(listNode) + 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; mh->lua_caches = mem;
mem_total+=mem; mem_total+=mem;
@ -1048,7 +1048,7 @@ struct redisMemOverhead *getMemoryOverheadData(void) {
if (keyscount==0) continue; if (keyscount==0) continue;
mh->total_keys += keyscount; 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; mh->db[mh->num_dbs].dbid = j;
mem = dictSize(db->pdict) * sizeof(dictEntry) + mem = dictSize(db->pdict) * sizeof(dictEntry) +
@ -1256,7 +1256,7 @@ robj *objectCommandLookupOrReply(client *c, robj *key, robj *reply) {
void objectCommand(client *c) { void objectCommand(client *c) {
robj *o; 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[] = { const char *help[] = {
"ENCODING <key> -- Return the kind of internal representation used in order to store the value associated with a key.", "ENCODING <key> -- Return the kind of internal representation used in order to store the value associated with a key.",
"FREQ <key> -- Return the access frequency index of the key. The returned integer is proportional to the logarithm of the recent access frequency of the key.", "FREQ <key> -- 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 NULL
}; };
addReplyHelp(c, help); 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])) if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.null[c->resp]))
== NULL) return; == NULL) return;
addReplyLongLong(c,o->refcount); 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])) if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.null[c->resp]))
== NULL) return; == NULL) return;
addReplyBulkCString(c,strEncoding(o->encoding)); 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])) if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.null[c->resp]))
== NULL) return; == NULL) return;
if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) { if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {
@ -1281,7 +1281,7 @@ NULL
return; return;
} }
addReplyLongLong(c,estimateObjectIdleTime(o)/1000); 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])) if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.null[c->resp]))
== NULL) return; == NULL) return;
if (!(server.maxmemory_policy & MAXMEMORY_FLAG_LFU)) { if (!(server.maxmemory_policy & MAXMEMORY_FLAG_LFU)) {
@ -1303,7 +1303,7 @@ NULL
* *
* Usage: MEMORY usage <key> */ * Usage: MEMORY usage <key> */
void memoryCommand(client *c) { 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[] = { const char *help[] = {
"DOCTOR - Return memory problems reports.", "DOCTOR - Return memory problems reports.",
"MALLOC-STATS -- Return internal statistics report from the memory allocator.", "MALLOC-STATS -- Return internal statistics report from the memory allocator.",
@ -1313,11 +1313,11 @@ void memoryCommand(client *c) {
NULL NULL
}; };
addReplyHelp(c, help); 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; dictEntry *de;
long long samples = OBJ_COMPUTE_SIZE_DEF_SAMPLES; long long samples = OBJ_COMPUTE_SIZE_DEF_SAMPLES;
for (int j = 3; j < c->argc; j++) { 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) j+1 < c->argc)
{ {
if (getLongLongFromObjectOrReply(c,c->argv[j+1],&samples,NULL) if (getLongLongFromObjectOrReply(c,c->argv[j+1],&samples,NULL)
@ -1337,11 +1337,11 @@ NULL
addReplyNull(c); addReplyNull(c);
return; return;
} }
size_t usage = objectComputeSize(dictGetVal(de),samples); size_t usage = objectComputeSize((robj*)dictGetVal(de),samples);
usage += sdsAllocSize(dictGetKey(de)); usage += sdsAllocSize((sds)dictGetKey(de));
usage += sizeof(dictEntry); usage += sizeof(dictEntry);
addReplyLongLong(c,usage); 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(); struct redisMemOverhead *mh = getMemoryOverheadData();
addReplyMapLen(c,25+mh->num_dbs); addReplyMapLen(c,25+mh->num_dbs);
@ -1435,7 +1435,7 @@ NULL
addReplyLongLong(c,mh->total_frag_bytes); addReplyLongLong(c,mh->total_frag_bytes);
freeMemoryOverheadData(mh); 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) #if defined(USE_JEMALLOC)
sds info = sdsempty(); sds info = sdsempty();
je_malloc_stats_print(inputCatSds, &info, NULL); je_malloc_stats_print(inputCatSds, &info, NULL);
@ -1443,10 +1443,10 @@ NULL
#else #else
addReplyBulkCString(c,"Stats not supported for the current allocator"); addReplyBulkCString(c,"Stats not supported for the current allocator");
#endif #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(); sds report = getMemoryDoctorReport();
addReplyBulkSds(c,report); 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) #if defined(USE_JEMALLOC)
char tmp[32]; char tmp[32];
unsigned narenas = 0; unsigned narenas = 0;

View File

@ -121,14 +121,14 @@ void addReplyPubsubPatUnsubscribed(client *c, robj *pattern) {
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
void freePubsubPattern(void *p) { void freePubsubPattern(void *p) {
pubsubPattern *pat = p; pubsubPattern *pat = (pubsubPattern *)p;
decrRefCount(pat->pattern); decrRefCount(pat->pattern);
zfree(pat); zfree(pat);
} }
int listMatchPubsubPattern(void *a, void *b) { int listMatchPubsubPattern(void *a, void *b) {
pubsubPattern *pa = a, *pb = b; pubsubPattern *pa = (pubsubPattern*)a, *pb = (pubsubPattern*)b;
return (pa->pclient == pb->pclient) && return (pa->pclient == pb->pclient) &&
(equalStringObjects(pa->pattern,pb->pattern)); (equalStringObjects(pa->pattern,pb->pattern));
@ -158,7 +158,7 @@ int pubsubSubscribeChannel(client *c, robj *channel) {
dictAdd(server.pubsub_channels,channel,clients); dictAdd(server.pubsub_channels,channel,clients);
incrRefCount(channel); incrRefCount(channel);
} else { } else {
clients = dictGetVal(de); clients = (list*)dictGetVal(de);
} }
listAddNodeTail(clients,c); 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 */ /* Remove the client from the channel -> clients list hash table */
de = dictFind(server.pubsub_channels,channel); de = dictFind(server.pubsub_channels,channel);
serverAssertWithInfo(c,NULL,de != NULL); serverAssertWithInfo(c,NULL,de != NULL);
clients = dictGetVal(de); clients = (list*)dictGetVal(de);
ln = listSearchKey(clients,c); ln = listSearchKey(clients,c);
serverAssertWithInfo(c,NULL,ln != NULL); serverAssertWithInfo(c,NULL,ln != NULL);
listDelNode(clients,ln); listDelNode(clients,ln);
@ -209,7 +209,7 @@ int pubsubSubscribePattern(client *c, robj *pattern) {
pubsubPattern *pat; pubsubPattern *pat;
listAddNodeTail(c->pubsub_patterns,pattern); listAddNodeTail(c->pubsub_patterns,pattern);
incrRefCount(pattern); incrRefCount(pattern);
pat = zmalloc(sizeof(*pat), MALLOC_LOCAL); pat = (pubsubPattern*)zmalloc(sizeof(*pat), MALLOC_LOCAL);
pat->pattern = getDecodedObject(pattern); pat->pattern = getDecodedObject(pattern);
pat->pclient = c; pat->pclient = c;
listAddNodeTail(server.pubsub_patterns,pat); listAddNodeTail(server.pubsub_patterns,pat);
@ -249,7 +249,7 @@ int pubsubUnsubscribeAllChannels(client *c, int notify) {
int count = 0; int count = 0;
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
robj *channel = dictGetKey(de); robj *channel = (robj*)dictGetKey(de);
count += pubsubUnsubscribeChannel(c,channel,notify); count += pubsubUnsubscribeChannel(c,channel,notify);
} }
@ -268,7 +268,7 @@ int pubsubUnsubscribeAllPatterns(client *c, int notify) {
listRewind(c->pubsub_patterns,&li); listRewind(c->pubsub_patterns,&li);
while ((ln = listNext(&li)) != NULL) { while ((ln = listNext(&li)) != NULL) {
robj *pattern = ln->value; robj *pattern = (robj*)ln->value;
count += pubsubUnsubscribePattern(c,pattern,notify); count += pubsubUnsubscribePattern(c,pattern,notify);
} }
@ -286,13 +286,13 @@ int pubsubPublishMessage(robj *channel, robj *message) {
/* Send to clients listening for that channel */ /* Send to clients listening for that channel */
de = dictFind(server.pubsub_channels,channel); de = dictFind(server.pubsub_channels,channel);
if (de) { if (de) {
list *list = dictGetVal(de); list *list = reinterpret_cast<::list*>(dictGetVal(de));
listNode *ln; listNode *ln;
listIter li; listIter li;
listRewind(list,&li); listRewind(list,&li);
while ((ln = listNext(&li)) != NULL) { while ((ln = listNext(&li)) != NULL) {
client *c = ln->value; client *c = reinterpret_cast<client*>(ln->value);
fastlock_lock(&c->lock); fastlock_lock(&c->lock);
addReplyPubsubMessage(c,channel,message); addReplyPubsubMessage(c,channel,message);
fastlock_unlock(&c->lock); fastlock_unlock(&c->lock);
@ -304,12 +304,12 @@ int pubsubPublishMessage(robj *channel, robj *message) {
listRewind(server.pubsub_patterns,&li); listRewind(server.pubsub_patterns,&li);
channel = getDecodedObject(channel); channel = getDecodedObject(channel);
while ((ln = listNext(&li)) != NULL) { while ((ln = listNext(&li)) != NULL) {
pubsubPattern *pat = ln->value; pubsubPattern *pat = (pubsubPattern*)ln->value;
if (stringmatchlen((char*)ptrFromObj(pat->pattern), if (stringmatchlen((char*)ptrFromObj(pat->pattern),
sdslen(ptrFromObj(pat->pattern)), sdslen(szFromObj(pat->pattern)),
(char*)ptrFromObj(channel), (char*)ptrFromObj(channel),
sdslen(ptrFromObj(channel)),0)) sdslen(szFromObj(channel)),0))
{ {
fastlock_lock(&pat->pclient->lock); fastlock_lock(&pat->pclient->lock);
addReplyPubsubPatMessage(pat->pclient, addReplyPubsubPatMessage(pat->pclient,
@ -380,7 +380,7 @@ void publishCommand(client *c) {
/* PUBSUB command for Pub/Sub introspection. */ /* PUBSUB command for Pub/Sub introspection. */
void pubsubCommand(client *c) { 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[] = { const char *help[] = {
"CHANNELS [<pattern>] -- Return the currently active channels matching a pattern (default: all).", "CHANNELS [<pattern>] -- Return the currently active channels matching a pattern (default: all).",
"NUMPAT -- Return number of subscriptions to patterns.", "NUMPAT -- Return number of subscriptions to patterns.",
@ -388,11 +388,11 @@ void pubsubCommand(client *c) {
NULL NULL
}; };
addReplyHelp(c, help); 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)) (c->argc == 2 || c->argc == 3))
{ {
/* PUBSUB CHANNELS [<pattern>] */ /* PUBSUB CHANNELS [<pattern>] */
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); dictIterator *di = dictGetIterator(server.pubsub_channels);
dictEntry *de; dictEntry *de;
long mblen = 0; long mblen = 0;
@ -400,8 +400,8 @@ NULL
replylen = addReplyDeferredLen(c); replylen = addReplyDeferredLen(c);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
robj *cobj = dictGetKey(de); robj *cobj = (robj*)dictGetKey(de);
sds channel = ptrFromObj(cobj); sds channel = szFromObj(cobj);
if (!pat || stringmatchlen(pat, sdslen(pat), if (!pat || stringmatchlen(pat, sdslen(pat),
channel, sdslen(channel),0)) channel, sdslen(channel),0))
@ -412,18 +412,18 @@ NULL
} }
dictReleaseIterator(di); dictReleaseIterator(di);
setDeferredArrayLen(c,replylen,mblen); 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] */ /* PUBSUB NUMSUB [Channel_1 ... Channel_N] */
int j; int j;
addReplyArrayLen(c,(c->argc-2)*2); addReplyArrayLen(c,(c->argc-2)*2);
for (j = 2; j < c->argc; j++) { 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]); addReplyBulk(c,c->argv[j]);
addReplyLongLong(c,l ? listLength(l) : 0); 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 */ /* PUBSUB NUMPAT */
addReplyLongLong(c,listLength(server.pubsub_patterns)); addReplyLongLong(c,listLength(server.pubsub_patterns));
} else { } else {

View File

@ -49,7 +49,7 @@ extern int rdbCheckMode;
void rdbCheckError(const char *fmt, ...); void rdbCheckError(const char *fmt, ...);
void rdbCheckSetError(const char *fmt, ...); void rdbCheckSetError(const char *fmt, ...);
void rdbCheckThenExit(int linenum, char *reason, ...) { void rdbCheckThenExit(int linenum, const char *reason, ...) {
va_list ap; va_list ap;
char msg[1024]; char msg[1024];
int len; int len;
@ -62,7 +62,7 @@ void rdbCheckThenExit(int linenum, char *reason, ...) {
if (!rdbCheckMode) { if (!rdbCheckMode) {
serverLog(LL_WARNING, "%s", msg); 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); redis_check_rdb_main(2,argv,NULL);
} else { } else {
rdbCheckError("%s",msg); rdbCheckError("%s",msg);
@ -285,7 +285,7 @@ void *rdbLoadIntegerObject(rio *rdb, int enctype, int flags, size_t *lenptr) {
char buf[LONG_STR_SIZE], *p; char buf[LONG_STR_SIZE], *p;
int len = ll2string(buf,sizeof(buf),val); int len = ll2string(buf,sizeof(buf),val);
if (lenptr) *lenptr = len; 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); memcpy(p,buf,len);
return p; return p;
} else if (encode) { } else if (encode) {
@ -339,7 +339,7 @@ writeerr:
return -1; 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; size_t comprlen, outlen;
void *out; 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 ((clen = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
if ((len = 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. */ /* Allocate our target according to the uncompressed size. */
if (plain) { if (plain) {
val = zmalloc(len, MALLOC_SHARED); val = (char*)zmalloc(len, MALLOC_SHARED);
} else { } else {
val = sdsnewlen(SDS_NOINIT,len); 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 /* 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 */ * 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; int enclen;
ssize_t n, nwritten = 0; 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 /* Try LZF compression - under 20 bytes it's unable to compress even
* aaaaaaaaaaaaaaaaaa so skip it */ * aaaaaaaaaaaaaaaaaa so skip it */
if (server.rdb_compression && len > 20) { 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 == -1) return -1;
if (n > 0) return n; if (n > 0) return n;
/* Return value of 0 means data can't be compressed, save the old way */ /* 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; if ((n = rdbSaveLen(rdb,len)) == -1) return -1;
nwritten += n; nwritten += n;
if (len > 0) { if (len > 0) {
if (rdbWriteRaw(rdb,s,len) == -1) return -1; if (rdbWriteRaw(rdb,(unsigned char*)s,len) == -1) return -1;
nwritten += len; nwritten += len;
} }
return nwritten; return nwritten;
@ -462,7 +462,7 @@ ssize_t rdbSaveStringObject(rio *rdb, robj *obj) {
return rdbSaveLongLongAsStringObject(rdb,(long)ptrFromObj(obj)); return rdbSaveLongLongAsStringObject(rdb,(long)ptrFromObj(obj));
} else { } else {
serverAssertWithInfo(NULL,obj,sdsEncodedObject(obj)); 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) if (plain)
zfree(buf); zfree(buf);
else else
sdsfree(buf); sdsfree((char*)buf);
return NULL; return NULL;
} }
return buf; return buf;
@ -524,11 +524,11 @@ void *rdbGenericLoadStringObject(rio *rdb, int flags, size_t *lenptr) {
} }
robj *rdbLoadStringObject(rio *rdb) { robj *rdbLoadStringObject(rio *rdb) {
return rdbGenericLoadStringObject(rdb,RDB_LOAD_NONE,NULL); return (robj*)rdbGenericLoadStringObject(rdb,RDB_LOAD_NONE,NULL);
} }
robj *rdbLoadEncodedStringObject(rio *rdb) { 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 /* 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; nwritten += n;
if (nacks) { if (nacks) {
streamNACK *nack = ri.data; streamNACK *nack = (streamNACK*)ri.data;
if ((n = rdbSaveMillisecondTime(rdb,nack->delivery_time)) == -1) if ((n = rdbSaveMillisecondTime(rdb,nack->delivery_time)) == -1)
return -1; return -1;
nwritten += n; nwritten += n;
@ -727,7 +727,7 @@ size_t rdbSaveStreamConsumers(rio *rdb, streamCG *cg) {
raxStart(&ri,cg->consumers); raxStart(&ri,cg->consumers);
raxSeek(&ri,"^",NULL,0); raxSeek(&ri,"^",NULL,0);
while(raxNext(&ri)) { while(raxNext(&ri)) {
streamConsumer *consumer = ri.data; streamConsumer *consumer = (streamConsumer*)ri.data;
/* Consumer name. */ /* Consumer name. */
if ((n = rdbSaveRawString(rdb,ri.key,ri.key_len)) == -1) return -1; 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) { } else if (o->type == OBJ_LIST) {
/* Save a list value */ /* Save a list value */
if (o->encoding == OBJ_ENCODING_QUICKLIST) { if (o->encoding == OBJ_ENCODING_QUICKLIST) {
quicklist *ql = ptrFromObj(o); quicklist *ql = (quicklist*)ptrFromObj(o);
quicklistNode *node = ql->head; quicklistNode *node = ql->head;
if ((n = rdbSaveLen(rdb,ql->len)) == -1) return -1; 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) { } else if (o->type == OBJ_SET) {
/* Save a set value */ /* Save a set value */
if (o->encoding == OBJ_ENCODING_HT) { if (o->encoding == OBJ_ENCODING_HT) {
dict *set = ptrFromObj(o); dict *set = (dict*)ptrFromObj(o);
dictIterator *di = dictGetIterator(set); dictIterator *di = dictGetIterator(set);
dictEntry *de; dictEntry *de;
@ -797,7 +797,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) {
nwritten += n; nwritten += n;
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sds ele = dictGetKey(de); sds ele = (sds)dictGetKey(de);
if ((n = rdbSaveRawString(rdb,(unsigned char*)ele,sdslen(ele))) if ((n = rdbSaveRawString(rdb,(unsigned char*)ele,sdslen(ele)))
== -1) == -1)
{ {
@ -810,7 +810,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) {
} else if (o->encoding == OBJ_ENCODING_INTSET) { } else if (o->encoding == OBJ_ENCODING_INTSET) {
size_t l = intsetBlobLen((intset*)ptrFromObj(o)); 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; nwritten += n;
} else { } else {
serverPanic("Unknown set encoding"); serverPanic("Unknown set encoding");
@ -820,10 +820,10 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) {
if (o->encoding == OBJ_ENCODING_ZIPLIST) { if (o->encoding == OBJ_ENCODING_ZIPLIST) {
size_t l = ziplistBlobLen((unsigned char*)ptrFromObj(o)); 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; nwritten += n;
} else if (o->encoding == OBJ_ENCODING_SKIPLIST) { } else if (o->encoding == OBJ_ENCODING_SKIPLIST) {
zset *zs = ptrFromObj(o); zset *zs = (zset*)ptrFromObj(o);
zskiplist *zsl = zs->zsl; zskiplist *zsl = zs->zsl;
if ((n = rdbSaveLen(rdb,zsl->length)) == -1) return -1; 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) { if (o->encoding == OBJ_ENCODING_ZIPLIST) {
size_t l = ziplistBlobLen((unsigned char*)ptrFromObj(o)); 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; nwritten += n;
} else if (o->encoding == OBJ_ENCODING_HT) { } else if (o->encoding == OBJ_ENCODING_HT) {
dictIterator *di = dictGetIterator(ptrFromObj(o)); dictIterator *di = dictGetIterator((dict*)ptrFromObj(o));
dictEntry *de; dictEntry *de;
if ((n = rdbSaveLen(rdb,dictSize((dict*)ptrFromObj(o)))) == -1) { if ((n = rdbSaveLen(rdb,dictSize((dict*)ptrFromObj(o)))) == -1) {
@ -870,8 +870,8 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) {
nwritten += n; nwritten += n;
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sds field = dictGetKey(de); sds field = (sds)dictGetKey(de);
sds value = dictGetVal(de); sds value = (sds)dictGetVal(de);
if ((n = rdbSaveRawString(rdb,(unsigned char*)field, if ((n = rdbSaveRawString(rdb,(unsigned char*)field,
sdslen(field))) == -1) sdslen(field))) == -1)
@ -894,7 +894,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) {
} }
} else if (o->type == OBJ_STREAM) { } else if (o->type == OBJ_STREAM) {
/* Store how many listpacks we have inside the radix tree. */ /* Store how many listpacks we have inside the radix tree. */
stream *s = ptrFromObj(o); stream *s = (stream*)ptrFromObj(o);
rax *rax = s->prax; rax *rax = s->prax;
if ((n = rdbSaveLen(rdb,raxSize(rax))) == -1) return -1; if ((n = rdbSaveLen(rdb,raxSize(rax))) == -1) return -1;
nwritten += n; nwritten += n;
@ -906,7 +906,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) {
raxStart(&ri,rax); raxStart(&ri,rax);
raxSeek(&ri,"^",NULL,0); raxSeek(&ri,"^",NULL,0);
while (raxNext(&ri)) { while (raxNext(&ri)) {
unsigned char *lp = ri.data; unsigned char *lp = (unsigned char*)ri.data;
size_t lp_bytes = lpBytes(lp); size_t lp_bytes = lpBytes(lp);
if ((n = rdbSaveRawString(rdb,ri.key,ri.key_len)) == -1) return -1; if ((n = rdbSaveRawString(rdb,ri.key,ri.key_len)) == -1) return -1;
nwritten += n; nwritten += n;
@ -939,7 +939,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key) {
raxStart(&ri,s->cgroups); raxStart(&ri,s->cgroups);
raxSeek(&ri,"^",NULL,0); raxSeek(&ri,"^",NULL,0);
while(raxNext(&ri)) { while(raxNext(&ri)) {
streamCG *cg = ri.data; streamCG *cg = (streamCG*)ri.data;
/* Save the group name. */ /* Save the group name. */
if ((n = rdbSaveRawString(rdb,ri.key,ri.key_len)) == -1) 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) { } else if (o->type == OBJ_MODULE) {
/* Save a module-specific value. */ /* Save a module-specific value. */
RedisModuleIO io; RedisModuleIO io;
moduleValue *mv = ptrFromObj(o); moduleValue *mv = (moduleValue*)ptrFromObj(o);
moduleType *mt = mv->type; moduleType *mt = mv->type;
moduleInitIOContext(io,mt,rdb,key); moduleInitIOContext(io,mt,rdb,key);
@ -1044,25 +1044,25 @@ int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, long long expiretime) {
} }
/* Save an AUX field. */ /* 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; ssize_t ret, len = 0;
if ((ret = rdbSaveType(rdb,RDB_OPCODE_AUX)) == -1) return -1; if ((ret = rdbSaveType(rdb,RDB_OPCODE_AUX)) == -1) return -1;
len += ret; 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; 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; len += ret;
return len; return len;
} }
/* Wrapper for rdbSaveAuxField() used when key/val length can be obtained /* Wrapper for rdbSaveAuxField() used when key/val length can be obtained
* with strlen(). */ * 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)); return rdbSaveAuxField(rdb,key,strlen(key),val,strlen(val));
} }
/* Wrapper for strlen(key) + integer type (up to long long range). */ /* 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]; char buf[LONG_STR_SIZE];
int vlen = ll2string(buf,sizeof(buf),val); int vlen = ll2string(buf,sizeof(buf),val);
return rdbSaveAuxField(rdb,key,strlen(key),buf,vlen); 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 */ /* Iterate this DB writing every entry */
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sds keystr = dictGetKey(de); sds keystr = (sds)dictGetKey(de);
robj key, *o = dictGetVal(de); robj key, *o = (robj*)dictGetVal(de);
long long expire; long long expire;
initStaticStringObject(key,keystr); initStaticStringObject(key,keystr);
@ -1166,8 +1166,8 @@ int rdbSaveRio(rio *rdb, int *error, int flags, rdbSaveInfo *rsi) {
if (rsi && dictSize(server.lua_scripts)) { if (rsi && dictSize(server.lua_scripts)) {
di = dictGetIterator(server.lua_scripts); di = dictGetIterator(server.lua_scripts);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
robj *body = dictGetVal(de); robj *body = (robj*)dictGetVal(de);
if (rdbSaveAuxField(rdb,"lua",3,ptrFromObj(body),sdslen(ptrFromObj(body))) == -1) if (rdbSaveAuxField(rdb,"lua",3,szFromObj(body),sdslen(szFromObj(body))) == -1)
goto werr; goto werr;
} }
dictReleaseIterator(di); dictReleaseIterator(di);
@ -1376,7 +1376,7 @@ robj *rdbLoadCheckModuleValue(rio *rdb, char *modulename) {
"Error reading integer from module %s value", modulename); "Error reading integer from module %s value", modulename);
} }
} else if (opcode == RDB_MODULE_OPCODE_STRING) { } 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) { if (o == NULL) {
rdbExitReportCorruptRDB( rdbExitReportCorruptRDB(
"Error reading string from module %s value", modulename); "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; if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
o = createQuicklistObject(); o = createQuicklistObject();
quicklistSetOptions(ptrFromObj(o), server.list_max_ziplist_size, quicklistSetOptions((quicklist*)ptrFromObj(o), server.list_max_ziplist_size,
server.list_compress_depth); server.list_compress_depth);
/* Load every single element of the list */ /* Load every single element of the list */
while(len--) { while(len--) {
if ((ele = rdbLoadEncodedStringObject(rdb)) == NULL) return NULL; if ((ele = rdbLoadEncodedStringObject(rdb)) == NULL) return NULL;
dec = getDecodedObject(ele); dec = getDecodedObject(ele);
size_t len = sdslen(ptrFromObj(dec)); size_t len = sdslen(szFromObj(dec));
quicklistPushTail(ptrFromObj(o), ptrFromObj(dec), len); quicklistPushTail((quicklist*)ptrFromObj(o), ptrFromObj(dec), len);
decrRefCount(dec); decrRefCount(dec);
decrRefCount(ele); 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 /* It's faster to expand the dict to the right size asap in order
* to avoid rehashing */ * to avoid rehashing */
if (len > DICT_HT_INITIAL_SIZE) if (len > DICT_HT_INITIAL_SIZE)
dictExpand(ptrFromObj(o),len); dictExpand((dict*)ptrFromObj(o),len);
} else { } else {
o = createIntsetObject(); o = createIntsetObject();
} }
@ -1447,16 +1447,16 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) {
long long llval; long long llval;
sds sdsele; sds sdsele;
if ((sdsele = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) if ((sdsele = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL))
== NULL) return NULL; == NULL) return NULL;
if (o->encoding == OBJ_ENCODING_INTSET) { if (o->encoding == OBJ_ENCODING_INTSET) {
/* Fetch integer value from element. */ /* Fetch integer value from element. */
if (isSdsRepresentableAsLongLong(sdsele,&llval) == C_OK) { if (isSdsRepresentableAsLongLong(sdsele,&llval) == C_OK) {
o->m_ptr = intsetAdd(ptrFromObj(o),llval,NULL); o->m_ptr = intsetAdd((intset*)ptrFromObj(o),llval,NULL);
} else { } else {
setTypeConvert(o,OBJ_ENCODING_HT); 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; if ((zsetlen = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
o = createZsetObject(); o = createZsetObject();
zs = ptrFromObj(o); zs = (zset*)ptrFromObj(o);
if (zsetlen > DICT_HT_INITIAL_SIZE) if (zsetlen > DICT_HT_INITIAL_SIZE)
dictExpand(zs->pdict,zsetlen); dictExpand(zs->pdict,zsetlen);
@ -1487,7 +1487,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) {
double score; double score;
zskiplistNode *znode; zskiplistNode *znode;
if ((sdsele = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) if ((sdsele = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL))
== NULL) return NULL; == NULL) return NULL;
if (rdbtype == RDB_TYPE_ZSET_2) { 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) { while (o->encoding == OBJ_ENCODING_ZIPLIST && len > 0) {
len--; len--;
/* Load raw strings */ /* Load raw strings */
if ((field = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) if ((field = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL))
== NULL) return NULL; == NULL) return NULL;
if ((value = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) if ((value = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL))
== NULL) return NULL; == NULL) return NULL;
/* Add pair to ziplist */ /* 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); 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); sdslen(value), ZIPLIST_TAIL);
/* Convert to hash table if size threshold is exceeded */ /* 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) 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 */ /* Load remaining fields and values into the hash table */
while (o->encoding == OBJ_ENCODING_HT && len > 0) { while (o->encoding == OBJ_ENCODING_HT && len > 0) {
len--; len--;
/* Load encoded strings */ /* Load encoded strings */
if ((field = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) if ((field = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL))
== NULL) return NULL; == NULL) return NULL;
if ((value = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL)) if ((value = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL))
== NULL) return NULL; == NULL) return NULL;
/* Add pair to hash table */ /* Add pair to hash table */
@ -1573,14 +1573,14 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) {
} else if (rdbtype == RDB_TYPE_LIST_QUICKLIST) { } else if (rdbtype == RDB_TYPE_LIST_QUICKLIST) {
if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL; if ((len = rdbLoadLen(rdb,NULL)) == RDB_LENERR) return NULL;
o = createQuicklistObject(); o = createQuicklistObject();
quicklistSetOptions(ptrFromObj(o), server.list_max_ziplist_size, quicklistSetOptions((quicklist*)ptrFromObj(o), server.list_max_ziplist_size,
server.list_compress_depth); server.list_compress_depth);
while (len--) { while (len--) {
unsigned char *zl = unsigned char *zl = (unsigned char*)
rdbGenericLoadStringObject(rdb,RDB_LOAD_PLAIN,NULL); rdbGenericLoadStringObject(rdb,RDB_LOAD_PLAIN,NULL);
if (zl == NULL) return NULL; if (zl == NULL) return NULL;
quicklistAppendZiplist(ptrFromObj(o), zl); quicklistAppendZiplist((quicklist*)ptrFromObj(o), zl);
} }
} else if (rdbtype == RDB_TYPE_HASH_ZIPMAP || } else if (rdbtype == RDB_TYPE_HASH_ZIPMAP ||
rdbtype == RDB_TYPE_LIST_ZIPLIST || 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_ZSET_ZIPLIST ||
rdbtype == RDB_TYPE_HASH_ZIPLIST) rdbtype == RDB_TYPE_HASH_ZIPLIST)
{ {
unsigned char *encoded = unsigned char *encoded = (unsigned char*)
rdbGenericLoadStringObject(rdb,RDB_LOAD_PLAIN,NULL); rdbGenericLoadStringObject(rdb,RDB_LOAD_PLAIN,NULL);
if (encoded == NULL) return NULL; if (encoded == NULL) return NULL;
o = createObject(OBJ_STRING,encoded); /* Obj type fixed below. */ 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. */ * when loading dumps created by Redis 2.4 gets deprecated. */
{ {
unsigned char *zl = ziplistNew(); unsigned char *zl = ziplistNew();
unsigned char *zi = zipmapRewind(ptrFromObj(o)); unsigned char *zi = zipmapRewind((unsigned char*)ptrFromObj(o));
unsigned char *fstr, *vstr; unsigned char *fstr, *vstr;
unsigned int flen, vlen; unsigned int flen, vlen;
unsigned int maxlen = 0; unsigned int maxlen = 0;
@ -1637,7 +1637,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) {
case RDB_TYPE_SET_INTSET: case RDB_TYPE_SET_INTSET:
o->type = OBJ_SET; o->type = OBJ_SET;
o->encoding = OBJ_ENCODING_INTSET; 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); setTypeConvert(o,OBJ_ENCODING_HT);
break; break;
case RDB_TYPE_ZSET_ZIPLIST: case RDB_TYPE_ZSET_ZIPLIST:
@ -1658,14 +1658,14 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) {
} }
} else if (rdbtype == RDB_TYPE_STREAM_LISTPACKS) { } else if (rdbtype == RDB_TYPE_STREAM_LISTPACKS) {
o = createStreamObject(); o = createStreamObject();
stream *s = ptrFromObj(o); stream *s = (stream*)ptrFromObj(o);
uint64_t listpacks = rdbLoadLen(rdb,NULL); uint64_t listpacks = rdbLoadLen(rdb,NULL);
while(listpacks--) { while(listpacks--) {
/* Get the master ID, the one we'll use as key of the radix tree /* 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 * node: the entries inside the listpack itself are delta-encoded
* relatively to this ID. */ * relatively to this ID. */
sds nodekey = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL); sds nodekey = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL);
if (nodekey == NULL) { if (nodekey == NULL) {
rdbExitReportCorruptRDB("Stream master ID loading failed: invalid encoding or I/O error."); 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. */ /* Load the listpack. */
unsigned char *lp = unsigned char *lp = (unsigned char*)
rdbGenericLoadStringObject(rdb,RDB_LOAD_PLAIN,NULL); rdbGenericLoadStringObject(rdb,RDB_LOAD_PLAIN,NULL);
if (lp == NULL) return NULL; if (lp == NULL) return NULL;
unsigned char *first = lpFirst(lp); 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 * consumer group ASAP and populate its structure as
* we read more data. */ * we read more data. */
streamID cg_id; streamID cg_id;
sds cgname = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL); sds cgname = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL);
if (cgname == NULL) { if (cgname == NULL) {
rdbExitReportCorruptRDB( rdbExitReportCorruptRDB(
"Error reading the consumer group name from Stream"); "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. */ * consumers and their local PELs. */
size_t consumers_num = rdbLoadLen(rdb,NULL); size_t consumers_num = rdbLoadLen(rdb,NULL);
while(consumers_num--) { while(consumers_num--) {
sds cname = rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL); sds cname = (sds)rdbGenericLoadStringObject(rdb,RDB_LOAD_SDS,NULL);
if (cname == NULL) { if (cname == NULL) {
rdbExitReportCorruptRDB( rdbExitReportCorruptRDB(
"Error reading the consumer name from Stream group"); "Error reading the consumer name from Stream group");
@ -1756,7 +1756,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, robj *key) {
while(pel_size--) { while(pel_size--) {
unsigned char rawid[sizeof(streamID)]; unsigned char rawid[sizeof(streamID)];
rdbLoadRaw(rdb,rawid,sizeof(rawid)); 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) if (nack == raxNotFound)
rdbExitReportCorruptRDB("Consumer entry not found in " rdbExitReportCorruptRDB("Consumer entry not found in "
"group global PEL"); "group global PEL");
@ -1880,6 +1880,9 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi, int loading_aof) {
int type, rdbver; int type, rdbver;
redisDb *db = server.db+0; redisDb *db = server.db+0;
char buf[1024]; 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->update_cksum = rdbLoadProgressCallback;
rdb->max_processing_chunk = server.loading_process_events_interval_bytes; 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; return C_ERR;
} }
/* Key-specific attributes, set by opcodes before the key type. */ now = mstime();
long long lru_idle = -1, lfu_freq = -1, expiretime = -1, now = mstime(); lru_clock = LRU_CLOCK();
long long lru_clock = LRU_CLOCK();
while(1) { while(1) {
robj *key, *val; robj *key, *val;
@ -1975,38 +1977,38 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi, int loading_aof) {
serverLog(LL_NOTICE,"RDB '%s': %s", serverLog(LL_NOTICE,"RDB '%s': %s",
(char*)ptrFromObj(auxkey), (char*)ptrFromObj(auxkey),
(char*)ptrFromObj(auxval)); (char*)ptrFromObj(auxval));
} else if (!strcasecmp(ptrFromObj(auxkey),"repl-stream-db")) { } else if (!strcasecmp(szFromObj(auxkey),"repl-stream-db")) {
if (rsi) rsi->repl_stream_db = atoi(ptrFromObj(auxval)); if (rsi) rsi->repl_stream_db = atoi(szFromObj(auxval));
} else if (!strcasecmp(ptrFromObj(auxkey),"repl-id")) { } else if (!strcasecmp(szFromObj(auxkey),"repl-id")) {
if (rsi && sdslen(ptrFromObj(auxval)) == CONFIG_RUN_ID_SIZE) { if (rsi && sdslen(szFromObj(auxval)) == CONFIG_RUN_ID_SIZE) {
memcpy(rsi->repl_id,ptrFromObj(auxval),CONFIG_RUN_ID_SIZE+1); memcpy(rsi->repl_id,ptrFromObj(auxval),CONFIG_RUN_ID_SIZE+1);
rsi->repl_id_is_set = 1; rsi->repl_id_is_set = 1;
} }
} else if (!strcasecmp(ptrFromObj(auxkey),"repl-offset")) { } else if (!strcasecmp(szFromObj(auxkey),"repl-offset")) {
if (rsi) rsi->repl_offset = strtoll(ptrFromObj(auxval),NULL,10); if (rsi) rsi->repl_offset = strtoll(szFromObj(auxval),NULL,10);
} else if (!strcasecmp(ptrFromObj(auxkey),"lua")) { } else if (!strcasecmp(szFromObj(auxkey),"lua")) {
/* Load the script back in memory. */ /* Load the script back in memory. */
if (luaCreateFunction(NULL,server.lua,auxval) == NULL) { if (luaCreateFunction(NULL,server.lua,auxval) == NULL) {
rdbExitReportCorruptRDB( rdbExitReportCorruptRDB(
"Can't load Lua script from RDB file! " "Can't load Lua script from RDB file! "
"BODY: %s", ptrFromObj(auxval)); "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", serverLog(LL_NOTICE,"Loading RDB produced by version %s",
(const char*)ptrFromObj(auxval)); (const char*)ptrFromObj(auxval));
} else if (!strcasecmp(ptrFromObj(auxkey),"ctime")) { } else if (!strcasecmp(szFromObj(auxkey),"ctime")) {
time_t age = time(NULL)-strtol(ptrFromObj(auxval),NULL,10); time_t age = time(NULL)-strtol(szFromObj(auxval),NULL,10);
if (age < 0) age = 0; if (age < 0) age = 0;
serverLog(LL_NOTICE,"RDB age %ld seconds", serverLog(LL_NOTICE,"RDB age %ld seconds",
(unsigned long) age); (unsigned long) age);
} else if (!strcasecmp(ptrFromObj(auxkey),"used-mem")) { } else if (!strcasecmp(szFromObj(auxkey),"used-mem")) {
long long usedmem = strtoll(ptrFromObj(auxval),NULL,10); long long usedmem = strtoll(szFromObj(auxval),NULL,10);
serverLog(LL_NOTICE,"RDB memory usage when created %.2f Mb", serverLog(LL_NOTICE,"RDB memory usage when created %.2f Mb",
(double) usedmem / (1024*1024)); (double) usedmem / (1024*1024));
} else if (!strcasecmp(ptrFromObj(auxkey),"aof-preamble")) { } else if (!strcasecmp(szFromObj(auxkey),"aof-preamble")) {
long long haspreamble = strtoll(ptrFromObj(auxval),NULL,10); long long haspreamble = strtoll(szFromObj(auxval),NULL,10);
if (haspreamble) serverLog(LL_NOTICE,"RDB has an AOF tail"); 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. */ /* Just ignored. */
} else { } else {
/* We ignore fields we don't understand, as by AUX field /* 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 * 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 * can continue to be empty, so that it's just a special case of the
* normal code path. */ * 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; ok_slaves[0] = 0;
if (!bysignal && exitcode == 0) { if (!bysignal && exitcode == 0) {
int readlen = sizeof(uint64_t); 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 /* Make space for enough elements as specified by the first
* uint64_t element in the array. */ * 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 && if (readlen &&
read(server.rdb_pipe_read_result_from_child, ok_slaves+1, read(server.rdb_pipe_read_result_from_child, ok_slaves+1,
readlen) != readlen) readlen) != readlen)
@ -2240,7 +2242,7 @@ void backgroundSaveDoneHandlerSocket(int exitcode, int bysignal) {
listRewind(server.slaves,&li); listRewind(server.slaves,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
client *slave = ln->value; client *slave = (client*)ln->value;
if (slave->replstate == SLAVE_STATE_WAIT_BGSAVE_END) { if (slave->replstate == SLAVE_STATE_WAIT_BGSAVE_END) {
uint64_t j; uint64_t j;
@ -2326,16 +2328,16 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) {
/* Collect the file descriptors of the slaves we want to transfer /* Collect the file descriptors of the slaves we want to transfer
* the RDB to, which are i WAIT_BGSAVE_START state. */ * 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 /* We also allocate an array of corresponding client IDs. This will
* be useful for the child process in order to build the report * be useful for the child process in order to build the report
* (sent via unix pipe) that will be sent to the parent. */ * (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; numfds = 0;
listRewind(server.slaves,&li); listRewind(server.slaves,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
client *slave = ln->value; client *slave = (client*)ln->value;
if (slave->replstate == SLAVE_STATE_WAIT_BGSAVE_START) { if (slave->replstate == SLAVE_STATE_WAIT_BGSAVE_START) {
clientids[numfds] = slave->id; clientids[numfds] = slave->id;
@ -2395,7 +2397,7 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) {
* set to 0 if the replication process terminated with a success * set to 0 if the replication process terminated with a success
* or the error code if an error occurred. */ * or the error code if an error occurred. */
void *msg = zmalloc(sizeof(uint64_t)*(1+2*numfds), MALLOC_LOCAL); 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; uint64_t *ids = len+1;
int j, msglen; int j, msglen;
@ -2432,7 +2434,7 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) {
* replicationSetupSlaveForFullResync() turned it into BGSAVE_END */ * replicationSetupSlaveForFullResync() turned it into BGSAVE_END */
listRewind(server.slaves,&li); listRewind(server.slaves,&li);
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
client *slave = ln->value; client *slave = (client*)ln->value;
int j; int j;
for (j = 0; j < numfds; 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 /* The SCHEDULE option changes the behavior of BGSAVE when an AOF rewrite
* is in progress. Instead of returning an error a BGSAVE gets scheduled. */ * is in progress. Instead of returning an error a BGSAVE gets scheduled. */
if (c->argc > 1) { 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; schedule = 1;
} else { } else {
addReply(c,shared.syntaxerr); addReply(c,shared.syntaxerr);
@ -2550,7 +2552,7 @@ rdbSaveInfo *rdbPopulateSaveInfo(rdbSaveInfo *rsi) {
// BUGBUG, warn user about this incomplete implementation // BUGBUG, warn user about this incomplete implementation
serverLog(LL_WARNING, "Warning: Only backing up first master's information in RDB"); 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 /* If the instance is a slave we need a connected master
* in order to fetch the currently selected DB. */ * in order to fetch the currently selected DB. */

View File

@ -151,7 +151,7 @@ void backgroundSaveDoneHandler(int exitcode, int bysignal);
int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, long long expiretime); int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, long long expiretime);
robj *rdbLoadStringObject(rio *rdb); robj *rdbLoadStringObject(rio *rdb);
ssize_t rdbSaveStringObject(rio *rdb, robj *obj); 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); void *rdbGenericLoadStringObject(rio *rdb, int flags, size_t *lenptr);
int rdbSaveBinaryDoubleValue(rio *rdb, double val); int rdbSaveBinaryDoubleValue(rio *rdb, double val);
int rdbLoadBinaryDoubleValue(rio *rdb, double *val); int rdbLoadBinaryDoubleValue(rio *rdb, double *val);

View File

@ -41,10 +41,11 @@
#include <assert.h> #include <assert.h>
#include <math.h> #include <math.h>
#include <pthread.h> #include <pthread.h>
extern "C" {
#include <sds.h> /* Use hiredis sds. */ #include <sds.h> /* Use hiredis sds. */
#include "ae.h"
#include "hiredis.h" #include "hiredis.h"
}
#include "ae.h"
#include "adlist.h" #include "adlist.h"
#include "dict.h" #include "dict.h"
#include "zmalloc.h" #include "zmalloc.h"
@ -231,7 +232,7 @@ static int dictSdsKeyCompare(void *privdata, const void *key1,
} }
/* _serverAssert is needed by dict */ /* _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, "=== ASSERTION FAILED ===");
fprintf(stderr, "==> %s:%d '%s' is not true",file,line,estr); fprintf(stderr, "==> %s:%d '%s' is not true",file,line,estr);
*((char*)-1) = 'x'; *((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, static redisConfig *getRedisConfig(const char *ip, int port,
const char *hostsocket) 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; if (!cfg) return NULL;
redisContext *c = NULL; redisContext *c = NULL;
redisReply *reply = NULL, *sub_reply = NULL; redisReply *reply = NULL, *sub_reply = NULL;
@ -250,15 +253,14 @@ static redisConfig *getRedisConfig(const char *ip, int port,
c = redisConnectUnix(hostsocket); c = redisConnectUnix(hostsocket);
if (c == NULL || c->err) { if (c == NULL || c->err) {
fprintf(stderr,"Could not connect to Redis at "); 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); if (hostsocket == NULL) fprintf(stderr,"%s:%d: %s\n",ip,port,err);
else fprintf(stderr,"%s: %s\n",hostsocket,err); else fprintf(stderr,"%s: %s\n",hostsocket,err);
goto fail; goto fail;
} }
redisAppendCommand(c, "CONFIG GET %s", "save"); redisAppendCommand(c, "CONFIG GET %s", "save");
redisAppendCommand(c, "CONFIG GET %s", "appendonly"); redisAppendCommand(c, "CONFIG GET %s", "appendonly");
int i = 0;
void *r = NULL;
for (; i < 2; i++) { for (; i < 2; i++) {
int res = redisGetReply(c, &r); int res = redisGetReply(c, &r);
if (reply) freeReplyObject(reply); 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; if (reply->type != REDIS_REPLY_ARRAY || reply->elements < 2) goto fail;
sub_reply = reply->element[1]; sub_reply = reply->element[1];
char *value = sub_reply->str; const char *value = sub_reply->str;
if (!value) value = ""; if (!value) value = "";
switch (i) { switch (i) {
case 0: cfg->save = sdsnew(value); break; case 0: cfg->save = sdsnew(value); break;
@ -325,7 +327,7 @@ static void freeAllClients(void) {
while(ln) { while(ln) {
next = ln->next; next = ln->next;
freeClient(ln->value); freeClient((client)ln->value);
ln = next; ln = next;
} }
} }
@ -405,7 +407,7 @@ static void clientDone(client c) {
} }
static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) { static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
client c = privdata; client c = (client)privdata;
void *reply = NULL; void *reply = NULL;
UNUSED(el); UNUSED(el);
UNUSED(fd); UNUSED(fd);
@ -430,7 +432,7 @@ static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
fprintf(stderr,"Unexpected error reply, exiting...\n"); fprintf(stderr,"Unexpected error reply, exiting...\n");
exit(1); exit(1);
} }
redisReply *r = reply; redisReply *r = (redisReply*)reply;
int is_err = (r->type == REDIS_REPLY_ERROR); int is_err = (r->type == REDIS_REPLY_ERROR);
if (is_err && config.showerrors) { 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) { static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
client c = privdata; client c = (client)privdata;
UNUSED(el); UNUSED(el);
UNUSED(fd); UNUSED(fd);
UNUSED(mask); UNUSED(mask);
@ -565,10 +567,10 @@ static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
* for arguments randomization. * for arguments randomization.
* *
* Even when cloning another client, prefix commands are applied if needed.*/ * 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 j;
int is_cluster_client = (config.cluster_mode && thread_id >= 0); 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; const char *ip = NULL;
int port = 0; int port = 0;
@ -653,7 +655,7 @@ static client createClient(char *cmd, size_t len, client from, int thread_id) {
if (from) { if (from) {
c->randlen = from->randlen; c->randlen = from->randlen;
c->randfree = 0; 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. */ /* copy the offsets. */
for (j = 0; j < (int)c->randlen; j++) { for (j = 0; j < (int)c->randlen; j++) {
c->randptr[j] = c->obuf + (from->randptr[j]-from->obuf); 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->randlen = 0;
c->randfree = RANDPTR_INITIAL_SIZE; 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) { while ((p = strstr(p,"__rand_int__")) != NULL) {
if (c->randfree == 0) { 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->randfree += c->randlen;
} }
c->randptr[c->randlen++] = p; c->randptr[c->randlen++] = p;
@ -682,7 +684,7 @@ static client createClient(char *cmd, size_t len, client from, int thread_id) {
if (from) { if (from) {
c->staglen = from->staglen; c->staglen = from->staglen;
c->stagfree = 0; 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. */ /* copy the offsets. */
for (j = 0; j < (int)c->staglen; j++) { for (j = 0; j < (int)c->staglen; j++) {
c->stagptr[j] = c->obuf + (from->stagptr[j]-from->obuf); 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->staglen = 0;
c->stagfree = RANDPTR_INITIAL_SIZE; 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) { while ((p = strstr(p,"{tag}")) != NULL) {
if (c->stagfree == 0) { if (c->stagfree == 0) {
c->stagptr = zrealloc(c->stagptr, c->stagptr = (char**)zrealloc(c->stagptr,
sizeof(char*) * c->staglen*2, MALLOC_LOCAL); sizeof(char*) * c->staglen*2, MALLOC_LOCAL);
c->stagfree += c->staglen; c->stagfree += c->staglen;
} }
@ -821,7 +823,7 @@ static void showLatencyReport(void) {
static void initBenchmarkThreads() { static void initBenchmarkThreads() {
int i; int i;
if (config.threads) freeBenchmarkThreads(); 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++) { for (i = 0; i < config.num_threads; i++) {
benchmarkThread *thread = createBenchmarkThread(i); benchmarkThread *thread = createBenchmarkThread(i);
config.threads[i] = thread; config.threads[i] = thread;
@ -841,7 +843,7 @@ static void startBenchmarkThreads() {
pthread_join(config.threads[i]->thread, NULL); 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; client c;
config.title = title; config.title = title;
@ -867,7 +869,7 @@ static void benchmark(char *title, char *cmd, int len) {
/* Thread functions. */ /* Thread functions. */
static benchmarkThread *createBenchmarkThread(int index) { 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; if (thread == NULL) return NULL;
thread->index = index; thread->index = index;
thread->el = aeCreateEventLoop(1024*10); thread->el = aeCreateEventLoop(1024*10);
@ -899,7 +901,7 @@ static void *execBenchmarkThread(void *ptr) {
/* Cluster helper functions. */ /* Cluster helper functions. */
static clusterNode *createClusterNode(char *ip, int port) { 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; if (!node) return NULL;
node->ip = ip; node->ip = ip;
node->port = port; node->port = port;
@ -907,7 +909,7 @@ static clusterNode *createClusterNode(char *ip, int port) {
node->flags = 0; node->flags = 0;
node->replicate = NULL; node->replicate = NULL;
node->replicas_count = 0; 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->slots_count = 0;
node->current_slot_index = 0; node->current_slot_index = 0;
node->updated_slots = NULL; node->updated_slots = NULL;
@ -953,7 +955,7 @@ static void freeClusterNodes() {
static clusterNode **addClusterNode(clusterNode *node) { static clusterNode **addClusterNode(clusterNode *node) {
int count = config.cluster_node_count + 1; 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); count * sizeof(*node), MALLOC_LOCAL);
if (!config.cluster_nodes) return NULL; if (!config.cluster_nodes) return NULL;
config.cluster_nodes[config.cluster_node_count++] = node; config.cluster_nodes[config.cluster_node_count++] = node;
@ -964,6 +966,7 @@ static int fetchClusterConfiguration() {
int success = 1; int success = 1;
redisContext *ctx = NULL; redisContext *ctx = NULL;
redisReply *reply = NULL; redisReply *reply = NULL;
char *lines = reply->str, *p, *line;
if (config.hostsocket == NULL) if (config.hostsocket == NULL)
ctx = redisConnect(config.hostip,config.hostport); ctx = redisConnect(config.hostip,config.hostport);
else else
@ -979,7 +982,7 @@ static int fetchClusterConfiguration() {
clusterNode *firstNode = createClusterNode((char *) config.hostip, clusterNode *firstNode = createClusterNode((char *) config.hostip,
config.hostport); config.hostport);
if (!firstNode) {success = 0; goto cleanup;} if (!firstNode) {success = 0; goto cleanup;}
reply = redisCommand(ctx, "CLUSTER NODES"); reply = (redisReply*)redisCommand(ctx, "CLUSTER NODES");
success = (reply != NULL); success = (reply != NULL);
if (!success) goto cleanup; if (!success) goto cleanup;
success = (reply->type != REDIS_REPLY_ERROR); success = (reply->type != REDIS_REPLY_ERROR);
@ -993,7 +996,7 @@ static int fetchClusterConfiguration() {
} }
goto cleanup; goto cleanup;
} }
char *lines = reply->str, *p, *line; lines = reply->str;
while ((p = strstr(lines, "\n")) != NULL) { while ((p = strstr(lines, "\n")) != NULL) {
*p = '\0'; *p = '\0';
line = lines; line = lines;
@ -1077,7 +1080,7 @@ static int fetchClusterConfiguration() {
sds dst = sdsnew(p); sds dst = sdsnew(p);
node->migrating_count += 2; node->migrating_count += 2;
node->migrating = node->migrating =
zrealloc(node->migrating, (char**)zrealloc(node->migrating,
(node->migrating_count * sizeof(sds)), MALLOC_LOCAL); (node->migrating_count * sizeof(sds)), MALLOC_LOCAL);
node->migrating[node->migrating_count - 2] = node->migrating[node->migrating_count - 2] =
slot; slot;
@ -1091,7 +1094,7 @@ static int fetchClusterConfiguration() {
sds slot = sdsnew(slotsdef); sds slot = sdsnew(slotsdef);
sds src = sdsnew(p); sds src = sdsnew(p);
node->importing_count += 2; node->importing_count += 2;
node->importing = zrealloc(node->importing, node->importing = (char**)zrealloc(node->importing,
(node->importing_count * sizeof(sds)), MALLOC_LOCAL); (node->importing_count * sizeof(sds)), MALLOC_LOCAL);
node->importing[node->importing_count - 2] = node->importing[node->importing_count - 2] =
slot; slot;
@ -1183,7 +1186,7 @@ static int fetchClusterSlotsConfiguration(client c) {
node->updated_slots_count = 0; node->updated_slots_count = 0;
dictReplace(masters, node->name, node) ; dictReplace(masters, node->name, node) ;
} }
reply = redisCommand(ctx, "CLUSTER SLOTS"); reply = (redisReply*)redisCommand(ctx, "CLUSTER SLOTS");
if (reply == NULL || reply->type == REDIS_REPLY_ERROR) { if (reply == NULL || reply->type == REDIS_REPLY_ERROR) {
success = 0; success = 0;
if (reply) if (reply)
@ -1211,9 +1214,9 @@ static int fetchClusterSlotsConfiguration(client c) {
goto cleanup; goto cleanup;
} }
sdsfree(name); sdsfree(name);
clusterNode *node = dictGetVal(entry); clusterNode *node = (clusterNode*)dictGetVal(entry);
if (node->updated_slots == NULL) 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++) for (slot = from; slot <= to; slot++)
node->updated_slots[node->updated_slots_count++] = 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 /* 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). */ * 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]; char buf[256];
int l = strlen(name); int l = strlen(name);
@ -1499,7 +1502,7 @@ int main(int argc, const char **argv) {
argc -= i; argc -= i;
argv += 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) { if (config.cluster_mode) {
/* Fetch cluster configuration. */ /* Fetch cluster configuration. */
@ -1596,7 +1599,7 @@ int main(int argc, const char **argv) {
} }
/* Run default benchmark suite. */ /* Run default benchmark suite. */
data = zmalloc(config.datasize+1, MALLOC_LOCAL); data = (char*)zmalloc(config.datasize+1, MALLOC_LOCAL);
do { do {
memset(data,'x',config.datasize); memset(data,'x',config.datasize);
data[config.datasize] = '\0'; data[config.datasize] = '\0';

View File

@ -190,7 +190,7 @@ int redis_check_aof_main(int argc, char **argv) {
if (has_preamble) { if (has_preamble) {
printf("The AOF appears to start with an RDB preamble.\n" printf("The AOF appears to start with an RDB preamble.\n"
"Checking the RDB preamble to start:\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"); printf("RDB preamble of AOF file is not sane, aborting.\n");
exit(1); exit(1);
} else { } else {

View File

@ -37,7 +37,7 @@ void rdbLoadProgressCallback(rio *r, const void *buf, size_t len);
int rdbCheckMode = 0; int rdbCheckMode = 0;
struct { struct {
rio *rio; ::rio *rio;
robj *key; /* Current key we are reading. */ robj *key; /* Current key we are reading. */
int key_type; /* Current key type if != -1. */ int key_type; /* Current key type if != -1. */
unsigned long keys; /* Number of keys processed. */ unsigned long keys; /* Number of keys processed. */
@ -59,7 +59,7 @@ struct {
#define RDB_CHECK_DOING_READ_LEN 6 #define RDB_CHECK_DOING_READ_LEN 6
#define RDB_CHECK_DOING_READ_AUX 7 #define RDB_CHECK_DOING_READ_AUX 7
char *rdb_check_doing_string[] = { const char *rdb_check_doing_string[] = {
"start", "start",
"read-type", "read-type",
"read-expire", "read-expire",
@ -70,7 +70,7 @@ char *rdb_check_doing_string[] = {
"read-aux" "read-aux"
}; };
char *rdb_type_string[] = { const char *rdb_type_string[] = {
"string", "string",
"list-linked", "list-linked",
"set-hashtable", "set-hashtable",
@ -176,7 +176,7 @@ void rdbCheckSetupSignals(void) {
* 1 is returned. * 1 is returned.
* The file is specified as a filename in 'rdbfilename' if 'fp' is not NULL, * The file is specified as a filename in 'rdbfilename' if 'fp' is not NULL,
* otherwise the already open file 'fp' is checked. */ * 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; uint64_t dbid;
int type, rdbver; int type, rdbver;
char buf[1024]; char buf[1024];
@ -339,7 +339,7 @@ err:
* status code according to success (RDB is sane) or error (RDB is corrupted). * 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 * Otherwise if called with a non NULL fp, the function returns C_OK or
* C_ERR depending on the success or failure. */ * 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) { if (argc != 2 && fp == NULL) {
fprintf(stderr, "Usage: %s <rdb-file-name>\n", argv[0]); fprintf(stderr, "Usage: %s <rdb-file-name>\n", argv[0]);
exit(1); exit(1);

933
src/redis-cli-cpphelper.cpp Normal file
View File

@ -0,0 +1,933 @@
#include "fmacros.h"
#include "version.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <assert.h>
#include <fcntl.h>
#include <limits.h>
#include <math.h>
extern "C" {
#include <hiredis.h>
#include <sds.h> /* 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;i<keys->elements;i++) {
redisAppendCommand(context, "TYPE %s", keys->element[i]->str);
}
/* Retrieve types */
for(i=0;i<keys->elements;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;i<keys->elements;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->biggest<sizes[i]) {
printf(
"[%05.2f%%] Biggest %-6s found so far '%s' with %llu %s\n",
pct, type->name, 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);
}

File diff suppressed because it is too large Load Diff

279
src/redis-cli.h Normal file
View File

@ -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

View File

@ -186,9 +186,9 @@ void freeReplicationBacklog(void) {
* This function also increments the global replication offset stored at * This function also increments the global replication offset stored at
* server.master_repl_offset, because there is no case where we want to feed * server.master_repl_offset, because there is no case where we want to feed
* the backlog without incrementing the offset. */ * the backlog without incrementing the offset. */
void feedReplicationBacklog(void *ptr, size_t len) { void feedReplicationBacklog(const void *ptr, size_t len) {
serverAssert(GlobalLocksAcquired()); serverAssert(GlobalLocksAcquired());
unsigned char *p = (unsigned char*)ptr; const unsigned char *p = (const unsigned char*)ptr;
server.master_repl_offset += len; server.master_repl_offset += len;

View File

@ -266,8 +266,8 @@ void rioInitWithFdset(rio *r, int *fds, int numfds) {
int j; int j;
*r = rioFdsetIO; *r = rioFdsetIO;
r->io.fdset.fds = zmalloc(sizeof(int)*numfds, MALLOC_LOCAL); r->io.fdset.fds = (int*)zmalloc(sizeof(int)*numfds, MALLOC_LOCAL);
r->io.fdset.state = 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); memcpy(r->io.fdset.fds,fds,sizeof(int)*numfds);
for (j = 0; j < numfds; j++) r->io.fdset.state[j] = 0; for (j = 0; j < numfds; j++) r->io.fdset.state[j] = 0;
r->io.fdset.numfds = numfds; 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 /* This function can be installed both in memory and file streams when checksum
* computation is needed. */ * computation is needed. */
void rioGenericUpdateChecksum(rio *r, const void *buf, size_t len) { 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. /* Set the file-based rio object to auto-fsync every 'bytes' file written.

View File

@ -36,6 +36,10 @@
#include <stdint.h> #include <stdint.h>
#include "sds.h" #include "sds.h"
#ifdef __cplusplus
extern "C" {
#endif
struct _rio { struct _rio {
/* Backend functions. /* Backend functions.
* Since this functions do not tolerate short writes or reads the return * 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 rioGenericUpdateChecksum(rio *r, const void *buf, size_t len);
void rioSetAutoSync(rio *r, off_t bytes); void rioSetAutoSync(rio *r, off_t bytes);
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -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). /* Join an array of C strings using the specified separator (also a C string).
* Returns the result as an sds 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(); sds join = sdsempty();
int j; int j;

View File

@ -60,6 +60,10 @@ struct __attribute__ ((__packed__)) sdshdr8 {
unsigned char flags; /* 3 lsb of type, 5 unused bits */ unsigned char flags; /* 3 lsb of type, 5 unused bits */
#ifndef __cplusplus #ifndef __cplusplus
char buf[]; char buf[];
#else
char *buf() {
return reinterpret_cast<char*>(this+1);
}
#endif #endif
}; };
struct __attribute__ ((__packed__)) sdshdr16 { struct __attribute__ ((__packed__)) sdshdr16 {
@ -270,7 +274,7 @@ sds sdsfromlonglong(long long value);
sds sdscatrepr(sds s, const char *p, size_t len); sds sdscatrepr(sds s, const char *p, size_t len);
sds *sdssplitargs(const char *line, int *argc); sds *sdssplitargs(const char *line, int *argc);
sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen); 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); sds sdsjoinsds(sds *argv, int argc, const char *sep, size_t seplen);
/* Low level functions exposed to the user API */ /* Low level functions exposed to the user API */

View File

@ -375,7 +375,7 @@ sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master);
void sentinelScheduleScriptExecution(char *path, ...); void sentinelScheduleScriptExecution(char *path, ...);
void sentinelStartFailover(sentinelRedisInstance *master); void sentinelStartFailover(sentinelRedisInstance *master);
void sentinelDiscardReplyCallback(redisAsyncContext *c, void *reply, void *privdata); 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); char *sentinelVoteLeader(sentinelRedisInstance *master, uint64_t req_epoch, char *req_runid, uint64_t *leader_epoch);
void sentinelFlushConfig(void); void sentinelFlushConfig(void);
void sentinelGenerateInitialMonitorEvents(void); void sentinelGenerateInitialMonitorEvents(void);
@ -394,7 +394,7 @@ void releaseSentinelRedisInstance(sentinelRedisInstance *ri);
void dictInstancesValDestructor (void *privdata, void *obj) { void dictInstancesValDestructor (void *privdata, void *obj) {
UNUSED(privdata); UNUSED(privdata);
releaseSentinelRedisInstance(obj); releaseSentinelRedisInstance((sentinelRedisInstance*)obj);
} }
/* Instance name (sds) -> instance (sentinelRedisInstance pointer) /* Instance name (sds) -> instance (sentinelRedisInstance pointer)
@ -554,7 +554,7 @@ sentinelAddr *createSentinelAddr(char *hostname, int port) {
errno = ENOENT; errno = ENOENT;
return NULL; return NULL;
} }
sa = zmalloc(sizeof(*sa), MALLOC_LOCAL); sa = (sentinelAddr*)zmalloc(sizeof(*sa), MALLOC_LOCAL);
sa->ip = sdsnew(ip); sa->ip = sdsnew(ip);
sa->port = port; sa->port = port;
return sa; return sa;
@ -564,7 +564,7 @@ sentinelAddr *createSentinelAddr(char *hostname, int port) {
sentinelAddr *dupSentinelAddr(sentinelAddr *src) { sentinelAddr *dupSentinelAddr(sentinelAddr *src) {
sentinelAddr *sa; sentinelAddr *sa;
sa = zmalloc(sizeof(*sa), MALLOC_LOCAL); sa = (sentinelAddr*)zmalloc(sizeof(*sa), MALLOC_LOCAL);
sa->ip = sdsnew(src->ip); sa->ip = sdsnew(src->ip);
sa->port = src->port; sa->port = src->port;
return sa; return sa;
@ -607,7 +607,7 @@ int sentinelAddrIsEqual(sentinelAddr *a, sentinelAddr *b) {
* *
* Any other specifier after "%@" is processed by printf itself. * 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, ...) { const char *fmt, ...) {
va_list ap; va_list ap;
char msg[LOG_MAX_LEN]; char msg[LOG_MAX_LEN];
@ -674,7 +674,7 @@ void sentinelGenerateInitialMonitorEvents(void) {
di = dictGetIterator(sentinel.masters); di = dictGetIterator(sentinel.masters);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
sentinelEvent(LL_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum); sentinelEvent(LL_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum);
} }
dictReleaseIterator(di); dictReleaseIterator(di);
@ -708,10 +708,10 @@ void sentinelScheduleScriptExecution(char *path, ...) {
va_end(ap); va_end(ap);
argv[0] = sdsnew(path); argv[0] = sdsnew(path);
sj = zmalloc(sizeof(*sj), MALLOC_LOCAL); sj = (sentinelScriptJob*)zmalloc(sizeof(*sj), MALLOC_LOCAL);
sj->flags = SENTINEL_SCRIPT_NONE; sj->flags = SENTINEL_SCRIPT_NONE;
sj->retry_num = 0; 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->start_time = 0;
sj->pid = 0; sj->pid = 0;
memcpy(sj->argv,argv,sizeof(char*)*(argc+1)); memcpy(sj->argv,argv,sizeof(char*)*(argc+1));
@ -725,7 +725,7 @@ void sentinelScheduleScriptExecution(char *path, ...) {
listRewind(sentinel.scripts_queue,&li); listRewind(sentinel.scripts_queue,&li);
while ((ln = listNext(&li)) != NULL) { while ((ln = listNext(&li)) != NULL) {
sj = ln->value; sj = (sentinelScriptJob*)ln->value;
if (sj->flags & SENTINEL_SCRIPT_RUNNING) continue; if (sj->flags & SENTINEL_SCRIPT_RUNNING) continue;
/* The first node is the oldest as we add on tail. */ /* 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); listRewind(sentinel.scripts_queue,&li);
while ((ln = listNext(&li)) != NULL) { while ((ln = listNext(&li)) != NULL) {
sentinelScriptJob *sj = ln->value; sentinelScriptJob *sj = (sentinelScriptJob*)ln->value;
if ((sj->flags & SENTINEL_SCRIPT_RUNNING) && sj->pid == pid) if ((sj->flags & SENTINEL_SCRIPT_RUNNING) && sj->pid == pid)
return ln; return ln;
@ -767,7 +767,7 @@ void sentinelRunPendingScripts(void) {
while (sentinel.running_scripts < SENTINEL_SCRIPT_MAX_RUNNING && while (sentinel.running_scripts < SENTINEL_SCRIPT_MAX_RUNNING &&
(ln = listNext(&li)) != NULL) (ln = listNext(&li)) != NULL)
{ {
sentinelScriptJob *sj = ln->value; sentinelScriptJob *sj = (sentinelScriptJob*)ln->value;
pid_t pid; pid_t pid;
/* Skip if already running. */ /* 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); serverLog(LL_WARNING,"wait3() returned a pid (%ld) we can't find in our scripts execution queue!", (long)pid);
continue; continue;
} }
sj = ln->value; sj = (sentinelScriptJob*)ln->value;
/* If the script was terminated by a signal or returns an /* If the script was terminated by a signal or returns an
* exit code of "1" (that means: please retry), we reschedule it * exit code of "1" (that means: please retry), we reschedule it
@ -874,7 +874,7 @@ void sentinelKillTimedoutScripts(void) {
listRewind(sentinel.scripts_queue,&li); listRewind(sentinel.scripts_queue,&li);
while ((ln = listNext(&li)) != NULL) { while ((ln = listNext(&li)) != NULL) {
sentinelScriptJob *sj = ln->value; sentinelScriptJob *sj = (sentinelScriptJob*)ln->value;
if (sj->flags & SENTINEL_SCRIPT_RUNNING && if (sj->flags & SENTINEL_SCRIPT_RUNNING &&
(now - sj->start_time) > SENTINEL_SCRIPT_MAX_RUNTIME) (now - sj->start_time) > SENTINEL_SCRIPT_MAX_RUNTIME)
@ -894,7 +894,7 @@ void sentinelPendingScriptsCommand(client *c) {
addReplyArrayLen(c,listLength(sentinel.scripts_queue)); addReplyArrayLen(c,listLength(sentinel.scripts_queue));
listRewind(sentinel.scripts_queue,&li); listRewind(sentinel.scripts_queue,&li);
while ((ln = listNext(&li)) != NULL) { while ((ln = listNext(&li)) != NULL) {
sentinelScriptJob *sj = ln->value; sentinelScriptJob *sj = (sentinelScriptJob*)ln->value;
int j = 0; int j = 0;
addReplyMapLen(c,5); addReplyMapLen(c,5);
@ -939,7 +939,7 @@ void sentinelPendingScriptsCommand(client *c) {
* *
* from/to fields are respectively master -> promoted slave addresses for * from/to fields are respectively master -> promoted slave addresses for
* "start" and "end". */ * "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]; char fromport[32], toport[32];
if (master->client_reconfig_script == NULL) return; 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. */ /* Create a not yet connected link object. */
instanceLink *createInstanceLink(void) { instanceLink *createInstanceLink(void) {
instanceLink *link = zmalloc(sizeof(*link), MALLOC_LOCAL); instanceLink *link = (instanceLink*)zmalloc(sizeof(*link), MALLOC_LOCAL);
link->refcount = 1; link->refcount = 1;
link->disconnected = 1; link->disconnected = 1;
@ -1053,7 +1053,7 @@ int sentinelTryConnectionSharing(sentinelRedisInstance *ri) {
di = dictGetIterator(sentinel.masters); di = dictGetIterator(sentinel.masters);
while((de = dictNext(di)) != NULL) { 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 /* We want to share with the same physical Sentinel referenced
* in other masters, so skip our master. */ * in other masters, so skip our master. */
if (master == ri->master) continue; if (master == ri->master) continue;
@ -1087,7 +1087,7 @@ int sentinelUpdateSentinelAddressInAllMasters(sentinelRedisInstance *ri) {
di = dictGetIterator(sentinel.masters); di = dictGetIterator(sentinel.masters);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *master = dictGetVal(de), *match; sentinelRedisInstance *master = (sentinelRedisInstance*)dictGetVal(de), *match;
match = getSentinelRedisInstanceByAddrAndRunID(master->sentinels, match = getSentinelRedisInstanceByAddrAndRunID(master->sentinels,
NULL,0,ri->runid); NULL,0,ri->runid);
/* If there is no match, this master does not know about this /* 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 * Note: we don't free the hiredis context as hiredis will do it for us
* for async connections. */ * for async connections. */
void instanceLinkConnectionError(const redisAsyncContext *c) { void instanceLinkConnectionError(const redisAsyncContext *c) {
instanceLink *link = c->data; instanceLink *link = (instanceLink*)c->data;
int pubsub; int pubsub;
if (!link) return; if (!link) return;
@ -1205,7 +1205,7 @@ sentinelRedisInstance *createSentinelRedisInstance(char *name, int flags, char *
} }
/* Create the instance object. */ /* 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, /* Note that all the instances are started in the disconnected state,
* the event loop will take care of connecting them. */ * the event loop will take care of connecting them. */
ri->flags = flags; ri->flags = flags;
@ -1303,7 +1303,7 @@ sentinelRedisInstance *sentinelRedisInstanceLookupSlave(
serverAssert(ri->flags & SRI_MASTER); serverAssert(ri->flags & SRI_MASTER);
anetFormatAddr(buf,sizeof(buf),ip,port); anetFormatAddr(buf,sizeof(buf),ip,port);
key = sdsnew(buf); key = sdsnew(buf);
slave = dictFetchValue(ri->slaves,key); slave = (sentinelRedisInstance*)dictFetchValue(ri->slaves,key);
sdsfree(key); sdsfree(key);
return slave; return slave;
} }
@ -1336,7 +1336,7 @@ int removeMatchingSentinelFromMaster(sentinelRedisInstance *master, char *runid)
di = dictGetSafeIterator(master->sentinels); di = dictGetSafeIterator(master->sentinels);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
if (ri->runid && strcmp(ri->runid,runid) == 0) { if (ri->runid && strcmp(ri->runid,runid) == 0) {
dictDelete(master->sentinels,ri->name); 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. */ serverAssert(ip || runid); /* User must pass at least one search param. */
di = dictGetIterator(instances); di = dictGetIterator(instances);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
if (runid && !ri->runid) continue; if (runid && !ri->runid) continue;
if ((runid == NULL || strcmp(ri->runid, runid) == 0) && if ((runid == NULL || strcmp(ri->runid, runid) == 0) &&
@ -1381,7 +1381,7 @@ sentinelRedisInstance *sentinelGetMasterByName(char *name) {
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
sds sdsname = sdsnew(name); sds sdsname = sdsnew(name);
ri = dictFetchValue(sentinel.masters,sdsname); ri = (sentinelRedisInstance*)dictFetchValue(sentinel.masters,sdsname);
sdsfree(sdsname); sdsfree(sdsname);
return ri; return ri;
} }
@ -1393,7 +1393,7 @@ void sentinelAddFlagsToDictOfRedisInstances(dict *instances, int flags) {
di = dictGetIterator(instances); di = dictGetIterator(instances);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
ri->flags |= flags; ri->flags |= flags;
} }
dictReleaseIterator(di); dictReleaseIterator(di);
@ -1407,7 +1407,7 @@ void sentinelDelFlagsToDictOfRedisInstances(dict *instances, int flags) {
di = dictGetIterator(instances); di = dictGetIterator(instances);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
ri->flags &= ~flags; ri->flags &= ~flags;
} }
dictReleaseIterator(di); dictReleaseIterator(di);
@ -1467,7 +1467,7 @@ int sentinelResetMastersByPattern(char *pattern, int flags) {
di = dictGetIterator(sentinel.masters); di = dictGetIterator(sentinel.masters);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
if (ri->name) { if (ri->name) {
if (stringmatch(pattern,ri->name,0)) { 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. */ * Don't include the one having the address we are switching to. */
di = dictGetIterator(master->slaves); di = dictGetIterator(master->slaves);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *slave = dictGetVal(de); sentinelRedisInstance *slave = (sentinelRedisInstance*)dictGetVal(de);
if (sentinelAddrIsEqual(slave->addr,newaddr)) continue; 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, slaves[numslaves++] = createSentinelAddr(slave->addr->ip,
slave->addr->port); 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 * as a slave as well, so that we'll be able to sense / reconfigure
* the old master. */ * the old master. */
if (!sentinelAddrIsEqual(newaddr,master->addr)) { 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, slaves[numslaves++] = createSentinelAddr(master->addr->ip,
master->addr->port); master->addr->port);
} }
@ -1584,14 +1584,14 @@ void sentinelPropagateDownAfterPeriod(sentinelRedisInstance *master) {
for (j = 0; d[j]; j++) { for (j = 0; d[j]; j++) {
di = dictGetIterator(d[j]); di = dictGetIterator(d[j]);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
ri->down_after_period = master->down_after_period; ri->down_after_period = master->down_after_period;
} }
dictReleaseIterator(di); dictReleaseIterator(di);
} }
} }
char *sentinelGetInstanceTypeString(sentinelRedisInstance *ri) { const char *sentinelGetInstanceTypeString(sentinelRedisInstance *ri) {
if (ri->flags & SRI_MASTER) return "master"; if (ri->flags & SRI_MASTER) return "master";
else if (ri->flags & SRI_SLAVE) return "slave"; else if (ri->flags & SRI_SLAVE) return "slave";
else if (ri->flags & SRI_SENTINEL) return "sentinel"; 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 * 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, * to the set of renamed commads. However, if the command was not renamed,
* we just return "command" itself. */ * we just return "command" itself. */
char *sentinelInstanceMapCommand(sentinelRedisInstance *ri, char *command) { const char *sentinelInstanceMapCommand(sentinelRedisInstance *ri, const char *command) {
sds sc = sdsnew(command); sds sc = sdsnew(command);
if (ri->master) ri = ri->master; if (ri->master) ri = ri->master;
char *retval = dictFetchValue(ri->renamed_commands, sc); char *retval = (char*)dictFetchValue(ri->renamed_commands, sc);
sdsfree(sc); sdsfree(sc);
return retval ? retval : command; return retval ? retval : command;
} }
/* ============================ Config handling ============================= */ /* ============================ Config handling ============================= */
char *sentinelHandleConfiguration(char **argv, int argc) { const char *sentinelHandleConfiguration(char **argv, int argc) {
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
if (!strcasecmp(argv[0],"monitor") && argc == 5) { if (!strcasecmp(argv[0],"monitor") && argc == 5) {
@ -1781,7 +1781,7 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) {
sentinelAddr *master_addr; sentinelAddr *master_addr;
/* sentinel monitor */ /* sentinel monitor */
master = dictGetVal(de); master = (sentinelRedisInstance*)dictGetVal(de);
master_addr = sentinelGetCurrentMasterAddress(master); master_addr = sentinelGetCurrentMasterAddress(master);
line = sdscatprintf(sdsempty(),"sentinel monitor %s %s %d %d", line = sdscatprintf(sdsempty(),"sentinel monitor %s %s %d %d",
master->name, master_addr->ip, master_addr->port, master->name, master_addr->ip, master_addr->port,
@ -1853,7 +1853,7 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) {
while((de = dictNext(di2)) != NULL) { while((de = dictNext(di2)) != NULL) {
sentinelAddr *slave_addr; sentinelAddr *slave_addr;
ri = dictGetVal(de); ri = (sentinelRedisInstance*)dictGetVal(de);
slave_addr = ri->addr; slave_addr = ri->addr;
/* If master_addr (obtained using sentinelGetCurrentMasterAddress() /* If master_addr (obtained using sentinelGetCurrentMasterAddress()
@ -1873,7 +1873,7 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) {
/* sentinel known-sentinel */ /* sentinel known-sentinel */
di2 = dictGetIterator(master->sentinels); di2 = dictGetIterator(master->sentinels);
while((de = dictNext(di2)) != NULL) { while((de = dictNext(di2)) != NULL) {
ri = dictGetVal(de); ri = (sentinelRedisInstance*)dictGetVal(de);
if (ri->runid == NULL) continue; if (ri->runid == NULL) continue;
line = sdscatprintf(sdsempty(), line = sdscatprintf(sdsempty(),
"sentinel known-sentinel %s %s %d %s", "sentinel known-sentinel %s %s %d %s",
@ -1885,8 +1885,8 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) {
/* sentinel rename-command */ /* sentinel rename-command */
di2 = dictGetIterator(master->renamed_commands); di2 = dictGetIterator(master->renamed_commands);
while((de = dictNext(di2)) != NULL) { while((de = dictNext(di2)) != NULL) {
sds oldname = dictGetKey(de); sds oldname = (sds)dictGetKey(de);
sds newname = dictGetVal(de); sds newname = (sds)dictGetVal(de);
line = sdscatprintf(sdsempty(), line = sdscatprintf(sdsempty(),
"sentinel rename-command %s %s %s", "sentinel rename-command %s %s %s",
master->name, oldname, newname); 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 * This makes it possible to list all the sentinel instances connected
* to a Redis servewr with CLIENT LIST, grepping for a specific name format. */ * 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]; char name[64];
snprintf(name,sizeof(name),"sentinel-%.8s-%s",sentinel.myid,type); 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) { void sentinelInfoReplyCallback(redisAsyncContext *c, void *reply, void *privdata) {
sentinelRedisInstance *ri = privdata; sentinelRedisInstance *ri = (sentinelRedisInstance*)privdata;
instanceLink *link = c->data; instanceLink *link = (instanceLink*)c->data;
redisReply *r; redisReply *r;
if (!reply || !link) return; if (!reply || !link) return;
link->pending_commands--; link->pending_commands--;
r = reply; r = (redisReply*)reply;
if (r->type == REDIS_REPLY_STRING) if (r->type == REDIS_REPLY_STRING)
sentinelRefreshInstanceInfo(ri,r->str); 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 /* Just discard the reply. We use this when we are not monitoring the return
* value of the command but its effects directly. */ * value of the command but its effects directly. */
void sentinelDiscardReplyCallback(redisAsyncContext *c, void *reply, void *privdata) { void sentinelDiscardReplyCallback(redisAsyncContext *c, void *reply, void *privdata) {
instanceLink *link = c->data; instanceLink *link = (instanceLink*)c->data;
UNUSED(reply); UNUSED(reply);
UNUSED(privdata); UNUSED(privdata);
@ -2360,13 +2360,13 @@ void sentinelDiscardReplyCallback(redisAsyncContext *c, void *reply, void *privd
} }
void sentinelPingReplyCallback(redisAsyncContext *c, void *reply, void *privdata) { void sentinelPingReplyCallback(redisAsyncContext *c, void *reply, void *privdata) {
sentinelRedisInstance *ri = privdata; sentinelRedisInstance *ri = (sentinelRedisInstance*)privdata;
instanceLink *link = c->data; instanceLink *link = (instanceLink*)c->data;
redisReply *r; redisReply *r;
if (!reply || !link) return; if (!reply || !link) return;
link->pending_commands--; link->pending_commands--;
r = reply; r = (redisReply*)reply;
if (r->type == REDIS_REPLY_STATUS || if (r->type == REDIS_REPLY_STATUS ||
r->type == REDIS_REPLY_ERROR) { 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 /* This is called when we get the reply about the PUBLISH command we send
* to the master to advertise this sentinel. */ * to the master to advertise this sentinel. */
void sentinelPublishReplyCallback(redisAsyncContext *c, void *reply, void *privdata) { void sentinelPublishReplyCallback(redisAsyncContext *c, void *reply, void *privdata) {
sentinelRedisInstance *ri = privdata; sentinelRedisInstance *ri = (sentinelRedisInstance*)privdata;
instanceLink *link = c->data; instanceLink *link = (instanceLink*)c->data;
redisReply *r; redisReply *r;
if (!reply || !link) return; if (!reply || !link) return;
link->pending_commands--; link->pending_commands--;
r = reply; r = (redisReply*)reply;
/* Only update pub_time if we actually published our message. Otherwise /* Only update pub_time if we actually published our message. Otherwise
* we'll retry again in 100 milliseconds. */ * 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 * If the master name specified in the message is not known, the message is
* discarded. */ * discarded. */
void sentinelProcessHelloMessage(char *hello, int hello_len) { void sentinelProcessHelloMessage(const char *hello, int hello_len) {
/* Format is composed of 8 tokens: /* Format is composed of 8 tokens:
* 0=ip,1=port,2=runid,3=current_epoch,4=master_name, * 0=ip,1=port,2=runid,3=current_epoch,4=master_name,
* 5=master_ip,6=master_port,7=master_config_epoch. */ * 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 /* This is our Pub/Sub callback for the Hello channel. It's useful in order
* to discover other sentinels attached at the same master. */ * to discover other sentinels attached at the same master. */
void sentinelReceiveHelloMessages(redisAsyncContext *c, void *reply, void *privdata) { void sentinelReceiveHelloMessages(redisAsyncContext *c, void *reply, void *privdata) {
sentinelRedisInstance *ri = privdata; sentinelRedisInstance *ri = (sentinelRedisInstance*)privdata;
redisReply *r; redisReply *r;
UNUSED(c); UNUSED(c);
if (!reply || !ri) return; if (!reply || !ri) return;
r = reply; r = (redisReply*)reply;
/* Update the last activity in the pubsub channel. Note that since we /* Update the last activity in the pubsub channel. Note that since we
* receive our messages as well this timestamp can be used to detect * receive our messages as well this timestamp can be used to detect
@ -2613,7 +2613,7 @@ void sentinelForceHelloUpdateDictOfRedisInstances(dict *instances) {
di = dictGetSafeIterator(instances); di = dictGetSafeIterator(instances);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
if (ri->last_pub_time >= (SENTINEL_PUBLISH_PERIOD+1)) if (ri->last_pub_time >= (SENTINEL_PUBLISH_PERIOD+1))
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); di = dictGetIterator(instances);
addReplyArrayLen(c,dictSize(instances)); addReplyArrayLen(c,dictSize(instances));
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
addReplySentinelRedisInstance(c,ri); addReplySentinelRedisInstance(c,ri);
} }
@ -2955,7 +2955,7 @@ sentinelRedisInstance *sentinelGetMasterByNameOrReplyError(client *c,
{ {
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
ri = dictFetchValue(sentinel.masters,ptrFromObj(name)); ri = (sentinelRedisInstance*)dictFetchValue(sentinel.masters,ptrFromObj(name));
if (!ri) { if (!ri) {
addReplyError(c,"No such master with that name"); addReplyError(c,"No such master with that name");
return NULL; return NULL;
@ -2975,7 +2975,7 @@ int sentinelIsQuorumReachable(sentinelRedisInstance *master, int *usableptr) {
di = dictGetIterator(master->sentinels); di = dictGetIterator(master->sentinels);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
if (ri->flags & (SRI_S_DOWN|SRI_O_DOWN)) continue; if (ri->flags & (SRI_S_DOWN|SRI_O_DOWN)) continue;
usable++; usable++;
@ -2989,11 +2989,11 @@ int sentinelIsQuorumReachable(sentinelRedisInstance *master, int *usableptr) {
} }
void sentinelCommand(client *c) { void sentinelCommand(client *c) {
if (!strcasecmp(ptrFromObj(c->argv[1]),"masters")) { if (!strcasecmp(szFromObj(c->argv[1]),"masters")) {
/* SENTINEL MASTERS */ /* SENTINEL MASTERS */
if (c->argc != 2) goto numargserr; if (c->argc != 2) goto numargserr;
addReplyDictOfRedisInstances(c,sentinel.masters); addReplyDictOfRedisInstances(c,sentinel.masters);
} else if (!strcasecmp(ptrFromObj(c->argv[1]),"master")) { } else if (!strcasecmp(szFromObj(c->argv[1]),"master")) {
/* SENTINEL MASTER <name> */ /* SENTINEL MASTER <name> */
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
@ -3001,8 +3001,8 @@ void sentinelCommand(client *c) {
if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2]))
== NULL) return; == NULL) return;
addReplySentinelRedisInstance(c,ri); addReplySentinelRedisInstance(c,ri);
} else if (!strcasecmp(ptrFromObj(c->argv[1]),"slaves") || } else if (!strcasecmp(szFromObj(c->argv[1]),"slaves") ||
!strcasecmp(ptrFromObj(c->argv[1]),"replicas")) !strcasecmp(szFromObj(c->argv[1]),"replicas"))
{ {
/* SENTINEL REPLICAS <master-name> */ /* SENTINEL REPLICAS <master-name> */
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
@ -3011,7 +3011,7 @@ void sentinelCommand(client *c) {
if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) == NULL) if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) == NULL)
return; return;
addReplyDictOfRedisInstances(c,ri->slaves); addReplyDictOfRedisInstances(c,ri->slaves);
} else if (!strcasecmp(ptrFromObj(c->argv[1]),"sentinels")) { } else if (!strcasecmp(szFromObj(c->argv[1]),"sentinels")) {
/* SENTINEL SENTINELS <master-name> */ /* SENTINEL SENTINELS <master-name> */
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
@ -3019,7 +3019,7 @@ void sentinelCommand(client *c) {
if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) == NULL) if ((ri = sentinelGetMasterByNameOrReplyError(c,c->argv[2])) == NULL)
return; return;
addReplyDictOfRedisInstances(c,ri->sentinels); 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 <ip> <port> <current-epoch> <runid> /* SENTINEL IS-MASTER-DOWN-BY-ADDR <ip> <port> <current-epoch> <runid>
* *
* Arguments: * Arguments:
@ -3050,7 +3050,7 @@ void sentinelCommand(client *c) {
!= C_OK) != C_OK)
return; return;
ri = getSentinelRedisInstanceByAddrAndRunID(sentinel.masters, 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. /* It exists? Is actually a master? Is subjectively down? It's down.
* Note: if we are in tilt mode we always reply with "0". */ * 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 /* Vote for the master (or fetch the previous vote) if the request
* includes a runid, otherwise the sender is not seeking for a vote. */ * 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, leader = sentinelVoteLeader(ri,(uint64_t)req_epoch,
ptrFromObj(c->argv[5]), szFromObj(c->argv[5]),
&leader_epoch); &leader_epoch);
} }
@ -3073,16 +3073,16 @@ void sentinelCommand(client *c) {
addReplyBulkCString(c, leader ? leader : "*"); addReplyBulkCString(c, leader ? leader : "*");
addReplyLongLong(c, (long long)leader_epoch); addReplyLongLong(c, (long long)leader_epoch);
if (leader) sdsfree(leader); if (leader) sdsfree(leader);
} else if (!strcasecmp(ptrFromObj(c->argv[1]),"reset")) { } else if (!strcasecmp(szFromObj(c->argv[1]),"reset")) {
/* SENTINEL RESET <pattern> */ /* SENTINEL RESET <pattern> */
if (c->argc != 3) goto numargserr; if (c->argc != 3) goto numargserr;
addReplyLongLong(c,sentinelResetMastersByPattern(ptrFromObj(c->argv[2]),SENTINEL_GENERATE_EVENT)); addReplyLongLong(c,sentinelResetMastersByPattern(szFromObj(c->argv[2]),SENTINEL_GENERATE_EVENT));
} else if (!strcasecmp(ptrFromObj(c->argv[1]),"get-master-addr-by-name")) { } else if (!strcasecmp(szFromObj(c->argv[1]),"get-master-addr-by-name")) {
/* SENTINEL GET-MASTER-ADDR-BY-NAME <master-name> */ /* SENTINEL GET-MASTER-ADDR-BY-NAME <master-name> */
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
if (c->argc != 3) goto numargserr; if (c->argc != 3) goto numargserr;
ri = sentinelGetMasterByName(ptrFromObj(c->argv[2])); ri = sentinelGetMasterByName(szFromObj(c->argv[2]));
if (ri == NULL) { if (ri == NULL) {
addReplyNullArray(c); addReplyNullArray(c);
} else { } else {
@ -3092,7 +3092,7 @@ void sentinelCommand(client *c) {
addReplyBulkCString(c,addr->ip); addReplyBulkCString(c,addr->ip);
addReplyBulkLongLong(c,addr->port); addReplyBulkLongLong(c,addr->port);
} }
} else if (!strcasecmp(ptrFromObj(c->argv[1]),"failover")) { } else if (!strcasecmp(szFromObj(c->argv[1]),"failover")) {
/* SENTINEL FAILOVER <master-name> */ /* SENTINEL FAILOVER <master-name> */
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
@ -3112,12 +3112,12 @@ void sentinelCommand(client *c) {
sentinelStartFailover(ri); sentinelStartFailover(ri);
ri->flags |= SRI_FORCE_FAILOVER; ri->flags |= SRI_FORCE_FAILOVER;
addReply(c,shared.ok); 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 */ /* SENTINEL PENDING-SCRIPTS */
if (c->argc != 2) goto numargserr; if (c->argc != 2) goto numargserr;
sentinelPendingScriptsCommand(c); sentinelPendingScriptsCommand(c);
} else if (!strcasecmp(ptrFromObj(c->argv[1]),"monitor")) { } else if (!strcasecmp(szFromObj(c->argv[1]),"monitor")) {
/* SENTINEL MONITOR <name> <ip> <port> <quorum> */ /* SENTINEL MONITOR <name> <ip> <port> <quorum> */
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
long quorum, port; long quorum, port;
@ -3137,14 +3137,14 @@ void sentinelCommand(client *c) {
/* Make sure the IP field is actually a valid IP before passing it /* Make sure the IP field is actually a valid IP before passing it
* to createSentinelRedisInstance(), otherwise we may trigger a * to createSentinelRedisInstance(), otherwise we may trigger a
* DNS lookup at runtime. */ * 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"); addReplyError(c,"Invalid IP address specified");
return; return;
} }
/* Parameters are valid. Try to create the master instance. */ /* Parameters are valid. Try to create the master instance. */
ri = createSentinelRedisInstance(ptrFromObj(c->argv[2]),SRI_MASTER, ri = createSentinelRedisInstance(szFromObj(c->argv[2]),SRI_MASTER,
ptrFromObj(c->argv[3]),port,quorum,NULL); szFromObj(c->argv[3]),port,quorum,NULL);
if (ri == NULL) { if (ri == NULL) {
switch(errno) { switch(errno) {
case EBUSY: case EBUSY:
@ -3162,12 +3162,12 @@ void sentinelCommand(client *c) {
sentinelEvent(LL_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum); sentinelEvent(LL_WARNING,"+monitor",ri,"%@ quorum %d",ri->quorum);
addReply(c,shared.ok); 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; if (c->argc != 2) goto numargserr;
sentinelFlushConfig(); sentinelFlushConfig();
addReply(c,shared.ok); addReply(c,shared.ok);
return; return;
} else if (!strcasecmp(ptrFromObj(c->argv[1]),"remove")) { } else if (!strcasecmp(szFromObj(c->argv[1]),"remove")) {
/* SENTINEL REMOVE <name> */ /* SENTINEL REMOVE <name> */
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
@ -3178,7 +3178,7 @@ void sentinelCommand(client *c) {
dictDelete(sentinel.masters,ptrFromObj(c->argv[2])); dictDelete(sentinel.masters,ptrFromObj(c->argv[2]));
sentinelFlushConfig(); sentinelFlushConfig();
addReply(c,shared.ok); addReply(c,shared.ok);
} else if (!strcasecmp(ptrFromObj(c->argv[1]),"ckquorum")) { } else if (!strcasecmp(szFromObj(c->argv[1]),"ckquorum")) {
/* SENTINEL CKQUORUM <name> */ /* SENTINEL CKQUORUM <name> */
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
int usable; int usable;
@ -3205,10 +3205,10 @@ void sentinelCommand(client *c) {
e = sdscat(e,"\r\n"); e = sdscat(e,"\r\n");
addReplySds(c,e); 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; if (c->argc < 3) goto numargserr;
sentinelSetCommand(c); sentinelSetCommand(c);
} else if (!strcasecmp(ptrFromObj(c->argv[1]),"info-cache")) { } else if (!strcasecmp(szFromObj(c->argv[1]),"info-cache")) {
/* SENTINEL INFO-CACHE <name> */ /* SENTINEL INFO-CACHE <name> */
if (c->argc < 2) goto numargserr; if (c->argc < 2) goto numargserr;
mstime_t now = mstime(); mstime_t now = mstime();
@ -3224,7 +3224,7 @@ void sentinelCommand(client *c) {
for (int i = 2; i < c->argc; i++) { for (int i = 2; i < c->argc; i++) {
sentinelRedisInstance *ri; sentinelRedisInstance *ri;
ri = sentinelGetMasterByName(ptrFromObj(c->argv[i])); ri = sentinelGetMasterByName(szFromObj(c->argv[i]));
if (!ri) continue; /* ignore non-existing names */ if (!ri) continue; /* ignore non-existing names */
dictAdd(masters_local, ri->name, ri); dictAdd(masters_local, ri->name, ri);
} }
@ -3244,7 +3244,7 @@ void sentinelCommand(client *c) {
dictEntry *de; dictEntry *de;
di = dictGetIterator(masters_local); di = dictGetIterator(masters_local);
while ((de = dictNext(di)) != NULL) { while ((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
addReplyBulkCBuffer(c,ri->name,strlen(ri->name)); addReplyBulkCBuffer(c,ri->name,strlen(ri->name));
addReplyArrayLen(c,dictSize(ri->slaves) + 1); /* +1 for self */ addReplyArrayLen(c,dictSize(ri->slaves) + 1); /* +1 for self */
addReplyArrayLen(c,2); addReplyArrayLen(c,2);
@ -3258,7 +3258,7 @@ void sentinelCommand(client *c) {
dictEntry *sde; dictEntry *sde;
sdi = dictGetIterator(ri->slaves); sdi = dictGetIterator(ri->slaves);
while ((sde = dictNext(sdi)) != NULL) { while ((sde = dictNext(sdi)) != NULL) {
sentinelRedisInstance *sri = dictGetVal(sde); sentinelRedisInstance *sri = (sentinelRedisInstance*)dictGetVal(sde);
addReplyArrayLen(c,2); addReplyArrayLen(c,2);
addReplyLongLong(c, now - sri->info_refresh); addReplyLongLong(c, now - sri->info_refresh);
if (sri->info) if (sri->info)
@ -3270,24 +3270,24 @@ void sentinelCommand(client *c) {
} }
dictReleaseIterator(di); dictReleaseIterator(di);
if (masters_local != sentinel.masters) dictRelease(masters_local); 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 <flag> <flag> ... <flag> */ /* SENTINEL SIMULATE-FAILURE <flag> <flag> ... <flag> */
int j; int j;
sentinel.simfailure_flags = SENTINEL_SIMFAILURE_NONE; sentinel.simfailure_flags = SENTINEL_SIMFAILURE_NONE;
for (j = 2; j < c->argc; j++) { 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_flags |=
SENTINEL_SIMFAILURE_CRASH_AFTER_ELECTION; SENTINEL_SIMFAILURE_CRASH_AFTER_ELECTION;
serverLog(LL_WARNING,"Failure simulation: this Sentinel " serverLog(LL_WARNING,"Failure simulation: this Sentinel "
"will crash after being successfully elected as failover " "will crash after being successfully elected as failover "
"leader"); "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_flags |=
SENTINEL_SIMFAILURE_CRASH_AFTER_PROMOTION; SENTINEL_SIMFAILURE_CRASH_AFTER_PROMOTION;
serverLog(LL_WARNING,"Failure simulation: this Sentinel " serverLog(LL_WARNING,"Failure simulation: this Sentinel "
"will crash after promoting the selected replica to master"); "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); addReplyArrayLen(c,2);
addReplyBulkCString(c,"crash-after-election"); addReplyBulkCString(c,"crash-after-election");
addReplyBulkCString(c,"crash-after-promotion"); addReplyBulkCString(c,"crash-after-promotion");
@ -3326,7 +3326,7 @@ void sentinelInfoCommand(client *c) {
} }
int defsections = 0, allsections = 0; 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) { if (section) {
allsections = !strcasecmp(section,"all"); allsections = !strcasecmp(section,"all");
defsections = !strcasecmp(section,"default"); defsections = !strcasecmp(section,"default");
@ -3363,8 +3363,8 @@ void sentinelInfoCommand(client *c) {
di = dictGetIterator(sentinel.masters); di = dictGetIterator(sentinel.masters);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
char *status = "ok"; const char *status = "ok";
if (ri->flags & SRI_O_DOWN) status = "odown"; if (ri->flags & SRI_O_DOWN) status = "odown";
else if (ri->flags & SRI_S_DOWN) status = "sdown"; else if (ri->flags & SRI_S_DOWN) status = "sdown";
@ -3394,7 +3394,7 @@ void sentinelRoleCommand(client *c) {
di = dictGetIterator(sentinel.masters); di = dictGetIterator(sentinel.masters);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
addReplyBulkCString(c,ri->name); addReplyBulkCString(c,ri->name);
} }
@ -3414,7 +3414,7 @@ void sentinelSetCommand(client *c) {
/* Process option - value pairs. */ /* Process option - value pairs. */
for (j = 3; j < c->argc; j++) { for (j = 3; j < c->argc; j++) {
int moreargs = (c->argc-1) - j; int moreargs = (c->argc-1) - j;
option = ptrFromObj(c->argv[j]); option = szFromObj(c->argv[j]);
long long ll; long long ll;
int old_j = j; /* Used to know what to log as an event. */ int old_j = j; /* Used to know what to log as an event. */
@ -3448,7 +3448,7 @@ void sentinelSetCommand(client *c) {
changes++; changes++;
} else if (!strcasecmp(option,"notification-script") && moreargs > 0) { } else if (!strcasecmp(option,"notification-script") && moreargs > 0) {
/* notification-script <path> */ /* notification-script <path> */
char *value = ptrFromObj(c->argv[++j]); char *value = szFromObj(c->argv[++j]);
if (sentinel.deny_scripts_reconfig) { if (sentinel.deny_scripts_reconfig) {
addReplyError(c, addReplyError(c,
"Reconfiguration of scripts path is denied for " "Reconfiguration of scripts path is denied for "
@ -3468,7 +3468,7 @@ void sentinelSetCommand(client *c) {
changes++; changes++;
} else if (!strcasecmp(option,"client-reconfig-script") && moreargs > 0) { } else if (!strcasecmp(option,"client-reconfig-script") && moreargs > 0) {
/* client-reconfig-script <path> */ /* client-reconfig-script <path> */
char *value = ptrFromObj(c->argv[++j]); char *value = szFromObj(c->argv[++j]);
if (sentinel.deny_scripts_reconfig) { if (sentinel.deny_scripts_reconfig) {
addReplyError(c, addReplyError(c,
"Reconfiguration of scripts path is denied for " "Reconfiguration of scripts path is denied for "
@ -3489,7 +3489,7 @@ void sentinelSetCommand(client *c) {
changes++; changes++;
} else if (!strcasecmp(option,"auth-pass") && moreargs > 0) { } else if (!strcasecmp(option,"auth-pass") && moreargs > 0) {
/* auth-pass <password> */ /* auth-pass <password> */
char *value = ptrFromObj(c->argv[++j]); char *value = szFromObj(c->argv[++j]);
sdsfree(ri->auth_pass); sdsfree(ri->auth_pass);
ri->auth_pass = strlen(value) ? sdsnew(value) : NULL; ri->auth_pass = strlen(value) ? sdsnew(value) : NULL;
changes++; changes++;
@ -3504,8 +3504,8 @@ void sentinelSetCommand(client *c) {
changes++; changes++;
} else if (!strcasecmp(option,"rename-command") && moreargs > 1) { } else if (!strcasecmp(option,"rename-command") && moreargs > 1) {
/* rename-command <oldname> <newname> */ /* rename-command <oldname> <newname> */
sds oldname = ptrFromObj(c->argv[++j]); sds oldname = szFromObj(c->argv[++j]);
sds newname = ptrFromObj(c->argv[++j]); sds newname = szFromObj(c->argv[++j]);
if ((sdslen(oldname) == 0) || (sdslen(newname) == 0)) { if ((sdslen(oldname) == 0) || (sdslen(newname) == 0)) {
badarg = sdslen(newname) ? j-1 : j; 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 * 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. */ * for all the three kind of instances: masters, slaves, sentinels. */
void sentinelPublishCommand(client *c) { 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."); addReplyError(c, "Only HELLO messages are accepted by Sentinel instances.");
return; return;
} }
sentinelProcessHelloMessage(ptrFromObj(c->argv[2]),sdslen(ptrFromObj(c->argv[2]))); sentinelProcessHelloMessage(szFromObj(c->argv[2]),sdslen(szFromObj(c->argv[2])));
addReplyLongLong(c,1); addReplyLongLong(c,1);
} }
@ -3659,7 +3659,7 @@ void sentinelCheckObjectivelyDown(sentinelRedisInstance *master) {
/* Count all the other sentinels. */ /* Count all the other sentinels. */
di = dictGetIterator(master->sentinels); di = dictGetIterator(master->sentinels);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
if (ri->flags & SRI_MASTER_DOWN) quorum++; 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 /* Receive the SENTINEL is-master-down-by-addr reply, see the
* sentinelAskMasterStateToOtherSentinels() function for more information. */ * sentinelAskMasterStateToOtherSentinels() function for more information. */
void sentinelReceiveIsMasterDownReply(redisAsyncContext *c, void *reply, void *privdata) { void sentinelReceiveIsMasterDownReply(redisAsyncContext *c, void *reply, void *privdata) {
sentinelRedisInstance *ri = privdata; sentinelRedisInstance *ri = (sentinelRedisInstance*)privdata;
instanceLink *link = c->data; instanceLink *link = (instanceLink*)c->data;
redisReply *r; redisReply *r;
if (!reply || !link) return; if (!reply || !link) return;
link->pending_commands--; link->pending_commands--;
r = reply; r = (redisReply*)reply;
/* Ignore every error or unexpected reply. /* Ignore every error or unexpected reply.
* Note that if the command returns an error for any reason we'll * 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); di = dictGetIterator(master->sentinels);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
mstime_t elapsed = mstime() - ri->last_master_down_reply_time; mstime_t elapsed = mstime() - ri->last_master_down_reply_time;
char port[32]; char port[32];
int retval; int retval;
@ -3860,7 +3860,7 @@ char *sentinelGetLeader(sentinelRedisInstance *master, uint64_t epoch) {
/* Count other sentinels votes */ /* Count other sentinels votes */
di = dictGetIterator(master->sentinels); di = dictGetIterator(master->sentinels);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
if (ri->leader != NULL && ri->leader_epoch == sentinel.current_epoch) if (ri->leader != NULL && ri->leader_epoch == sentinel.current_epoch)
sentinelLeaderIncr(counters,ri->leader); sentinelLeaderIncr(counters,ri->leader);
} }
@ -3875,7 +3875,7 @@ char *sentinelGetLeader(sentinelRedisInstance *master, uint64_t epoch) {
if (votes > max_votes) { if (votes > max_votes) {
max_votes = votes; max_votes = votes;
winner = dictGetKey(de); winner = (char*)dictGetKey(de);
} }
} }
dictReleaseIterator(di); 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 * The command returns C_OK if the SLAVEOF command was accepted for
* (later) delivery otherwise C_ERR. The command replies are just * (later) delivery otherwise C_ERR. The command replies are just
* discarded. */ * discarded. */
int sentinelSendSlaveOf(sentinelRedisInstance *ri, char *host, int port) { int sentinelSendSlaveOf(sentinelRedisInstance *ri, const char *host, int port) {
char portstr[32]; char portstr[32];
int retval; int retval;
@ -4096,7 +4096,7 @@ int compareSlavesForPromotion(const void *a, const void *b) {
} }
sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master) { sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master) {
sentinelRedisInstance **instance = sentinelRedisInstance **instance = (sentinelRedisInstance**)
zmalloc(sizeof(instance[0])*dictSize(master->slaves), MALLOC_LOCAL); zmalloc(sizeof(instance[0])*dictSize(master->slaves), MALLOC_LOCAL);
sentinelRedisInstance *selected = NULL; sentinelRedisInstance *selected = NULL;
int instances = 0; int instances = 0;
@ -4110,7 +4110,7 @@ sentinelRedisInstance *sentinelSelectSlave(sentinelRedisInstance *master) {
di = dictGetIterator(master->slaves); di = dictGetIterator(master->slaves);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *slave = dictGetVal(de); sentinelRedisInstance *slave = (sentinelRedisInstance*)dictGetVal(de);
mstime_t info_validity_time; mstime_t info_validity_time;
if (slave->flags & (SRI_S_DOWN|SRI_O_DOWN)) continue; if (slave->flags & (SRI_S_DOWN|SRI_O_DOWN)) continue;
@ -4245,7 +4245,7 @@ void sentinelFailoverDetectEnd(sentinelRedisInstance *master) {
* configured. */ * configured. */
di = dictGetIterator(master->slaves); di = dictGetIterator(master->slaves);
while((de = dictNext(di)) != NULL) { 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_PROMOTED|SRI_RECONF_DONE)) continue;
if (slave->flags & SRI_S_DOWN) continue; if (slave->flags & SRI_S_DOWN) continue;
@ -4275,7 +4275,7 @@ void sentinelFailoverDetectEnd(sentinelRedisInstance *master) {
di = dictGetIterator(master->slaves); di = dictGetIterator(master->slaves);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *slave = dictGetVal(de); sentinelRedisInstance *slave = (sentinelRedisInstance*)dictGetVal(de);
int retval; int retval;
if (slave->flags & (SRI_RECONF_DONE|SRI_RECONF_SENT)) continue; if (slave->flags & (SRI_RECONF_DONE|SRI_RECONF_SENT)) continue;
@ -4303,7 +4303,7 @@ void sentinelFailoverReconfNextSlave(sentinelRedisInstance *master) {
di = dictGetIterator(master->slaves); di = dictGetIterator(master->slaves);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *slave = dictGetVal(de); sentinelRedisInstance *slave = (sentinelRedisInstance*)dictGetVal(de);
if (slave->flags & (SRI_RECONF_SENT|SRI_RECONF_INPROG)) if (slave->flags & (SRI_RECONF_SENT|SRI_RECONF_INPROG))
in_progress++; in_progress++;
@ -4314,7 +4314,7 @@ void sentinelFailoverReconfNextSlave(sentinelRedisInstance *master) {
while(in_progress < master->parallel_syncs && while(in_progress < master->parallel_syncs &&
(de = dictNext(di)) != NULL) (de = dictNext(di)) != NULL)
{ {
sentinelRedisInstance *slave = dictGetVal(de); sentinelRedisInstance *slave = (sentinelRedisInstance*)dictGetVal(de);
int retval; int retval;
/* Skip the promoted slave, and already configured slaves. */ /* 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. */ /* There are a number of things we need to perform against every master. */
di = dictGetIterator(instances); di = dictGetIterator(instances);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
sentinelRedisInstance *ri = dictGetVal(de); sentinelRedisInstance *ri = (sentinelRedisInstance*)dictGetVal(de);
sentinelHandleRedisInstance(ri); sentinelHandleRedisInstance(ri);
if (ri->flags & SRI_MASTER) { if (ri->flags & SRI_MASTER) {

View File

@ -997,10 +997,6 @@ struct redisCommand redisCommandTable[] = {
"admin no-script ok-loading ok-stale", "admin no-script ok-loading ok-stale",
0,NULL,0,0,0,0,0,0}, 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, {"acl",aclCommand,-2,
"admin no-script ok-loading ok-stale", "admin no-script ok-loading ok-stale",
0,NULL,0,0,0,0,0,0}, 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, * keys and redis objects as values (objects can hold SDS strings,
* lists, sets). */ * lists, sets). */
extern "C" void dictVanillaFree(void *privdata, void *val) void dictVanillaFree(void *privdata, void *val)
{ {
DICT_NOTUSED(privdata); DICT_NOTUSED(privdata);
zfree(val); zfree(val);
} }
extern "C" void dictListDestructor(void *privdata, void *val) void dictListDestructor(void *privdata, void *val)
{ {
DICT_NOTUSED(privdata); DICT_NOTUSED(privdata);
listRelease((list*)val); 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 /* A case insensitive version used for the command lookup table and other
* places where case insensitive non binary-safe comparison is needed. */ * 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) const void *key2)
{ {
DICT_NOTUSED(privdata); DICT_NOTUSED(privdata);
@ -1205,7 +1201,7 @@ uint64_t dictSdsHash(const void *key) {
return dictGenHashFunction((unsigned char*)key, sdslen((char*)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)); return dictGenCaseHashFunction((unsigned char*)key, sdslen((char*)key));
} }
@ -2155,7 +2151,7 @@ void afterSleep(struct aeEventLoop *eventLoop) {
/* =========================== Server initialization ======================== */ /* =========================== Server initialization ======================== */
extern "C" void createSharedObjects(void) { void createSharedObjects(void) {
int j; int j;
shared.crlf = createObject(OBJ_STRING,sdsnew("\r\n")); shared.crlf = createObject(OBJ_STRING,sdsnew("\r\n"));
@ -2299,7 +2295,6 @@ void initServerConfig(void) {
server.unixsocketperm = CONFIG_DEFAULT_UNIX_SOCKET_PERM; server.unixsocketperm = CONFIG_DEFAULT_UNIX_SOCKET_PERM;
server.sofd = -1; server.sofd = -1;
server.protected_mode = CONFIG_DEFAULT_PROTECTED_MODE; server.protected_mode = CONFIG_DEFAULT_PROTECTED_MODE;
server.gopher_enabled = CONFIG_DEFAULT_GOPHER_ENABLED;
server.dbnum = CONFIG_DEFAULT_DBNUM; server.dbnum = CONFIG_DEFAULT_DBNUM;
server.verbosity = CONFIG_DEFAULT_VERBOSITY; server.verbosity = CONFIG_DEFAULT_VERBOSITY;
server.maxidletime = CONFIG_DEFAULT_CLIENT_TIMEOUT; server.maxidletime = CONFIG_DEFAULT_CLIENT_TIMEOUT;
@ -4761,7 +4756,7 @@ void redisOutOfMemoryHandler(size_t allocation_size) {
serverPanic("Redis aborting for OUT OF MEMORY"); serverPanic("Redis aborting for OUT OF MEMORY");
} }
void redisSetProcTitle(char *title) { void redisSetProcTitle(const char *title) {
#ifdef USE_SETPROCTITLE #ifdef USE_SETPROCTITLE
const char *server_mode = ""; const char *server_mode = "";
if (server.cluster_enabled) server_mode = " [cluster]"; 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 * the program main. However the program is part of the Redis executable
* so that we can easily execute an RDB check on loading errors. */ * so that we can easily execute an RDB check on loading errors. */
if (strstr(argv[0],"keydb-check-rdb") != NULL) 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) else if (strstr(argv[0],"keydb-check-aof") != NULL)
redis_check_aof_main(argc,argv); redis_check_aof_main(argc,argv);

View File

@ -136,7 +136,6 @@ extern "C" {
#define CONFIG_DEFAULT_UNIX_SOCKET_PERM 0 #define CONFIG_DEFAULT_UNIX_SOCKET_PERM 0
#define CONFIG_DEFAULT_TCP_KEEPALIVE 300 #define CONFIG_DEFAULT_TCP_KEEPALIVE 300
#define CONFIG_DEFAULT_PROTECTED_MODE 1 #define CONFIG_DEFAULT_PROTECTED_MODE 1
#define CONFIG_DEFAULT_GOPHER_ENABLED 0
#define CONFIG_DEFAULT_LOGFILE "" #define CONFIG_DEFAULT_LOGFILE ""
#define CONFIG_DEFAULT_SYSLOG_ENABLED 0 #define CONFIG_DEFAULT_SYSLOG_ENABLED 0
#define CONFIG_DEFAULT_STOP_WRITES_ON_BGSAVE_ERROR 1 #define CONFIG_DEFAULT_STOP_WRITES_ON_BGSAVE_ERROR 1
@ -1171,8 +1170,6 @@ struct redisServer {
dict *migrate_cached_sockets;/* MIGRATE cached sockets */ dict *migrate_cached_sockets;/* MIGRATE cached sockets */
uint64_t next_client_id; /* Next client unique ID. Incremental. */ uint64_t next_client_id; /* Next client unique ID. Incremental. */
int protected_mode; /* Don't accept external connections. */ 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 */ /* RDB / AOF loading information */
int loading; /* We are loading data from disk if true */ int loading; /* We are loading data from disk if true */
off_t loading_total_bytes; 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); uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l);
void exitFromChild(int retcode); void exitFromChild(int retcode);
size_t redisPopcount(void *s, long count); size_t redisPopcount(void *s, long count);
void redisSetProcTitle(char *title); void redisSetProcTitle(const char *title);
/* networking.c -- Networking and Client related operations */ /* networking.c -- Networking and Client related operations */
client *createClient(int fd, int iel); 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 setDeferredPushLen(client *c, void *node, long length);
void processInputBuffer(client *c, int callFlags); void processInputBuffer(client *c, int callFlags);
void processInputBufferAndReplicate(client *c); void processInputBufferAndReplicate(client *c);
void processGopherRequest(client *c);
void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask); void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask);
void acceptTcpHandler(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); 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 getLongLongFromObject(robj *o, long long *target);
int getLongDoubleFromObject(robj *o, long double *target); int getLongDoubleFromObject(robj *o, long double *target);
int getLongDoubleFromObjectOrReply(client *c, robj *o, long double *target, const char *msg); 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 compareStringObjects(robj *a, robj *b);
int collateStringObjects(robj *a, robj *b); int collateStringObjects(robj *a, robj *b);
int equalStringObjects(robj *a, robj *b); int equalStringObjects(robj *a, robj *b);
@ -1827,7 +1823,7 @@ void changeReplicationId(void);
void clearReplicationId2(void); void clearReplicationId2(void);
void chopReplicationBacklog(void); void chopReplicationBacklog(void);
void replicationCacheMasterUsingMyself(struct redisMaster *mi); void replicationCacheMasterUsingMyself(struct redisMaster *mi);
void feedReplicationBacklog(void *ptr, size_t len); void feedReplicationBacklog(const void *ptr, size_t len);
/* Generic persistence functions */ /* Generic persistence functions */
void startLoading(FILE *fp); void startLoading(FILE *fp);
@ -1881,7 +1877,7 @@ int ACLSetUser(user *u, const char *op, ssize_t oplen);
sds ACLDefaultUserFirstPassword(void); sds ACLDefaultUserFirstPassword(void);
uint64_t ACLGetCommandCategoryFlagByName(const char *name); uint64_t ACLGetCommandCategoryFlagByName(const char *name);
int ACLAppendUserForLoading(sds *argv, int argc, int *argc_err); int ACLAppendUserForLoading(sds *argv, int argc, int *argc_err);
char *ACLSetUserStringError(void); const char *ACLSetUserStringError(void);
int ACLLoadConfiguredUsers(void); int ACLLoadConfiguredUsers(void);
sds ACLDescribeUser(user *u); sds ACLDescribeUser(user *u);
void ACLLoadUsersAtStartup(void); void ACLLoadUsersAtStartup(void);
@ -2130,12 +2126,12 @@ int clusterSendModuleMessageToTarget(const char *target, uint64_t module_id, uin
void initSentinelConfig(void); void initSentinelConfig(void);
void initSentinel(void); void initSentinel(void);
void sentinelTimer(void); void sentinelTimer(void);
char *sentinelHandleConfiguration(char **argv, int argc); const char *sentinelHandleConfiguration(char **argv, int argc);
void sentinelIsRunning(void); void sentinelIsRunning(void);
/* keydb-check-rdb & aof */ /* keydb-check-rdb & aof */
int redis_check_rdb(char *rdbfilename, FILE *fp); int redis_check_rdb(const char *rdbfilename, FILE *fp);
int redis_check_rdb_main(int argc, char **argv, FILE *fp); int redis_check_rdb_main(int argc, const char **argv, FILE *fp);
int redis_check_aof_main(int argc, char **argv); int redis_check_aof_main(int argc, char **argv);
/* Scripting */ /* Scripting */
@ -2376,7 +2372,6 @@ void xclaimCommand(client *c);
void xinfoCommand(client *c); void xinfoCommand(client *c);
void xdelCommand(client *c); void xdelCommand(client *c);
void xtrimCommand(client *c); void xtrimCommand(client *c);
void lolwutCommand(client *c);
void aclCommand(client *c); void aclCommand(client *c);
void replicaReplayCommand(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); void serverLogHexDump(int level, const char *descr, void *value, size_t len);
int memtest_preserving_test(unsigned long *m, size_t bytes, int passes); int memtest_preserving_test(unsigned long *m, size_t bytes, int passes);
void mixDigest(unsigned char *digest, void *ptr, size_t len); 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 populateCommandTableParseFlags(struct redisCommand *c, const char *strflags);
int moduleGILAcquiredByModule(void); int moduleGILAcquiredByModule(void);

View File

@ -46,12 +46,12 @@
* Incrementing the ref count of all the objects retained is up to * Incrementing the ref count of all the objects retained is up to
* this function. */ * this function. */
slowlogEntry *slowlogCreateEntry(client *c, robj **argv, int argc, long long duration) { 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; int j, slargc = argc;
if (slargc > SLOWLOG_ENTRY_MAX_ARGC) slargc = SLOWLOG_ENTRY_MAX_ARGC; if (slargc > SLOWLOG_ENTRY_MAX_ARGC) slargc = SLOWLOG_ENTRY_MAX_ARGC;
se->argc = slargc; 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++) { for (j = 0; j < slargc; j++) {
/* Logging too many arguments is a useless memory waste, so we stop /* Logging too many arguments is a useless memory waste, so we stop
* at SLOWLOG_ENTRY_MAX_ARGC, but use the last argument to specify * 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... */ /* Trim too long strings as well... */
if (argv[j]->type == OBJ_STRING && if (argv[j]->type == OBJ_STRING &&
sdsEncodedObject(argv[j]) && 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); sds s = sdsnewlen(ptrFromObj(argv[j]), SLOWLOG_ENTRY_MAX_STRING);
s = sdscatprintf(s,"... (%lu more bytes)", s = sdscatprintf(s,"... (%lu more bytes)",
(unsigned long) (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); se->argv[j] = createObject(OBJ_STRING,s);
} else if (argv[j]->refcount == OBJ_SHARED_REFCOUNT) { } else if (argv[j]->refcount == OBJ_SHARED_REFCOUNT) {
se->argv[j] = argv[j]; se->argv[j] = argv[j];
@ -89,7 +89,7 @@ slowlogEntry *slowlogCreateEntry(client *c, robj **argv, int argc, long long dur
se->duration = duration; se->duration = duration;
se->id = server.slowlog_entry_id++; se->id = server.slowlog_entry_id++;
se->peerid = sdsnew(getClientPeerId(c)); 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; 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. */ * This function will take care to release all the retained object. */
void slowlogFreeEntry(void *septr) { void slowlogFreeEntry(void *septr) {
slowlogEntry *se = septr; slowlogEntry *se = (slowlogEntry*)septr;
int j; int j;
for (j = 0; j < se->argc; 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 /* The SLOWLOG command. Implements all the subcommands needed to handle the
* Redis slow log. */ * Redis slow log. */
void slowlogCommand(client *c) { 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[] = { const char *help[] = {
"GET [count] -- Return top entries from the slowlog (default: 10)." "GET [count] -- Return top entries from the slowlog (default: 10)."
" Entries are made of:", " Entries are made of:",
@ -150,13 +150,13 @@ void slowlogCommand(client *c) {
NULL NULL
}; };
addReplyHelp(c, help); 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(); slowlogReset();
addReply(c,shared.ok); 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)); addReplyLongLong(c,listLength(server.slowlog));
} else if ((c->argc == 2 || c->argc == 3) && } 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; long count = 10, sent = 0;
listIter li; listIter li;
@ -173,7 +173,7 @@ NULL
while(count-- && (ln = listNext(&li))) { while(count-- && (ln = listNext(&li))) {
int j; int j;
se = ln->value; se = (slowlogEntry*)ln->value;
addReplyArrayLen(c,6); addReplyArrayLen(c,6);
addReplyLongLong(c,se->id); addReplyLongLong(c,se->id);
addReplyLongLong(c,se->time); addReplyLongLong(c,se->time);

View File

@ -55,7 +55,7 @@ static int label_margin_top = 1;
/* Create a new sequence. */ /* Create a new sequence. */
struct sequence *createSparklineSequence(void) { 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->length = 0;
seq->samples = NULL; seq->samples = NULL;
return seq; return seq;
@ -70,7 +70,7 @@ void sparklineSequenceAddSample(struct sequence *seq, double value, char *label)
if (value < seq->min) seq->min = value; if (value < seq->min) seq->min = value;
else if (value > seq->max) seq->max = 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].value = value;
seq->samples[seq->length].label = label; seq->samples[seq->length].label = label;
seq->length++; seq->length++;
@ -99,7 +99,7 @@ sds sparklineRenderRange(sds output, struct sequence *seq, int rows, int offset,
double relmax = seq->max - seq->min; double relmax = seq->max - seq->min;
int steps = charset_len*rows; int steps = charset_len*rows;
int row = 0; int row = 0;
char *chars = zmalloc(len, MALLOC_LOCAL); char *chars = (char*)zmalloc(len, MALLOC_LOCAL);
int loop = 1; int loop = 1;
int opt_fill = flags & SPARKLINE_FILL; int opt_fill = flags & SPARKLINE_FILL;
int opt_log = flags & SPARKLINE_LOG_SCALE; int opt_log = flags & SPARKLINE_LOG_SCALE;

View File

@ -47,10 +47,18 @@ struct sequence {
#define SPARKLINE_FILL 1 /* Fill the area under the curve. */ #define SPARKLINE_FILL 1 /* Fill the area under the curve. */
#define SPARKLINE_LOG_SCALE 2 /* Use logarithmic scale. */ #define SPARKLINE_LOG_SCALE 2 /* Use logarithmic scale. */
#ifdef __cplusplus
extern "C" {
#endif
struct sequence *createSparklineSequence(void); struct sequence *createSparklineSequence(void);
void sparklineSequenceAddSample(struct sequence *seq, double value, char *label); void sparklineSequenceAddSample(struct sequence *seq, double value, char *label);
void freeSparklineSequence(struct sequence *seq); void freeSparklineSequence(struct sequence *seq);
sds sparklineRenderRange(sds output, struct sequence *seq, int rows, int offset, int len, int flags); 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); sds sparklineRender(sds output, struct sequence *seq, int columns, int rows, int flags);
#ifdef __cplusplus
}
#endif
#endif /* __SPARKLINE_H */ #endif /* __SPARKLINE_H */

View File

@ -35,6 +35,10 @@
#ifndef _ZIPMAP_H #ifndef _ZIPMAP_H
#define _ZIPMAP_H #define _ZIPMAP_H
#ifdef __cplusplus
extern "C" {
#endif
unsigned char *zipmapNew(void); 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 *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); 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[]); int zipmapTest(int argc, char *argv[]);
#endif #endif
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -358,7 +358,7 @@ int zmalloc_get_allocator_info(size_t *allocated,
* Example: zmalloc_get_smap_bytes_by_field("Rss:",-1); * Example: zmalloc_get_smap_bytes_by_field("Rss:",-1);
*/ */
#if defined(HAVE_PROC_SMAPS) #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]; char line[1024];
size_t bytes = 0; size_t bytes = 0;
int flen = strlen(field); int flen = strlen(field);
@ -386,7 +386,7 @@ size_t zmalloc_get_smap_bytes_by_field(char *field, long pid) {
return bytes; return bytes;
} }
#else #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) field);
((void) pid); ((void) pid);
return 0; return 0;

View File

@ -96,7 +96,7 @@ void zmalloc_set_oom_handler(void (*oom_handler)(size_t));
size_t zmalloc_get_rss(void); size_t zmalloc_get_rss(void);
int zmalloc_get_allocator_info(size_t *allocated, size_t *active, size_t *resident); 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_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); size_t zmalloc_get_memory_size(void);
void zlibc_free(void *ptr); void zlibc_free(void *ptr);