diff --git a/src/acl.c b/src/acl.c index f8be5b77d..fb204c3e7 100644 --- a/src/acl.c +++ b/src/acl.c @@ -1403,7 +1403,7 @@ void ACLInit(void) { * ENOENT: if the specified user does not exist at all. */ int ACLCheckUserCredentials(robj *username, robj *password) { - user *u = ACLGetUserByName(username->ptr, sdslen(username->ptr)); + user *u = ACLGetUserByName(objectGetVal(username), sdslen(objectGetVal(username))); if (u == NULL) { errno = ENOENT; return C_ERR; @@ -1423,7 +1423,7 @@ int ACLCheckUserCredentials(robj *username, robj *password) { listIter li; listNode *ln; listRewind(u->passwords, &li); - sds hashed = ACLHashPassword(password->ptr, sdslen(password->ptr)); + sds hashed = ACLHashPassword(objectGetVal(password), sdslen(objectGetVal(password))); while ((ln = listNext(&li))) { sds thispass = listNodeValue(ln); if (!time_independent_strcmp(hashed, thispass, HASH_PASSWORD_LEN)) { @@ -1451,7 +1451,7 @@ void addAuthErrReply(client *c, robj *err) { addReplyError(c, "-WRONGPASS invalid username-password pair or user is disabled."); return; } - addReplyError(c, err->ptr); + addReplyError(c, objectGetVal(err)); } /* This is like ACLCheckUserCredentials(), however if the user/pass @@ -1463,18 +1463,18 @@ static int checkPasswordBasedAuth(client *c, robj *username, robj *password) { int result; if (ACLCheckUserCredentials(username, password) == C_OK) { - user *user = ACLGetUserByName(username->ptr, sdslen(username->ptr)); + user *user = ACLGetUserByName(objectGetVal(username), sdslen(objectGetVal(username))); clientSetUser(c, user, 1); moduleNotifyUserChanged(c); result = AUTH_OK; } else { - addACLLogEntry(c, ACL_DENIED_AUTH, (c->flag.multi) ? ACL_LOG_CTX_MULTI : ACL_LOG_CTX_TOPLEVEL, 0, username->ptr, + addACLLogEntry(c, ACL_DENIED_AUTH, (c->flag.multi) ? ACL_LOG_CTX_MULTI : ACL_LOG_CTX_TOPLEVEL, 0, objectGetVal(username), NULL); result = AUTH_ERR; } moduleFireAuthenticationEvent(c->id, - username->ptr, + objectGetVal(username), NULL, result == AUTH_OK); @@ -1691,7 +1691,7 @@ static int ACLSelectorCheckCmd(aclSelector *selector, while (1) { if (selector->allowed_firstargs[id][subid] == NULL) return ACL_DENIED_CMD; int idx = cmd->parent ? 2 : 1; - if (!strcasecmp(argv[idx]->ptr, selector->allowed_firstargs[id][subid])) + if (!strcasecmp(objectGetVal(argv[idx]), selector->allowed_firstargs[id][subid])) break; /* First argument match found. Stop here. */ subid++; } @@ -1710,7 +1710,7 @@ static int ACLSelectorCheckCmd(aclSelector *selector, keyReference *resultidx = result->keys; for (int j = 0; j < result->numkeys; j++) { int idx = resultidx[j].pos; - ret = ACLSelectorCheckKey(selector, argv[idx]->ptr, sdslen(argv[idx]->ptr), resultidx[j].flags, false); + ret = ACLSelectorCheckKey(selector, objectGetVal(argv[idx]), sdslen(objectGetVal(argv[idx])), resultidx[j].flags, false); if (ret != ACL_OK) { if (keyidxptr) *keyidxptr = resultidx[j].pos; return ret; @@ -1731,7 +1731,7 @@ static int ACLSelectorCheckCmd(aclSelector *selector, if (!(channelref[j].flags & channel_flags)) continue; int is_pattern = channelref[j].flags & CMD_CHANNEL_PATTERN; int ret = - ACLCheckChannelAgainstList(selector->channels, argv[idx]->ptr, sdslen(argv[idx]->ptr), is_pattern); + ACLCheckChannelAgainstList(selector->channels, objectGetVal(argv[idx]), sdslen(objectGetVal(argv[idx])), is_pattern); if (ret != ACL_OK) { if (keyidxptr) *keyidxptr = channelref[j].pos; getKeysFreeResult(&channels); @@ -1961,7 +1961,7 @@ static int ACLShouldKillPubsubClient(client *c, list *upcoming) { void *next; while (!kill && hashtableNext(&iter, &next)) { robj *o = next; - int res = ACLCheckChannelAgainstList(upcoming, o->ptr, sdslen(o->ptr), 1); + int res = ACLCheckChannelAgainstList(upcoming, objectGetVal(o), sdslen(objectGetVal(o)), 1); kill = (res == ACL_DENIED_CHANNEL); } hashtableCleanupIterator(&iter); @@ -1974,7 +1974,7 @@ static int ACLShouldKillPubsubClient(client *c, list *upcoming) { void *next; while (!kill && hashtableNext(&iter, &next)) { robj *o = next; - int res = ACLCheckChannelAgainstList(upcoming, o->ptr, sdslen(o->ptr), 0); + int res = ACLCheckChannelAgainstList(upcoming, objectGetVal(o), sdslen(objectGetVal(o)), 0); kill = (res == ACL_DENIED_CHANNEL); } hashtableCleanupIterator(&iter); @@ -1986,7 +1986,7 @@ static int ACLShouldKillPubsubClient(client *c, list *upcoming) { void *next; while (!kill && hashtableNext(&iter, &next)) { robj *o = next; - int res = ACLCheckChannelAgainstList(upcoming, o->ptr, sdslen(o->ptr), 0); + int res = ACLCheckChannelAgainstList(upcoming, objectGetVal(o), sdslen(objectGetVal(o)), 0); kill = (res == ACL_DENIED_CHANNEL); } hashtableCleanupIterator(&iter); @@ -2488,7 +2488,7 @@ static int ACLSaveToFile(const char *filename) { user = sdscatsds(user, u->name); user = sdscatlen(user, " ", 1); robj *descr = ACLDescribeUser(u); - user = sdscatsds(user, descr->ptr); + user = sdscatsds(user, objectGetVal(descr)); decrRefCount(descr); acl = sdscatsds(acl, user); acl = sdscatlen(acl, "\n", 1); @@ -2682,9 +2682,9 @@ void addACLLogEntry(client *c, int reason, int context, int argpos, sds username } else { switch (reason) { case ACL_DENIED_CMD: le->object = sdsdup(c->cmd->fullname); break; - case ACL_DENIED_KEY: le->object = sdsdup(c->argv[argpos]->ptr); break; - case ACL_DENIED_CHANNEL: le->object = sdsdup(c->argv[argpos]->ptr); break; - case ACL_DENIED_AUTH: le->object = sdsdup(c->argv[0]->ptr); break; + case ACL_DENIED_KEY: le->object = sdsdup(objectGetVal(c->argv[argpos])); break; + case ACL_DENIED_CHANNEL: le->object = sdsdup(objectGetVal(c->argv[argpos])); break; + case ACL_DENIED_AUTH: le->object = sdsdup(objectGetVal(c->argv[0])); break; default: le->object = sdsempty(); } } @@ -2857,7 +2857,7 @@ static int aclAddReplySelectorDescription(client *c, aclSelector *s) { * ACL LOG [ | RESET] */ void aclCommand(client *c) { - char *sub = c->argv[1]->ptr; + char *sub = objectGetVal(c->argv[1]); if (!strcasecmp(sub, "setuser") && c->argc >= 3) { /* Initially redact all of the arguments to not leak any information * about the user. */ @@ -2865,7 +2865,7 @@ void aclCommand(client *c) { redactClientCommandArgument(c, j); } - sds username = c->argv[2]->ptr; + sds username = objectGetVal(c->argv[2]); /* Check username validity. */ if (ACLStringHasSpaces(username, sdslen(username))) { addReplyError(c, "Usernames can't contain spaces or null characters"); @@ -2875,7 +2875,7 @@ void aclCommand(client *c) { user *u = ACLGetUserByName(username, sdslen(username)); sds *temp_argv = zmalloc(c->argc * sizeof(sds)); - for (int i = 3; i < c->argc; i++) temp_argv[i - 3] = c->argv[i]->ptr; + for (int i = 3; i < c->argc; i++) temp_argv[i - 3] = objectGetVal(c->argv[i]); sds error = ACLStringSetUser(u, username, temp_argv, c->argc - 3); zfree(temp_argv); @@ -2892,7 +2892,7 @@ void aclCommand(client *c) { int deleted = 0; for (int j = 2; j < c->argc; j++) { - sds username = c->argv[j]->ptr; + sds username = objectGetVal(c->argv[j]); if (!strcmp(username, "default")) { addReplyError(c, "The 'default' user cannot be removed"); return; @@ -2900,7 +2900,7 @@ void aclCommand(client *c) { } for (int j = 2; j < c->argc; j++) { - sds username = c->argv[j]->ptr; + sds username = objectGetVal(c->argv[j]); user *u; if (raxRemove(Users, (unsigned char *)username, sdslen(username), (void **)&u)) { ACLFreeUserAndKillClients(u); @@ -2912,7 +2912,7 @@ void aclCommand(client *c) { /* Redact the username to not leak any information about the user. */ redactClientCommandArgument(c, 2); - user *u = ACLGetUserByName(c->argv[2]->ptr, sdslen(c->argv[2]->ptr)); + user *u = ACLGetUserByName(objectGetVal(c->argv[2]), sdslen(objectGetVal(c->argv[2]))); if (u == NULL) { addReplyNull(c); return; @@ -2973,7 +2973,7 @@ void aclCommand(client *c) { config = sdscatsds(config, u->name); config = sdscatlen(config, " ", 1); robj *descr = ACLDescribeUser(u); - config = sdscatsds(config, descr->ptr); + config = sdscatsds(config, objectGetVal(descr)); decrRefCount(descr); addReplyBulkSds(c, config); } @@ -3012,9 +3012,9 @@ void aclCommand(client *c) { for (j = 0; ACLCommandCategories[j].flag != 0; j++) addReplyBulkCString(c, ACLCommandCategories[j].name); setDeferredArrayLen(c, dl, j); } else if (!strcasecmp(sub, "cat") && c->argc == 3) { - uint64_t cflag = ACLGetCommandCategoryFlagByName(c->argv[2]->ptr); + uint64_t cflag = ACLGetCommandCategoryFlagByName(objectGetVal(c->argv[2])); if (cflag == 0) { - addReplyErrorFormat(c, "Unknown category '%.128s'", (char *)c->argv[2]->ptr); + addReplyErrorFormat(c, "Unknown category '%.128s'", (char *)objectGetVal(c->argv[2])); return; } int arraylen = 0; @@ -3047,7 +3047,7 @@ void aclCommand(client *c) { * the number of entries the user wants to display, or alternatively * the "RESET" command in order to flush the old entries. */ if (c->argc == 3) { - if (!strcasecmp(c->argv[2]->ptr, "reset")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "reset")) { listSetFreeMethod(ACLLog, ACLFreeLogEntry); listEmpty(ACLLog); listSetFreeMethod(ACLLog, NULL); @@ -3115,14 +3115,14 @@ void aclCommand(client *c) { } } else if (!strcasecmp(sub, "dryrun") && c->argc >= 4) { struct serverCommand *cmd; - user *u = ACLGetUserByName(c->argv[2]->ptr, sdslen(c->argv[2]->ptr)); + user *u = ACLGetUserByName(objectGetVal(c->argv[2]), sdslen(objectGetVal(c->argv[2]))); if (u == NULL) { - addReplyErrorFormat(c, "User '%s' not found", (char *)c->argv[2]->ptr); + addReplyErrorFormat(c, "User '%s' not found", (char *)objectGetVal(c->argv[2])); return; } if ((cmd = lookupCommand(c->argv + 3, c->argc - 3)) == NULL) { - addReplyErrorFormat(c, "Command '%s' not found", (char *)c->argv[3]->ptr); + addReplyErrorFormat(c, "Command '%s' not found", (char *)objectGetVal(c->argv[3])); return; } @@ -3134,7 +3134,7 @@ void aclCommand(client *c) { int idx; int result = ACLCheckAllUserCommandPerm(u, cmd, c->argv + 3, c->argc - 3, &idx); if (result != ACL_OK) { - sds err = getAclErrorMessage(result, u, cmd, c->argv[idx + 3]->ptr, 1); + sds err = getAclErrorMessage(result, u, cmd, objectGetVal(c->argv[idx + 3]), 1); addReplyBulkSds(c, err); return; } diff --git a/src/aof.c b/src/aof.c index 38a9f86eb..25c3fcc76 100644 --- a/src/aof.c +++ b/src/aof.c @@ -1280,11 +1280,11 @@ sds catAppendOnlyGenericCommand(sds dst, int argc, robj **argv) { for (j = 0; j < argc; j++) { o = getDecodedObject(argv[j]); buf[0] = '$'; - len = 1 + ll2string(buf + 1, sizeof(buf) - 1, sdslen(o->ptr)); + len = 1 + ll2string(buf + 1, sizeof(buf) - 1, sdslen(objectGetVal(o))); buf[len++] = '\r'; buf[len++] = '\n'; dst = sdscatlen(dst, buf, len); - dst = sdscatlen(dst, o->ptr, sdslen(o->ptr)); + dst = sdscatlen(dst, objectGetVal(o), sdslen(objectGetVal(o))); dst = sdscatlen(dst, "\r\n", 2); decrRefCount(o); } @@ -1778,9 +1778,9 @@ int rioWriteBulkObject(rio *r, robj *obj) { /* Avoid using getDecodedObject to help copy-on-write (we are often * in a child process when this function is called). */ if (obj->encoding == OBJ_ENCODING_INT) { - return rioWriteBulkLongLong(r, (long)obj->ptr); + return rioWriteBulkLongLong(r, (long)objectGetVal(obj)); } else if (sdsEncodedObject(obj)) { - return rioWriteBulkString(r, obj->ptr, sdslen(obj->ptr)); + return rioWriteBulkString(r, objectGetVal(obj), sdslen(objectGetVal(obj))); } else { serverPanic("Unknown string encoding"); } @@ -1860,7 +1860,7 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) { long long count = 0, items = zsetLength(o); if (o->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = o->ptr; + unsigned char *zl = objectGetVal(o); unsigned char *eptr, *sptr; unsigned char *vstr; unsigned int vlen; @@ -1895,7 +1895,7 @@ int rewriteSortedSetObject(rio *r, robj *key, robj *o) { items--; } } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = o->ptr; + zset *zs = objectGetVal(o); hashtableIterator iter; hashtableInitIterator(&iter, zs->ht, 0); void *next; @@ -2067,7 +2067,7 @@ int rioWriteStreamEmptyConsumer(rio *r, /* Emit the commands needed to rebuild a stream object. * The function returns 0 on error, 1 on success. */ int rewriteStreamObject(rio *r, robj *key, robj *o) { - stream *s = o->ptr; + stream *s = objectGetVal(o); streamIterator si; streamIteratorStart(&si, s, NULL, NULL, 0); streamID id; @@ -2188,7 +2188,7 @@ int rewriteStreamObject(rio *r, robj *key, robj *o) { * The function returns 0 on error, 1 on success. */ int rewriteModuleObject(rio *r, robj *key, robj *o, int dbid) { ValkeyModuleIO io; - moduleValue *mv = o->ptr; + moduleValue *mv = objectGetVal(o); moduleType *mt = mv->type; moduleInitIOContext(&io, mt, r, key, dbid); mt->aof_rewrite(&io, key, mv->value); diff --git a/src/bitops.c b/src/bitops.c index 1e8424bdd..e9daf1ce6 100644 --- a/src/bitops.c +++ b/src/bitops.c @@ -574,7 +574,7 @@ void printBits(unsigned char *p, unsigned long count) { int getBitOffsetFromArgument(client *c, robj *o, uint64_t *offset, int hash, int bits) { long long loffset; char *err = "bit offset is not an integer or out of range"; - sds p = o->ptr; + sds p = objectGetVal(o); size_t plen = sdslen(p); int usehash = 0; @@ -607,7 +607,7 @@ int getBitOffsetFromArgument(client *c, robj *o, uint64_t *offset, int hash, int * * On error C_ERR is returned and an error is sent to the client. */ int getBitfieldTypeFromArgument(client *c, robj *o, int *sign, int *bits) { - sds p = o->ptr; + sds p = objectGetVal(o); size_t plen = sdslen(p); char *err = "Invalid bitfield type. Use something like i16 u8. Note that u64 is not supported but i64 is."; long long llbits; @@ -647,9 +647,9 @@ robj *lookupStringForBitCommand(client *c, uint64_t maxbit, int *dirty) { if (dirty) *dirty = 1; } else { o = dbUnshareStringValue(c->db, c->argv[1], o); - size_t oldlen = sdslen(o->ptr); - o->ptr = sdsgrowzero(o->ptr, byte + 1); - if (dirty && oldlen != sdslen(o->ptr)) *dirty = 1; + size_t oldlen = sdslen(objectGetVal(o)); + objectSetVal(o, sdsgrowzero(objectGetVal(o), byte + 1)); + if (dirty && oldlen != sdslen(objectGetVal(o))) *dirty = 1; } return o; } @@ -675,10 +675,10 @@ unsigned char *getObjectReadOnlyString(robj *o, long *len, char *llbuf) { * array if our string was integer encoded. */ if (o && o->encoding == OBJ_ENCODING_INT) { p = (unsigned char *)llbuf; - if (len) *len = ll2string(llbuf, LONG_STR_SIZE, (long)o->ptr); + if (len) *len = ll2string(llbuf, LONG_STR_SIZE, (long)objectGetVal(o)); } else if (o) { - p = (unsigned char *)o->ptr; - if (len) *len = sdslen(o->ptr); + p = (unsigned char *)objectGetVal(o); + if (len) *len = sdslen(objectGetVal(o)); } else { if (len) *len = 0; } @@ -709,7 +709,7 @@ void setbitCommand(client *c) { /* Get current values */ byte = bitoffset >> 3; - byteval = ((uint8_t *)o->ptr)[byte]; + byteval = ((uint8_t *)objectGetVal(o))[byte]; bit = 7 - (bitoffset & 0x7); bitval = byteval & (1 << bit); @@ -720,7 +720,7 @@ void setbitCommand(client *c) { /* Update byte with new bit value. */ byteval &= ~(1 << bit); byteval |= ((on & 0x1) << bit); - ((uint8_t *)o->ptr)[byte] = byteval; + ((uint8_t *)objectGetVal(o))[byte] = byteval; signalModifiedKey(c, c->db, c->argv[1]); notifyKeyspaceEvent(NOTIFY_STRING, "setbit", c->argv[1], c->db->id); server.dirty++; @@ -745,9 +745,9 @@ void getbitCommand(client *c) { byte = bitoffset >> 3; bit = 7 - (bitoffset & 0x7); if (sdsEncodedObject(o)) { - if (byte < sdslen(o->ptr)) bitval = ((uint8_t *)o->ptr)[byte] & (1 << bit); + if (byte < sdslen(objectGetVal(o))) bitval = ((uint8_t *)objectGetVal(o))[byte] & (1 << bit); } else { - if (byte < (size_t)ll2string(llbuf, sizeof(llbuf), (long)o->ptr)) bitval = llbuf[byte] & (1 << bit); + if (byte < (size_t)ll2string(llbuf, sizeof(llbuf), (long)objectGetVal(o))) bitval = llbuf[byte] & (1 << bit); } addReply(c, bitval ? shared.cone : shared.czero); @@ -756,7 +756,7 @@ void getbitCommand(client *c) { /* BITOP op_name target_key src_key1 src_key2 src_key3 ... src_keyN */ VALKEY_NO_SANITIZE("alignment") void bitopCommand(client *c) { - char *opname = c->argv[1]->ptr; + char *opname = objectGetVal(c->argv[1]); robj *o, *targetkey = c->argv[2]; unsigned long op, j, numkeys; robj **objects; /* Array of source objects. */ @@ -813,8 +813,8 @@ void bitopCommand(client *c) { return; } objects[j] = getDecodedObject(o); - src[j] = objects[j]->ptr; - len[j] = sdslen(objects[j]->ptr); + src[j] = objectGetVal(objects[j]); + len[j] = sdslen(objectGetVal(objects[j])); if (len[j] > maxlen) maxlen = len[j]; if (j == 0 || len[j] < minlen) minlen = len[j]; } @@ -954,9 +954,9 @@ void bitcountCommand(client *c) { if (c->argc == 3 || c->argc == 4 || c->argc == 5) { if (getLongLongFromObjectOrReply(c, c->argv[2], &start, NULL) != C_OK) return; if (c->argc == 5) { - if (!strcasecmp(c->argv[4]->ptr, "bit")) + if (!strcasecmp(objectGetVal(c->argv[4]), "bit")) isbit = 1; - else if (!strcasecmp(c->argv[4]->ptr, "byte")) + else if (!strcasecmp(objectGetVal(c->argv[4]), "byte")) isbit = 0; else { addReplyErrorObject(c, shared.syntaxerr); @@ -1059,9 +1059,9 @@ void bitposCommand(client *c) { if (c->argc == 4 || c->argc == 5 || c->argc == 6) { if (getLongLongFromObjectOrReply(c, c->argv[3], &start, NULL) != C_OK) return; if (c->argc == 6) { - if (!strcasecmp(c->argv[5]->ptr, "bit")) + if (!strcasecmp(objectGetVal(c->argv[5]), "bit")) isbit = 1; - else if (!strcasecmp(c->argv[5]->ptr, "byte")) + else if (!strcasecmp(objectGetVal(c->argv[5]), "byte")) isbit = 0; else { addReplyErrorObject(c, shared.syntaxerr); @@ -1215,12 +1215,12 @@ void bitfieldGeneric(client *c, int flags) { uint64_t highest_write_offset = 0; for (j = 2; j < c->argc; j++) { - int remargs = c->argc - j - 1; /* Remaining args other than current. */ - char *subcmd = c->argv[j]->ptr; /* Current command name. */ - int opcode; /* Current operation code. */ - long long i64 = 0; /* Signed SET value. */ - int sign = 0; /* Signed or unsigned type? */ - int bits = 0; /* Bitfield width in bits. */ + int remargs = c->argc - j - 1; /* Remaining args other than current. */ + char *subcmd = objectGetVal(c->argv[j]); /* Current command name. */ + int opcode; /* Current operation code. */ + long long i64 = 0; /* Signed SET value. */ + int sign = 0; /* Signed or unsigned type? */ + int bits = 0; /* Bitfield width in bits. */ if (!strcasecmp(subcmd, "get") && remargs >= 2) opcode = BITFIELDOP_GET; @@ -1229,7 +1229,7 @@ void bitfieldGeneric(client *c, int flags) { else if (!strcasecmp(subcmd, "incrby") && remargs >= 3) opcode = BITFIELDOP_INCRBY; else if (!strcasecmp(subcmd, "overflow") && remargs >= 1) { - char *owtypename = c->argv[j + 1]->ptr; + char *owtypename = objectGetVal(c->argv[j + 1]); j++; if (!strcasecmp(owtypename, "wrap")) owtype = BFOVERFLOW_WRAP; @@ -1326,7 +1326,7 @@ void bitfieldGeneric(client *c, int flags) { int64_t oldval, newval, wrapped, retval; int overflow; - oldval = getSignedBitfield(o->ptr, thisop->offset, thisop->bits); + oldval = getSignedBitfield(objectGetVal(o), thisop->offset, thisop->bits); if (thisop->opcode == BITFIELDOP_INCRBY) { overflow = checkSignedBitfieldOverflow(oldval, thisop->i64, thisop->bits, thisop->owtype, &wrapped); @@ -1343,7 +1343,7 @@ void bitfieldGeneric(client *c, int flags) { * NULL to signal the condition. */ if (!(overflow && thisop->owtype == BFOVERFLOW_FAIL)) { addReplyLongLong(c, retval); - setSignedBitfield(o->ptr, thisop->offset, thisop->bits, newval); + setSignedBitfield(objectGetVal(o), thisop->offset, thisop->bits, newval); if (dirty || (oldval != newval)) changes++; } else { @@ -1355,7 +1355,7 @@ void bitfieldGeneric(client *c, int flags) { uint64_t oldval, newval, retval, wrapped = 0; int overflow; - oldval = getUnsignedBitfield(o->ptr, thisop->offset, thisop->bits); + oldval = getUnsignedBitfield(objectGetVal(o), thisop->offset, thisop->bits); if (thisop->opcode == BITFIELDOP_INCRBY) { newval = oldval + thisop->i64; @@ -1373,7 +1373,7 @@ void bitfieldGeneric(client *c, int flags) { * NULL to signal the condition. */ if (!(overflow && thisop->owtype == BFOVERFLOW_FAIL)) { addReplyLongLong(c, retval); - setUnsignedBitfield(o->ptr, thisop->offset, thisop->bits, newval); + setUnsignedBitfield(objectGetVal(o), thisop->offset, thisop->bits, newval); if (dirty || (oldval != newval)) changes++; } else { diff --git a/src/cluster.c b/src/cluster.c index 47917dac8..e4482238e 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -207,18 +207,18 @@ void restoreCommand(client *c) { /* Parse additional options */ for (j = 4; j < c->argc; j++) { int additional = c->argc - j - 1; - if (!strcasecmp(c->argv[j]->ptr, "replace")) { + if (!strcasecmp(objectGetVal(c->argv[j]), "replace")) { replace = 1; - } else if (!strcasecmp(c->argv[j]->ptr, "absttl")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "absttl")) { absttl = 1; - } else if (!strcasecmp(c->argv[j]->ptr, "idletime") && additional >= 1 && lfu_freq == -1) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "idletime") && additional >= 1 && lfu_freq == -1) { if (getLongLongFromObjectOrReply(c, c->argv[j + 1], &lru_idle, NULL) != C_OK) return; if (lru_idle < 0) { addReplyError(c, "Invalid IDLETIME value, must be >= 0"); return; } j++; /* Consume additional arg. */ - } else if (!strcasecmp(c->argv[j]->ptr, "freq") && additional >= 1 && lru_idle == -1) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "freq") && additional >= 1 && lru_idle == -1) { if (getLongLongFromObjectOrReply(c, c->argv[j + 1], &lfu_freq, NULL) != C_OK) return; if (lfu_freq < 0 || lfu_freq > 255) { addReplyError(c, "Invalid FREQ value, must be >= 0 and <= 255"); @@ -247,12 +247,12 @@ void restoreCommand(client *c) { } /* Verify RDB version and data checksum. */ - if (verifyDumpPayload(c->argv[3]->ptr, sdslen(c->argv[3]->ptr), &rdbver) == C_ERR) { + if (verifyDumpPayload(objectGetVal(c->argv[3]), sdslen(objectGetVal(c->argv[3])), &rdbver) == C_ERR) { addReplyError(c, "DUMP payload version or checksum are wrong"); return; } - rioInitWithBuffer(&payload, c->argv[3]->ptr); + rioInitWithBuffer(&payload, objectGetVal(c->argv[3])); type = rdbLoadObjectType(&payload); if (type == -1) { addReplyError(c, "Bad data format"); @@ -266,7 +266,7 @@ void restoreCommand(client *c) { return; } - obj = rdbLoadObject(type, &payload, key->ptr, c->db->id, NULL); + obj = rdbLoadObject(type, &payload, objectGetVal(key), c->db->id, NULL); if (obj == NULL) { addReplyError(c, "Bad data format"); return; @@ -342,9 +342,9 @@ migrateCachedSocket *migrateGetSocket(client *c, robj *host, robj *port, long ti migrateCachedSocket *cs; /* Check if we have an already cached socket for this ip:port pair. */ - name = sdscatlen(name, host->ptr, sdslen(host->ptr)); + name = sdscatlen(name, objectGetVal(host), sdslen(objectGetVal(host))); name = sdscatlen(name, ":", 1); - name = sdscatlen(name, port->ptr, sdslen(port->ptr)); + name = sdscatlen(name, objectGetVal(port), sdslen(objectGetVal(port))); cs = dictFetchValue(server.migrate_cached_sockets, name); if (cs) { sdsfree(name); @@ -364,7 +364,7 @@ migrateCachedSocket *migrateGetSocket(client *c, robj *host, robj *port, long ti /* Create the connection */ conn = connCreate(connTypeOfCluster()); - if (connBlockingConnect(conn, host->ptr, atoi(port->ptr), timeout) != C_OK) { + if (connBlockingConnect(conn, objectGetVal(host), atoi(objectGetVal(port)), timeout) != C_OK) { addReplyError(c, "-IOERR error or timeout connecting to the client"); connClose(conn); sdsfree(name); @@ -386,9 +386,9 @@ void migrateCloseSocket(robj *host, robj *port) { sds name = sdsempty(); migrateCachedSocket *cs; - name = sdscatlen(name, host->ptr, sdslen(host->ptr)); + name = sdscatlen(name, objectGetVal(host), sdslen(objectGetVal(host))); name = sdscatlen(name, ":", 1); - name = sdscatlen(name, port->ptr, sdslen(port->ptr)); + name = sdscatlen(name, objectGetVal(port), sdslen(objectGetVal(port))); cs = dictFetchValue(server.migrate_cached_sockets, name); if (!cs) { sdsfree(name); @@ -447,29 +447,29 @@ void migrateCommand(client *c) { /* Parse additional options */ for (j = 6; j < c->argc; j++) { int moreargs = (c->argc - 1) - j; - if (!strcasecmp(c->argv[j]->ptr, "copy")) { + if (!strcasecmp(objectGetVal(c->argv[j]), "copy")) { copy = 1; - } else if (!strcasecmp(c->argv[j]->ptr, "replace")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "replace")) { replace = 1; - } else if (!strcasecmp(c->argv[j]->ptr, "auth")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "auth")) { if (!moreargs) { addReplyErrorObject(c, shared.syntaxerr); return; } j++; - password = c->argv[j]->ptr; + password = objectGetVal(c->argv[j]); redactClientCommandArgument(c, j); - } else if (!strcasecmp(c->argv[j]->ptr, "auth2")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "auth2")) { if (moreargs < 2) { addReplyErrorObject(c, shared.syntaxerr); return; } - username = c->argv[++j]->ptr; + username = objectGetVal(c->argv[++j]); redactClientCommandArgument(c, j); - password = c->argv[++j]->ptr; + password = objectGetVal(c->argv[++j]); redactClientCommandArgument(c, j); - } else if (!strcasecmp(c->argv[j]->ptr, "keys")) { - if (sdslen(c->argv[3]->ptr) != 0) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "keys")) { + if (sdslen(objectGetVal(c->argv[3])) != 0) { addReplyError(c, "When using MIGRATE KEYS option, the key argument" " must be set to the empty string"); return; @@ -576,7 +576,7 @@ try_again: else serverAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, "RESTORE", 7)); serverAssertWithInfo(c, NULL, sdsEncodedObject(kv[j])); - serverAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, kv[j]->ptr, sdslen(kv[j]->ptr))); + serverAssertWithInfo(c, NULL, rioWriteBulkString(&cmd, objectGetVal(kv[j]), sdslen(objectGetVal(kv[j])))); serverAssertWithInfo(c, NULL, rioWriteBulkLongLong(&cmd, ttl)); /* Emit the payload argument, that is the serialized object using @@ -875,27 +875,27 @@ void clusterCommand(client *c) { return; } - if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "help")) { + if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "help")) { clusterCommandHelp(c); - } else if (!strcasecmp(c->argv[1]->ptr, "nodes") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "nodes") && c->argc == 2) { /* CLUSTER NODES */ /* Report TLS ports to TLS client, and report non-TLS port to non-TLS client. */ sds nodes = clusterGenNodesDescription(c, 0, shouldReturnTlsInfo()); addReplyVerbatim(c, nodes, sdslen(nodes), "txt"); sdsfree(nodes); - } else if (!strcasecmp(c->argv[1]->ptr, "myid") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "myid") && c->argc == 2) { /* CLUSTER MYID */ clusterCommandMyId(c); - } else if (!strcasecmp(c->argv[1]->ptr, "myshardid") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "myshardid") && c->argc == 2) { /* CLUSTER MYSHARDID */ clusterCommandMyShardId(c); - } else if (!strcasecmp(c->argv[1]->ptr, "slots") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "slots") && c->argc == 2) { /* CLUSTER SLOTS */ clusterCommandSlots(c); - } else if (!strcasecmp(c->argv[1]->ptr, "shards") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "shards") && c->argc == 2) { /* CLUSTER SHARDS */ clusterCommandShards(c); - } else if (!strcasecmp(c->argv[1]->ptr, "info") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "info") && c->argc == 2) { /* CLUSTER INFO */ sds info = genClusterInfoString(sdsempty()); @@ -903,12 +903,12 @@ void clusterCommand(client *c) { /* Produce the reply protocol. */ addReplyVerbatim(c, info, sdslen(info), "txt"); sdsfree(info); - } else if (!strcasecmp(c->argv[1]->ptr, "keyslot") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "keyslot") && c->argc == 3) { /* CLUSTER KEYSLOT */ - sds key = c->argv[2]->ptr; + sds key = objectGetVal(c->argv[2]); addReplyLongLong(c, keyHashSlot(key, sdslen(key))); - } else if (!strcasecmp(c->argv[1]->ptr, "countkeysinslot") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "countkeysinslot") && c->argc == 3) { /* CLUSTER COUNTKEYSINSLOT */ long long slot; @@ -918,7 +918,7 @@ void clusterCommand(client *c) { return; } addReplyLongLong(c, countKeysInSlotForDb(slot, c->db)); - } else if (!strcasecmp(c->argv[1]->ptr, "getkeysinslot") && c->argc == 4) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "getkeysinslot") && c->argc == 4) { /* CLUSTER GETKEYSINSLOT */ long long maxkeys, slot; @@ -942,14 +942,14 @@ void clusterCommand(client *c) { addReplyBulkCBuffer(c, sdskey, sdslen(sdskey)); } kvstoreReleaseHashtableIterator(kvs_di); - } else if ((!strcasecmp(c->argv[1]->ptr, "slaves") || !strcasecmp(c->argv[1]->ptr, "replicas")) && c->argc == 3) { + } else if ((!strcasecmp(objectGetVal(c->argv[1]), "slaves") || !strcasecmp(objectGetVal(c->argv[1]), "replicas")) && c->argc == 3) { /* CLUSTER REPLICAS */ - clusterNode *n = clusterLookupNode(c->argv[2]->ptr, sdslen(c->argv[2]->ptr)); + clusterNode *n = clusterLookupNode(objectGetVal(c->argv[2]), sdslen(objectGetVal(c->argv[2]))); int j; /* Lookup the specified node in our table. */ if (!n) { - addReplyErrorFormat(c, "Unknown node %s", (char *)c->argv[2]->ptr); + addReplyErrorFormat(c, "Unknown node %s", (char *)objectGetVal(c->argv[2])); return; } @@ -983,7 +983,7 @@ int clusterSlotByCommand(struct serverCommand *cmd, robj **argv, int argc, int * int slot = -1; if (numkeys == 0) *read_flags |= READ_FLAGS_NO_KEYS; for (int i = 0; i < numkeys; i++) { - sds key = argv[result.keys[i].pos]->ptr; + sds key = objectGetVal(argv[result.keys[i].pos]); int keyslot = keyHashSlot(key, sdslen(key)); if (slot == -1) { slot = keyslot; @@ -1199,7 +1199,7 @@ clusterNode *getNodeByQuery(client *c, int *error_code) { * Allowing cross-DB COPY is possible, but it would require looking up the second key in the target DB. * The command should only be allowed if the key exists. We may revisit this decision in the future. */ if (mcmd->proc == copyCommand && - margc >= 4 && !strcasecmp(margv[3]->ptr, "db")) { + margc >= 4 && !strcasecmp(objectGetVal(margv[3]), "db")) { long long value; if (getLongLongFromObject(margv[4], &value) != C_OK || value != currentDb->id) { if (error_code) *error_code = CLUSTER_REDIR_UNSTABLE; @@ -1369,7 +1369,7 @@ int clusterRedirectBlockedClientIfNeeded(client *c) { di = dictGetIterator(c->bstate->keys); if ((de = dictNext(di)) != NULL) { robj *key = dictGetKey(de); - int slot = keyHashSlot((char *)key->ptr, sdslen(key->ptr)); + int slot = keyHashSlot((char *)objectGetVal(key), sdslen(objectGetVal(key))); serverAssert(slot == c->slot); clusterNode *node = getNodeBySlot(slot); @@ -1614,9 +1614,9 @@ void clusterCommandFlushslot(client *c) { int lazy = server.lazyfree_lazy_user_flush; if ((slot = getSlotOrReply(c, c->argv[2])) == -1) return; if (c->argc == 4) { - if (!strcasecmp(c->argv[3]->ptr, "async")) { + if (!strcasecmp(objectGetVal(c->argv[3]), "async")) { lazy = 1; - } else if (!strcasecmp(c->argv[3]->ptr, "sync")) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "sync")) { lazy = 0; } else { addReplyErrorObject(c, shared.syntaxerr); diff --git a/src/cluster_legacy.c b/src/cluster_legacy.c index df5eb6767..40b7a7ccd 100644 --- a/src/cluster_legacy.c +++ b/src/cluster_legacy.c @@ -4832,8 +4832,8 @@ clusterMsgSendBlock *clusterCreatePublishMsgBlock(robj *channel, robj *message, channel = getDecodedObject(channel); message = getDecodedObject(message); - channel_len = sdslen(channel->ptr); - message_len = sdslen(message->ptr); + channel_len = sdslen(objectGetVal(channel)); + message_len = sdslen(objectGetVal(message)); size_t msglen; if (is_light) { @@ -4856,8 +4856,8 @@ clusterMsgSendBlock *clusterCreatePublishMsgBlock(robj *channel, robj *message, } hdr_data_msg->channel_len = htonl(channel_len); hdr_data_msg->message_len = htonl(message_len); - memcpy(hdr_data_msg->bulk_data, channel->ptr, sdslen(channel->ptr)); - memcpy(hdr_data_msg->bulk_data + sdslen(channel->ptr), message->ptr, sdslen(message->ptr)); + memcpy(hdr_data_msg->bulk_data, objectGetVal(channel), sdslen(objectGetVal(channel))); + memcpy(hdr_data_msg->bulk_data + sdslen(objectGetVal(channel)), objectGetVal(message), sdslen(objectGetVal(message))); decrRefCount(channel); decrRefCount(message); @@ -7248,7 +7248,7 @@ int clusterNodeIsPrimary(clusterNode *n) { } int handleDebugClusterCommand(client *c) { - if (c->argc != 5 || strcasecmp(c->argv[1]->ptr, "CLUSTERLINK") || strcasecmp(c->argv[2]->ptr, "KILL")) { + if (c->argc != 5 || strcasecmp(objectGetVal(c->argv[1]), "CLUSTERLINK") || strcasecmp(objectGetVal(c->argv[2]), "KILL")) { return 0; } @@ -7258,9 +7258,9 @@ int handleDebugClusterCommand(client *c) { } /* Find the node. */ - clusterNode *n = clusterLookupNode(c->argv[4]->ptr, sdslen(c->argv[4]->ptr)); + clusterNode *n = clusterLookupNode(objectGetVal(c->argv[4]), sdslen(objectGetVal(c->argv[4]))); if (!n) { - addReplyErrorFormat(c, "Unknown node %s", (char *)c->argv[4]->ptr); + addReplyErrorFormat(c, "Unknown node %s", (char *)objectGetVal(c->argv[4])); return 1; } if (n == server.cluster->myself) { @@ -7269,15 +7269,15 @@ int handleDebugClusterCommand(client *c) { } /* Terminate the link based on the direction or all. */ - if (!strcasecmp(c->argv[3]->ptr, "from")) { + if (!strcasecmp(objectGetVal(c->argv[3]), "from")) { if (n->inbound_link) freeClusterLink(n->inbound_link); - } else if (!strcasecmp(c->argv[3]->ptr, "to")) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "to")) { if (n->link) freeClusterLink(n->link); - } else if (!strcasecmp(c->argv[3]->ptr, "all")) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "all")) { if (n->link) freeClusterLink(n->link); if (n->inbound_link) freeClusterLink(n->inbound_link); } else { - addReplyErrorFormat(c, "Unknown direction %s", (char *)c->argv[3]->ptr); + addReplyErrorFormat(c, "Unknown direction %s", (char *)objectGetVal(c->argv[3])); } addReply(c, shared.ok); @@ -7377,15 +7377,15 @@ int clusterParseSetSlotCommand(client *c, int *slot_out, clusterNode **node_out, if ((slot = getSlotOrReply(c, c->argv[2])) == -1) return 0; - if (!strcasecmp(c->argv[3]->ptr, "migrating") && c->argc >= 5) { + if (!strcasecmp(objectGetVal(c->argv[3]), "migrating") && c->argc >= 5) { /* CLUSTER SETSLOT MIGRATING */ if (nodeIsPrimary(myself) && server.cluster->slots[slot] != myself) { addReplyErrorFormat(c, "I'm not the owner of hash slot %u", slot); return 0; } - n = clusterLookupNode(c->argv[4]->ptr, sdslen(c->argv[4]->ptr)); + n = clusterLookupNode(objectGetVal(c->argv[4]), sdslen(objectGetVal(c->argv[4]))); if (n == NULL) { - addReplyErrorFormat(c, "I don't know about node %s", (char *)c->argv[4]->ptr); + addReplyErrorFormat(c, "I don't know about node %s", (char *)objectGetVal(c->argv[4])); return 0; } if (nodeIsReplica(n)) { @@ -7393,15 +7393,15 @@ int clusterParseSetSlotCommand(client *c, int *slot_out, clusterNode **node_out, return 0; } if (c->argc > 5) optarg_pos = 5; - } else if (!strcasecmp(c->argv[3]->ptr, "importing") && c->argc >= 5) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "importing") && c->argc >= 5) { /* CLUSTER SETSLOT IMPORTING */ if (server.cluster->slots[slot] == myself) { addReplyErrorFormat(c, "I'm already the owner of hash slot %u", slot); return 0; } - n = clusterLookupNode(c->argv[4]->ptr, sdslen(c->argv[4]->ptr)); + n = clusterLookupNode(objectGetVal(c->argv[4]), sdslen(objectGetVal(c->argv[4]))); if (n == NULL) { - addReplyErrorFormat(c, "I don't know about node %s", (char *)c->argv[4]->ptr); + addReplyErrorFormat(c, "I don't know about node %s", (char *)objectGetVal(c->argv[4])); return 0; } if (nodeIsReplica(n)) { @@ -7409,14 +7409,14 @@ int clusterParseSetSlotCommand(client *c, int *slot_out, clusterNode **node_out, return 0; } if (c->argc > 5) optarg_pos = 5; - } else if (!strcasecmp(c->argv[3]->ptr, "stable") && c->argc >= 4) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "stable") && c->argc >= 4) { /* CLUSTER SETSLOT STABLE */ if (c->argc > 4) optarg_pos = 4; - } else if (!strcasecmp(c->argv[3]->ptr, "node") && c->argc >= 5) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "node") && c->argc >= 5) { /* CLUSTER SETSLOT NODE */ - n = clusterLookupNode(c->argv[4]->ptr, sdslen(c->argv[4]->ptr)); + n = clusterLookupNode(objectGetVal(c->argv[4]), sdslen(objectGetVal(c->argv[4]))); if (!n) { - addReplyErrorFormat(c, "Unknown node %s", (char *)c->argv[4]->ptr); + addReplyErrorFormat(c, "Unknown node %s", (char *)objectGetVal(c->argv[4])); return 0; } if (nodeIsReplica(n)) { @@ -7442,7 +7442,7 @@ int clusterParseSetSlotCommand(client *c, int *slot_out, clusterNode **node_out, /* Process optional arguments */ for (int i = optarg_pos; i < c->argc; i++) { - if (!strcasecmp(c->argv[i]->ptr, "timeout")) { + if (!strcasecmp(objectGetVal(c->argv[i]), "timeout")) { if (i + 1 >= c->argc) { addReplyError(c, "Missing timeout value"); return 0; @@ -7540,18 +7540,18 @@ void clusterCommandSetSlot(client *c) { /* Slot states have been updated on the compatible replicas (if any). * Now execute the command on the primary. */ - if (!strcasecmp(c->argv[3]->ptr, "migrating")) { + if (!strcasecmp(objectGetVal(c->argv[3]), "migrating")) { serverLog(LL_NOTICE, "Migrating slot %d to node %.40s (%s)", slot, n->name, n->human_nodename); setMigratingSlotDest(slot, n); - } else if (!strcasecmp(c->argv[3]->ptr, "importing")) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "importing")) { serverLog(LL_NOTICE, "Importing slot %d from node %.40s (%s)", slot, n->name, n->human_nodename); setImportingSlotSource(slot, n); - } else if (!strcasecmp(c->argv[3]->ptr, "stable")) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "stable")) { /* CLUSTER SETSLOT STABLE */ serverLog(LL_NOTICE, "Marking slot %d stable", slot); setImportingSlotSource(slot, NULL); setMigratingSlotDest(slot, NULL); - } else if (!strcasecmp(c->argv[3]->ptr, "node")) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "node")) { /* CLUSTER SETSLOT NODE */ serverLog(LL_NOTICE, "Assigning slot %d to node %.40s (%s) in shard %.40s", slot, n->name, n->human_nodename, n->shard_id); @@ -7630,12 +7630,12 @@ void clusterCommandSetSlot(client *c) { } int clusterCommandSpecial(client *c) { - if (!strcasecmp(c->argv[1]->ptr, "meet") && (c->argc == 4 || c->argc == 5)) { + if (!strcasecmp(objectGetVal(c->argv[1]), "meet") && (c->argc == 4 || c->argc == 5)) { /* CLUSTER MEET [cport] */ long long port, cport; if (getLongLongFromObject(c->argv[3], &port) != C_OK) { - addReplyErrorFormat(c, "Invalid base port specified: %s", (char *)c->argv[3]->ptr); + addReplyErrorFormat(c, "Invalid base port specified: %s", (char *)objectGetVal(c->argv[3])); return 1; } if (port <= 0 || port > 65535) { @@ -7645,7 +7645,7 @@ int clusterCommandSpecial(client *c) { if (c->argc == 5) { if (getLongLongFromObject(c->argv[4], &cport) != C_OK) { - addReplyErrorFormat(c, "Invalid bus port specified: %s", (char *)c->argv[4]->ptr); + addReplyErrorFormat(c, "Invalid bus port specified: %s", (char *)objectGetVal(c->argv[4])); return 1; } } else { @@ -7657,17 +7657,17 @@ int clusterCommandSpecial(client *c) { return 1; } - if (clusterStartHandshake(c->argv[2]->ptr, port, cport) == 0 && errno == EINVAL) { - addReplyErrorFormat(c, "Invalid node address specified: %s:%s", (char *)c->argv[2]->ptr, - (char *)c->argv[3]->ptr); + if (clusterStartHandshake(objectGetVal(c->argv[2]), port, cport) == 0 && errno == EINVAL) { + addReplyErrorFormat(c, "Invalid node address specified: %s:%s", (char *)objectGetVal(c->argv[2]), + (char *)objectGetVal(c->argv[3])); } else { sds client = catClientInfoShortString(sdsempty(), c, server.hide_user_data_from_log); - serverLog(LL_NOTICE, "Cluster meet %s:%lld (user request from '%s').", (char *)c->argv[2]->ptr, port, + serverLog(LL_NOTICE, "Cluster meet %s:%lld (user request from '%s').", (char *)objectGetVal(c->argv[2]), port, client); sdsfree(client); addReply(c, shared.ok); } - } else if (!strcasecmp(c->argv[1]->ptr, "flushslots") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "flushslots") && c->argc == 2) { /* CLUSTER FLUSHSLOTS */ if (!dbsHaveNoKeys()) { addReplyError(c, "DB must be empty to perform CLUSTER FLUSHSLOTS."); @@ -7676,12 +7676,12 @@ int clusterCommandSpecial(client *c) { clusterDelNodeSlots(myself); clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); addReply(c, shared.ok); - } else if ((!strcasecmp(c->argv[1]->ptr, "addslots") || !strcasecmp(c->argv[1]->ptr, "delslots")) && c->argc >= 3) { + } else if ((!strcasecmp(objectGetVal(c->argv[1]), "addslots") || !strcasecmp(objectGetVal(c->argv[1]), "delslots")) && c->argc >= 3) { /* CLUSTER ADDSLOTS [slot] ... */ /* CLUSTER DELSLOTS [slot] ... */ int j, slot; unsigned char *slots = zmalloc(CLUSTER_SLOTS); - int del = !strcasecmp(c->argv[1]->ptr, "delslots"); + int del = !strcasecmp(objectGetVal(c->argv[1]), "delslots"); memset(slots, 0, CLUSTER_SLOTS); /* Check that all the arguments are parseable.*/ @@ -7703,7 +7703,7 @@ int clusterCommandSpecial(client *c) { zfree(slots); clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); addReply(c, shared.ok); - } else if ((!strcasecmp(c->argv[1]->ptr, "addslotsrange") || !strcasecmp(c->argv[1]->ptr, "delslotsrange")) && + } else if ((!strcasecmp(objectGetVal(c->argv[1]), "addslotsrange") || !strcasecmp(objectGetVal(c->argv[1]), "delslotsrange")) && c->argc >= 4) { if (c->argc % 2 == 1) { addReplyErrorArity(c); @@ -7713,7 +7713,7 @@ int clusterCommandSpecial(client *c) { /* CLUSTER DELSLOTSRANGE [ ...] */ int j, startslot, endslot; unsigned char *slots = zmalloc(CLUSTER_SLOTS); - int del = !strcasecmp(c->argv[1]->ptr, "delslotsrange"); + int del = !strcasecmp(objectGetVal(c->argv[1]), "delslotsrange"); memset(slots, 0, CLUSTER_SLOTS); /* Check that all the arguments are parseable and that all the @@ -7742,35 +7742,35 @@ int clusterCommandSpecial(client *c) { zfree(slots); clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "setslot") && c->argc >= 4) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "setslot") && c->argc >= 4) { /* SETSLOT 10 MIGRATING */ /* SETSLOT 10 IMPORTING */ /* SETSLOT 10 STABLE */ /* SETSLOT 10 NODE */ clusterCommandSetSlot(c); - } else if (!strcasecmp(c->argv[1]->ptr, "bumpepoch") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "bumpepoch") && c->argc == 2) { /* CLUSTER BUMPEPOCH */ int retval = clusterBumpConfigEpochWithoutConsensus(); sds reply = sdscatfmt(sdsempty(), "+%s %U\r\n", (retval == C_OK) ? "BUMPED" : "STILL", (unsigned long long)myself->configEpoch); addReplySds(c, reply); - } else if (!strcasecmp(c->argv[1]->ptr, "saveconfig") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "saveconfig") && c->argc == 2) { int retval = clusterSaveConfig(1); if (retval == C_OK) addReply(c, shared.ok); else addReplyErrorFormat(c, "error saving the cluster node config: %s", strerror(errno)); - } else if (!strcasecmp(c->argv[1]->ptr, "forget") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "forget") && c->argc == 3) { /* CLUSTER FORGET */ - clusterNode *n = clusterLookupNode(c->argv[2]->ptr, sdslen(c->argv[2]->ptr)); + clusterNode *n = clusterLookupNode(objectGetVal(c->argv[2]), sdslen(objectGetVal(c->argv[2]))); if (!n) { - if (clusterBlacklistExists((char *)c->argv[2]->ptr, sdslen(c->argv[2]->ptr))) + if (clusterBlacklistExists((char *)objectGetVal(c->argv[2]), sdslen(objectGetVal(c->argv[2])))) /* Already forgotten. The deletion may have been gossipped by * another node, so we pretend it succeeded. */ addReply(c, shared.ok); else - addReplyErrorFormat(c, "Unknown node %s", (char *)c->argv[2]->ptr); + addReplyErrorFormat(c, "Unknown node %s", (char *)objectGetVal(c->argv[2])); return 1; } else if (n == myself) { addReplyError(c, "I tried hard but I can't forget myself..."); @@ -7780,17 +7780,17 @@ int clusterCommandSpecial(client *c) { return 1; } sds client = catClientInfoShortString(sdsempty(), c, server.hide_user_data_from_log); - serverLog(LL_NOTICE, "Cluster forget %s (user request from '%s').", (char *)c->argv[2]->ptr, client); + serverLog(LL_NOTICE, "Cluster forget %s (user request from '%s').", (char *)objectGetVal(c->argv[2]), client); sdsfree(client); clusterBlacklistAddNode(n); clusterDelNode(n); clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "replicate") && (c->argc == 3 || c->argc == 4)) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "replicate") && (c->argc == 3 || c->argc == 4)) { /* CLUSTER REPLICATE ( | NO ONE)*/ if (c->argc == 4) { /* CLUSTER REPLICATE NO ONE */ - if (strcasecmp(c->argv[2]->ptr, "NO") != 0 || strcasecmp(c->argv[3]->ptr, "ONE") != 0) { + if (strcasecmp(objectGetVal(c->argv[2]), "NO") != 0 || strcasecmp(objectGetVal(c->argv[3]), "ONE") != 0) { addReplySubcommandSyntaxError(c); return 1; } @@ -7818,9 +7818,9 @@ int clusterCommandSpecial(client *c) { } /* CLUSTER REPLICATE */ /* Lookup the specified node in our table. */ - clusterNode *n = clusterLookupNode(c->argv[2]->ptr, sdslen(c->argv[2]->ptr)); + clusterNode *n = clusterLookupNode(objectGetVal(c->argv[2]), sdslen(objectGetVal(c->argv[2]))); if (!n) { - addReplyErrorFormat(c, "Unknown node %s", (char *)c->argv[2]->ptr); + addReplyErrorFormat(c, "Unknown node %s", (char *)objectGetVal(c->argv[2])); return 1; } @@ -7859,17 +7859,17 @@ int clusterCommandSpecial(client *c) { clusterSetPrimary(n, 1, 1); clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG | CLUSTER_TODO_BROADCAST_ALL); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "count-failure-reports") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "count-failure-reports") && c->argc == 3) { /* CLUSTER COUNT-FAILURE-REPORTS */ - clusterNode *n = clusterLookupNode(c->argv[2]->ptr, sdslen(c->argv[2]->ptr)); + clusterNode *n = clusterLookupNode(objectGetVal(c->argv[2]), sdslen(objectGetVal(c->argv[2]))); if (!n) { - addReplyErrorFormat(c, "Unknown node %s", (char *)c->argv[2]->ptr); + addReplyErrorFormat(c, "Unknown node %s", (char *)objectGetVal(c->argv[2])); return 1; } else { addReplyLongLong(c, clusterNodeFailureReportsCount(n)); } - } else if (!strcasecmp(c->argv[1]->ptr, "failover") && (c->argc >= 2)) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "failover") && (c->argc >= 2)) { /* CLUSTER FAILOVER [FORCE|TAKEOVER] [REPLICAID ] * REPLICAID is currently available only for internal so we won't * put it into the JSON file. */ @@ -7878,12 +7878,12 @@ int clusterCommandSpecial(client *c) { for (int j = 2; j < c->argc; j++) { int moreargs = (c->argc - 1) - j; - if (!strcasecmp(c->argv[j]->ptr, "force")) { + if (!strcasecmp(objectGetVal(c->argv[j]), "force")) { force = 1; - } else if (!strcasecmp(c->argv[j]->ptr, "takeover")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "takeover")) { takeover = 1; force = 1; /* Takeover also implies force. */ - } else if (c == server.primary && !strcasecmp(c->argv[j]->ptr, "replicaid") && moreargs) { + } else if (c == server.primary && !strcasecmp(objectGetVal(c->argv[j]), "replicaid") && moreargs) { /* This option is currently available only for primary. */ j++; replicaid = c->argv[j]; @@ -7894,7 +7894,7 @@ int clusterCommandSpecial(client *c) { } /* Check if it should be executed by myself. */ - if (replicaid != NULL && memcmp(replicaid->ptr, myself->name, CLUSTER_NAMELEN) != 0) { + if (replicaid != NULL && memcmp(objectGetVal(replicaid), myself->name, CLUSTER_NAMELEN) != 0) { /* Ignore this command, including the sanity check and the process. */ addReply(c, shared.ok); return 1; @@ -7942,7 +7942,7 @@ int clusterCommandSpecial(client *c) { } sdsfree(client); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "set-config-epoch") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "set-config-epoch") && c->argc == 3) { /* CLUSTER SET-CONFIG-EPOCH * * The user is allowed to set the config epoch only when a node is @@ -7973,15 +7973,15 @@ int clusterCommandSpecial(client *c) { clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); addReply(c, shared.ok); } - } else if (!strcasecmp(c->argv[1]->ptr, "reset") && (c->argc == 2 || c->argc == 3)) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "reset") && (c->argc == 2 || c->argc == 3)) { /* CLUSTER RESET [SOFT|HARD] */ int hard = 0; /* Parse soft/hard argument. Default is soft. */ if (c->argc == 3) { - if (!strcasecmp(c->argv[2]->ptr, "hard")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "hard")) { hard = 1; - } else if (!strcasecmp(c->argv[2]->ptr, "soft")) { + } else if (!strcasecmp(objectGetVal(c->argv[2]), "soft")) { hard = 0; } else { addReplyErrorObject(c, shared.syntaxerr); @@ -8001,22 +8001,22 @@ int clusterCommandSpecial(client *c) { sdsfree(client); clusterReset(hard); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "links") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "links") && c->argc == 2) { /* CLUSTER LINKS */ addReplyClusterLinksDescription(c); - } else if (!strcasecmp(c->argv[1]->ptr, "flushslot") && (c->argc == 3 || c->argc == 4)) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "flushslot") && (c->argc == 3 || c->argc == 4)) { /* CLUSTER FLUSHSLOT [ASYNC|SYNC] */ clusterCommandFlushslot(c); - } else if (!strcasecmp(c->argv[1]->ptr, "migrateslots") && c->argc > 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "migrateslots") && c->argc > 3) { /* CLUSTER MIGRATESLOTS SLOTSRANGE [ ...] NODE [SLOTSRANGE ... NODE ...] */ clusterCommandMigrateSlots(c); - } else if (!strcasecmp(c->argv[1]->ptr, "getslotmigrations") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "getslotmigrations") && c->argc == 2) { /* CLUSTER GETSLOTMIGRATIONS */ clusterCommandGetSlotMigrations(c); - } else if (!strcasecmp(c->argv[1]->ptr, "cancelslotmigrations") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "cancelslotmigrations") && c->argc == 2) { /* CLUSTER CANCELSLOTMIGRATIONS */ clusterCommandCancelSlotMigrations(c); - } else if (!strcasecmp(c->argv[1]->ptr, "syncslots") && c->argc > 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "syncslots") && c->argc > 2) { /* CLUSTER SYNCSLOTS */ clusterCommandSyncSlots(c); } else { diff --git a/src/cluster_migrateslots.c b/src/cluster_migrateslots.c index ba5fab687..9a2cb6245 100644 --- a/src/cluster_migrateslots.c +++ b/src/cluster_migrateslots.c @@ -402,7 +402,7 @@ int clusterRDBLoadSlotImport(rio *rdb) { slot_range->end_slot = end_slot; listAddNodeTail(slot_ranges, slot_range); } - slotMigrationJob *new_import = createSlotImportJob(NULL, NULL, job_name->ptr, slot_ranges); + slotMigrationJob *new_import = createSlotImportJob(NULL, NULL, objectGetVal(job_name), slot_ranges); listAddNodeTail(server.cluster->slot_migration_jobs, new_import); decrRefCount(job_name); return C_OK; @@ -542,9 +542,9 @@ void clusterCommandSyncSlotsEstablish(client *c) { bool is_tracking_only = c->flag.primary || c->id == CLIENT_ID_AOF; int i = 3; while (i < c->argc) { - if (!strcasecmp(c->argv[i]->ptr, "source")) { + if (!strcasecmp(objectGetVal(c->argv[i]), "source")) { if (source_node || i + 1 >= c->argc || - sdslen(c->argv[i + 1]->ptr) != CLUSTER_NAMELEN) { + sdslen(objectGetVal(c->argv[i + 1])) != CLUSTER_NAMELEN) { addReplyErrorObject(c, shared.syntaxerr); goto cleanup; } @@ -556,7 +556,7 @@ void clusterCommandSyncSlotsEstablish(client *c) { i += 2; continue; } - source_node_name = c->argv[i + 1]->ptr; + source_node_name = objectGetVal(c->argv[i + 1]); source_node = clusterLookupNode(source_node_name, CLUSTER_NAMELEN); i += 2; @@ -570,17 +570,17 @@ void clusterCommandSyncSlotsEstablish(client *c) { } continue; } - if (!strcasecmp(c->argv[i]->ptr, "name")) { + if (!strcasecmp(objectGetVal(c->argv[i]), "name")) { if (name || i + 1 >= c->argc || - sdslen(c->argv[i + 1]->ptr) != CLUSTER_NAMELEN) { + sdslen(objectGetVal(c->argv[i + 1])) != CLUSTER_NAMELEN) { addReplyErrorObject(c, shared.syntaxerr); goto cleanup; } - name = c->argv[i + 1]->ptr; + name = objectGetVal(c->argv[i + 1]); i += 2; continue; } - if (!strcasecmp(c->argv[i]->ptr, "slotsrange")) { + if (!strcasecmp(objectGetVal(c->argv[i]), "slotsrange")) { if (slot_ranges) { addReplyErrorObject(c, shared.syntaxerr); goto cleanup; @@ -722,31 +722,31 @@ void clusterCommandSyncSlotsFinish(client *c) { char *message = NULL; int i = 3; while (i < c->argc) { - if (!strcasecmp(c->argv[i]->ptr, "state")) { + if (!strcasecmp(objectGetVal(c->argv[i]), "state")) { if (state || i + 1 >= c->argc) { addReplyErrorObject(c, shared.syntaxerr); return; } - state = c->argv[i + 1]->ptr; + state = objectGetVal(c->argv[i + 1]); i += 2; continue; } - if (!strcasecmp(c->argv[i]->ptr, "name")) { + if (!strcasecmp(objectGetVal(c->argv[i]), "name")) { if (name || i + 1 >= c->argc || - sdslen(c->argv[i + 1]->ptr) != CLUSTER_NAMELEN) { + sdslen(objectGetVal(c->argv[i + 1])) != CLUSTER_NAMELEN) { addReplyErrorObject(c, shared.syntaxerr); return; } - name = c->argv[i + 1]->ptr; + name = objectGetVal(c->argv[i + 1]); i += 2; continue; } - if (!strcasecmp(c->argv[i]->ptr, "message")) { + if (!strcasecmp(objectGetVal(c->argv[i]), "message")) { if (message || i + 1 >= c->argc) { addReplyErrorObject(c, shared.syntaxerr); return; } - message = c->argv[i + 1]->ptr; + message = objectGetVal(c->argv[i + 1]); i += 2; continue; } @@ -1151,7 +1151,7 @@ void clusterCommandMigrateSlots(client *c) { list *slot_ranges = NULL; while (curr_index < c->argc) { - if (strcasecmp(c->argv[curr_index]->ptr, "slotsrange")) { + if (strcasecmp(objectGetVal(c->argv[curr_index]), "slotsrange")) { addReplyErrorObject(c, shared.syntaxerr); goto cleanup; } @@ -1192,21 +1192,21 @@ void clusterCommandMigrateSlots(client *c) { } if (curr_index + 1 >= c->argc || - strcasecmp(c->argv[curr_index]->ptr, "node")) { + strcasecmp(objectGetVal(c->argv[curr_index]), "node")) { addReplyErrorObject(c, shared.syntaxerr); goto cleanup; } curr_index++; - if (sdslen(c->argv[curr_index]->ptr) != CLUSTER_NAMELEN) { + if (sdslen(objectGetVal(c->argv[curr_index])) != CLUSTER_NAMELEN) { addReplyErrorFormat(c, "Invalid node name: %s", - (sds)c->argv[curr_index]->ptr); + (sds)objectGetVal(c->argv[curr_index])); goto cleanup; } - clusterNode *target_node = clusterLookupNode(c->argv[curr_index]->ptr, + clusterNode *target_node = clusterLookupNode(objectGetVal(c->argv[curr_index]), CLUSTER_NAMELEN); if (!target_node) { addReplyErrorFormat(c, "Unknown node name: %s", - (sds)c->argv[curr_index]->ptr); + (sds)objectGetVal(c->argv[curr_index])); goto cleanup; } if (target_node == server.cluster->myself) { @@ -2561,12 +2561,12 @@ void clusterCommandSyncSlotsCapa(client *c) { * with slot import. */ void clusterCommandSyncSlots(client *c) { /* Commands used by primary and replica */ - if (!strcasecmp(c->argv[2]->ptr, "establish")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "establish")) { /* CLUSTER SYNCSLOTS ESTABLISH */ clusterCommandSyncSlotsEstablish(c); return; } - if (!strcasecmp(c->argv[2]->ptr, "finish")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "finish")) { /* CLUSTER SYNCSLOTS FINISH */ clusterCommandSyncSlotsFinish(c); return; @@ -2574,37 +2574,37 @@ void clusterCommandSyncSlots(client *c) { /* Commands only used by primary (ignored on replica) */ if (c->flag.primary) return; - if (!strcasecmp(c->argv[2]->ptr, "snapshot-eof")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "snapshot-eof")) { /* CLUSTER SYNCSLOTS SNAPSHOT-EOF */ clusterCommandSyncSlotsSnapshotEof(c); return; } - if (!strcasecmp(c->argv[2]->ptr, "request-pause")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "request-pause")) { /* CLUSTER SYNCSLOTS REQUEST-PAUSE */ clusterCommandSyncSlotsRequestPause(c); return; } - if (!strcasecmp(c->argv[2]->ptr, "paused")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "paused")) { /* CLUSTER SYNCSLOTS PAUSED */ clusterCommandSyncSlotsPaused(c); return; } - if (!strcasecmp(c->argv[2]->ptr, "request-failover")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "request-failover")) { /* CLUSTER SYNCSLOTS REQUEST-FAILOVER */ clusterCommandSyncSlotsRequestFailover(c); return; } - if (!strcasecmp(c->argv[2]->ptr, "failover-granted")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "failover-granted")) { /* CLUSTER SYNCSLOTS FAILOVER-GRANTED */ clusterCommandSyncSlotsFailoverGranted(c); return; } - if (!strcasecmp(c->argv[2]->ptr, "ack")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "ack")) { /* CLUSTER SYNCSLOTS ACK */ clusterCommandSyncSlotsAck(c); return; } - if (!strcasecmp(c->argv[2]->ptr, "capa")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "capa")) { /* CLUSTER SYNCSLOTS CAPA [...] */ clusterCommandSyncSlotsCapa(c); return; diff --git a/src/cluster_slot_stats.c b/src/cluster_slot_stats.c index a591c7c27..c87aaa920 100644 --- a/src/cluster_slot_stats.c +++ b/src/cluster_slot_stats.c @@ -259,7 +259,7 @@ void clusterSlotStatsCommand(client *c) { } /* Parse additional arguments. */ - if (c->argc == 5 && !strcasecmp(c->argv[2]->ptr, "slotsrange")) { + if (c->argc == 5 && !strcasecmp(objectGetVal(c->argv[2]), "slotsrange")) { /* CLUSTER SLOT-STATS SLOTSRANGE start-slot end-slot */ int startslot, endslot; if ((startslot = getSlotOrReply(c, c->argv[3])) == -1 || @@ -275,17 +275,17 @@ void clusterSlotStatsCommand(client *c) { int assigned_slots_count = markSlotsAssignedToMyShard(assigned_slots, startslot, endslot); addReplySlotsRange(c, assigned_slots, startslot, endslot, assigned_slots_count); - } else if (c->argc >= 4 && !strcasecmp(c->argv[2]->ptr, "orderby")) { + } else if (c->argc >= 4 && !strcasecmp(objectGetVal(c->argv[2]), "orderby")) { /* CLUSTER SLOT-STATS ORDERBY metric [LIMIT limit] [ASC | DESC] */ int desc = 1; slotStatType order_by = INVALID; - if (!strcasecmp(c->argv[3]->ptr, "key-count")) { + if (!strcasecmp(objectGetVal(c->argv[3]), "key-count")) { order_by = KEY_COUNT; - } else if (!strcasecmp(c->argv[3]->ptr, "cpu-usec") && server.cluster_slot_stats_enabled) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "cpu-usec") && server.cluster_slot_stats_enabled) { order_by = CPU_USEC; - } else if (!strcasecmp(c->argv[3]->ptr, "network-bytes-in") && server.cluster_slot_stats_enabled) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "network-bytes-in") && server.cluster_slot_stats_enabled) { order_by = NETWORK_BYTES_IN; - } else if (!strcasecmp(c->argv[3]->ptr, "network-bytes-out") && server.cluster_slot_stats_enabled) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "network-bytes-out") && server.cluster_slot_stats_enabled) { order_by = NETWORK_BYTES_OUT; } else { addReplyError(c, "Unrecognized sort metric for ORDERBY."); @@ -296,7 +296,7 @@ void clusterSlotStatsCommand(client *c) { long limit = CLUSTER_SLOTS; while (i < c->argc) { int moreargs = c->argc > i + 1; - if (!strcasecmp(c->argv[i]->ptr, "limit") && moreargs) { + if (!strcasecmp(objectGetVal(c->argv[i]), "limit") && moreargs) { if (getRangeLongFromObjectOrReply( c, c->argv[i + 1], 1, CLUSTER_SLOTS, &limit, "Limit has to lie in between 1 and 16384 (maximum number of slots).") != C_OK) { @@ -304,10 +304,10 @@ void clusterSlotStatsCommand(client *c) { } i++; limit_counter++; - } else if (!strcasecmp(c->argv[i]->ptr, "asc")) { + } else if (!strcasecmp(objectGetVal(c->argv[i]), "asc")) { desc = 0; asc_desc_counter++; - } else if (!strcasecmp(c->argv[i]->ptr, "desc")) { + } else if (!strcasecmp(objectGetVal(c->argv[i]), "desc")) { desc = 1; asc_desc_counter++; } else { diff --git a/src/commandlog.c b/src/commandlog.c index 7b357f776..e01b7f92e 100644 --- a/src/commandlog.c +++ b/src/commandlog.c @@ -45,11 +45,11 @@ static commandlogEntry *commandlogCreateEntry(client *c, robj **argv, int argc, } else { /* Trim too long strings as well... */ if (argv[j]->type == OBJ_STRING && sdsEncodedObject(argv[j]) && - sdslen(argv[j]->ptr) > COMMANDLOG_ENTRY_MAX_STRING) { - sds s = sdsnewlen(argv[j]->ptr, COMMANDLOG_ENTRY_MAX_STRING); + sdslen(objectGetVal(argv[j])) > COMMANDLOG_ENTRY_MAX_STRING) { + sds s = sdsnewlen(objectGetVal(argv[j]), COMMANDLOG_ENTRY_MAX_STRING); s = sdscatprintf(s, "... (%lu more bytes)", - (unsigned long)sdslen(argv[j]->ptr) - COMMANDLOG_ENTRY_MAX_STRING); + (unsigned long)sdslen(objectGetVal(argv[j])) - COMMANDLOG_ENTRY_MAX_STRING); ce->argv[j] = createObject(OBJ_STRING, s); } else if (argv[j]->refcount == OBJ_SHARED_REFCOUNT) { ce->argv[j] = argv[j]; @@ -68,7 +68,7 @@ static commandlogEntry *commandlogCreateEntry(client *c, robj **argv, int argc, ce->value = value; ce->id = server.commandlog[type].entry_id++; ce->peerid = sdsnew(getClientPeerId(c)); - ce->cname = c->name ? sdsnew(c->name->ptr) : sdsempty(); + ce->cname = c->name ? sdsnew(objectGetVal(c->name)) : sdsempty(); return ce; } @@ -172,7 +172,7 @@ void commandlogPushCurrentCommand(client *c, struct serverCommand *cmd) { /* The SLOWLOG command. Implements all the subcommands needed to handle the * slow log. */ void slowlogCommand(client *c) { - if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "help")) { + if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "help")) { const char *help[] = { "GET []", " Return top entries from the slowlog (default: 10, -1 mean all).", @@ -186,12 +186,12 @@ void slowlogCommand(client *c) { NULL, }; addReplyHelp(c, help); - } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "reset")) { + } else if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "reset")) { commandlogReset(COMMANDLOG_TYPE_SLOW); addReply(c, shared.ok); - } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "len")) { + } else if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "len")) { addReplyLongLong(c, listLength(server.commandlog[COMMANDLOG_TYPE_SLOW].entries)); - } else if ((c->argc == 2 || c->argc == 3) && !strcasecmp(c->argv[1]->ptr, "get")) { + } else if ((c->argc == 2 || c->argc == 3) && !strcasecmp(objectGetVal(c->argv[1]), "get")) { long count = 10; if (c->argc == 3) { @@ -214,9 +214,9 @@ void slowlogCommand(client *c) { } static int commandlogGetTypeOrReply(client *c, robj *o) { - if (!strcasecmp(o->ptr, "slow")) return COMMANDLOG_TYPE_SLOW; - if (!strcasecmp(o->ptr, "large-request")) return COMMANDLOG_TYPE_LARGE_REQUEST; - if (!strcasecmp(o->ptr, "large-reply")) return COMMANDLOG_TYPE_LARGE_REPLY; + if (!strcasecmp(objectGetVal(o), "slow")) return COMMANDLOG_TYPE_SLOW; + if (!strcasecmp(objectGetVal(o), "large-request")) return COMMANDLOG_TYPE_LARGE_REQUEST; + if (!strcasecmp(objectGetVal(o), "large-reply")) return COMMANDLOG_TYPE_LARGE_REPLY; addReplyError(c, "type should be one of the following: slow, large-request, large-reply"); return -1; } @@ -225,7 +225,7 @@ static int commandlogGetTypeOrReply(client *c, robj *o) { * command log. */ void commandlogCommand(client *c) { int type; - if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "help")) { + if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "help")) { const char *help[] = { "GET ", " Return top entries of the specified from the commandlog (-1 mean all).", @@ -243,14 +243,14 @@ void commandlogCommand(client *c) { NULL, }; addReplyHelp(c, help); - } else if (c->argc == 3 && !strcasecmp(c->argv[1]->ptr, "reset")) { + } else if (c->argc == 3 && !strcasecmp(objectGetVal(c->argv[1]), "reset")) { if ((type = commandlogGetTypeOrReply(c, c->argv[2])) == -1) return; commandlogReset(type); addReply(c, shared.ok); - } else if (c->argc == 3 && !strcasecmp(c->argv[1]->ptr, "len")) { + } else if (c->argc == 3 && !strcasecmp(objectGetVal(c->argv[1]), "len")) { if ((type = commandlogGetTypeOrReply(c, c->argv[2])) == -1) return; addReplyLongLong(c, listLength(server.commandlog[type].entries)); - } else if (c->argc == 4 && !strcasecmp(c->argv[1]->ptr, "get")) { + } else if (c->argc == 4 && !strcasecmp(objectGetVal(c->argv[1]), "get")) { long count; /* Consume count arg. */ diff --git a/src/config.c b/src/config.c index 58b3324fa..480a5651c 100644 --- a/src/config.c +++ b/src/config.c @@ -817,11 +817,11 @@ void configSetCommand(client *c) { /* Find all relevant configs */ for (i = 0; i < config_count; i++) { - standardConfig *config = lookupConfig(c->argv[2 + i * 2]->ptr); + standardConfig *config = lookupConfig(objectGetVal(c->argv[2 + i * 2])); /* Fail if we couldn't find this config */ if (!config) { if (!invalid_args) { - invalid_arg_name = c->argv[2 + i * 2]->ptr; + invalid_arg_name = objectGetVal(c->argv[2 + i * 2]); invalid_args = 1; } continue; @@ -842,7 +842,7 @@ void configSetCommand(client *c) { (config->flags & PROTECTED_CONFIG && !allowProtectedAction(server.enable_protected_configs, c))) { /* Note: we don't abort the loop since we still want to handle redacting sensitive configs (above) */ errstr = (config->flags & IMMUTABLE_CONFIG) ? "can't set immutable config" : "can't set protected config"; - err_arg_name = c->argv[2 + i * 2]->ptr; + err_arg_name = objectGetVal(c->argv[2 + i * 2]); invalid_args = 1; continue; } @@ -859,14 +859,14 @@ void configSetCommand(client *c) { if (set_configs[j] == config) { /* Note: we don't abort the loop since we still want to handle redacting sensitive configs (above) */ errstr = "duplicate parameter"; - err_arg_name = c->argv[2 + i * 2]->ptr; + err_arg_name = objectGetVal(c->argv[2 + i * 2]); invalid_args = 1; break; } } set_configs[i] = config; config_names[i] = config->name; - new_values[i] = c->argv[2 + i * 2 + 1]->ptr; + new_values[i] = objectGetVal(c->argv[2 + i * 2 + 1]); } if (invalid_args) goto err; @@ -968,7 +968,7 @@ void configGetCommand(client *c) { dict *matches = dictCreate(&externalStringType); for (i = 0; i < c->argc - 2; i++) { robj *o = c->argv[2 + i]; - sds name = o->ptr; + sds name = objectGetVal(o); /* If the string doesn't contain glob patterns, just directly * look up the key in the dictionary. */ @@ -1455,7 +1455,7 @@ void rewriteConfigUserOption(struct rewriteConfigState *state) { line = sdscatsds(line, u->name); line = sdscatlen(line, " ", 1); robj *descr = ACLDescribeUser(u); - line = sdscatsds(line, descr->ptr); + line = sdscatsds(line, objectGetVal(descr)); decrRefCount(descr); rewriteConfigRewriteLine(state, "user", line, 1); } diff --git a/src/db.c b/src/db.c index e9ff95192..bc30f53aa 100644 --- a/src/db.c +++ b/src/db.c @@ -78,8 +78,8 @@ static robj *dbFindWithDictIndex(serverDb *db, sds key, int dict_index); * expired on replicas even if the primary is lagging expiring our key via DELs * in the replication link. */ robj *lookupKey(serverDb *db, robj *key, int flags) { - int dict_index = getKVStoreIndexForKey(key->ptr); - robj *val = dbFindWithDictIndex(db, key->ptr, dict_index); + int dict_index = getKVStoreIndexForKey(objectGetVal(key)); + robj *val = dbFindWithDictIndex(db, objectGetVal(key), dict_index); if (val) { /* Forcing deletion of expired keys on a replica makes the replica * inconsistent with the primary. We forbid it on readonly replicas, but @@ -199,21 +199,21 @@ void dbUpdateObjectWithVolatileItemsTracking(serverDb *db, robj *o) { * If the update_if_existing argument is false, the program is aborted * if the key already exists, otherwise, it can fall back to dbOverwrite. */ static void dbAddInternal(serverDb *db, robj *key, robj **valref, int update_if_existing) { - int dict_index = getKVStoreIndexForKey(key->ptr); + int dict_index = getKVStoreIndexForKey(objectGetVal(key)); void **oldref = NULL; if (update_if_existing) { - oldref = kvstoreHashtableFindRef(db->keys, dict_index, key->ptr); + oldref = kvstoreHashtableFindRef(db->keys, dict_index, objectGetVal(key)); if (oldref != NULL) { dbSetValue(db, key, valref, 1, oldref); return; } } else { - debugServerAssertWithInfo(NULL, key, kvstoreHashtableFindRef(db->keys, dict_index, key->ptr) == NULL); + debugServerAssertWithInfo(NULL, key, kvstoreHashtableFindRef(db->keys, dict_index, objectGetVal(key)) == NULL); } /* Not existing. Convert val to valkey object and insert. */ robj *val = *valref; - val = objectSetKeyAndExpire(val, key->ptr, -1); + val = objectSetKeyAndExpire(val, objectGetVal(key), -1); /* Track hash object if it has volatile fields (for active expiry). * For example, this is needed when a hash is moved to a new DB (e.g. MOVE). */ dbTrackKeyWithVolatileItems(db, val); @@ -318,8 +318,8 @@ int dbAddRDBLoad(serverDb *db, sds key, robj **valref) { static void dbSetValue(serverDb *db, robj *key, robj **valref, int overwrite, void **oldref) { robj *val = *valref; if (oldref == NULL) { - int dict_index = getKVStoreIndexForKey(key->ptr); - oldref = kvstoreHashtableFindRef(db->keys, dict_index, key->ptr); + int dict_index = getKVStoreIndexForKey(objectGetVal(key)); + oldref = kvstoreHashtableFindRef(db->keys, dict_index, objectGetVal(key)); } serverAssertWithInfo(NULL, key, oldref != NULL); robj *old = *oldref; @@ -346,13 +346,13 @@ static void dbSetValue(serverDb *db, robj *key, robj **valref, int overwrite, vo * encoding with the content of val. */ int tmp_type = old->type; int tmp_encoding = old->encoding; - void *tmp_ptr = old->ptr; + void *tmp_ptr = objectGetVal(old); old->type = val->type; old->encoding = val->encoding; - old->ptr = val->ptr; + objectSetVal(old, objectGetVal(val)); val->type = tmp_type; val->encoding = tmp_encoding; - val->ptr = tmp_ptr; + objectSetVal(val, tmp_ptr); /* Set new to old to keep the old object. Set old to val to be freed below. */ new = old; old = val; @@ -360,12 +360,12 @@ static void dbSetValue(serverDb *db, robj *key, robj **valref, int overwrite, vo /* Replace the old value at its location in the key space. */ val->lru = old->lru; long long expire = objectGetExpire(old); - new = objectSetKeyAndExpire(val, key->ptr, expire); + new = objectSetKeyAndExpire(val, objectGetVal(key), expire); *oldref = new; /* Replace the old value at its location in the expire space. */ if (expire >= 0) { - int dict_index = getKVStoreIndexForKey(key->ptr); - void **expireref = kvstoreHashtableFindRef(db->expires, dict_index, key->ptr); + int dict_index = getKVStoreIndexForKey(objectGetVal(key)); + void **expireref = kvstoreHashtableFindRef(db->expires, dict_index, objectGetVal(key)); serverAssert(expireref != NULL); *expireref = new; } @@ -462,7 +462,7 @@ robj *dbRandomKey(serverDb *db) { int dbGenericDeleteWithDictIndex(serverDb *db, robj *key, int async, int flags, int dict_index) { hashtablePosition pos; - void **ref = kvstoreHashtableTwoPhasePopFindRef(db->keys, dict_index, key->ptr, &pos); + void **ref = kvstoreHashtableTwoPhasePopFindRef(db->keys, dict_index, objectGetVal(key), &pos); if (ref != NULL) { robj *val = *ref; /* VM_StringDMA may call dbUnshareStringValue which may free val, so we @@ -481,10 +481,10 @@ int dbGenericDeleteWithDictIndex(serverDb *db, robj *key, int async, int flags, * (The expires table has no destructor callback.) */ kvstoreHashtableTwoPhasePopDelete(db->keys, dict_index, &pos); if (objectGetExpire(val) != -1) { - bool deleted = kvstoreHashtableDelete(db->expires, dict_index, key->ptr); + bool deleted = kvstoreHashtableDelete(db->expires, dict_index, objectGetVal(key)); serverAssert(deleted); } else { - debugServerAssert(!kvstoreHashtableDelete(db->expires, dict_index, key->ptr)); + debugServerAssert(!kvstoreHashtableDelete(db->expires, dict_index, objectGetVal(key))); } /* If deleting a hash object, un-track it from the volatile items tracking if it contains volatile items.*/ @@ -506,7 +506,7 @@ int dbGenericDeleteWithDictIndex(serverDb *db, robj *key, int async, int flags, /* Helper for sync and async delete. */ int dbGenericDelete(serverDb *db, robj *key, int async, int flags) { - int dict_index = getKVStoreIndexForKey(key->ptr); + int dict_index = getKVStoreIndexForKey(objectGetVal(key)); return dbGenericDeleteWithDictIndex(db, key, async, flags, dict_index); } @@ -572,7 +572,7 @@ robj *dbUnshareStringValue(serverDb *db, robj *key, robj *o) { serverAssert(o->type == OBJ_STRING); if (o->refcount != 1 || o->encoding != OBJ_ENCODING_RAW) { robj *decoded = getDecodedObject(o); - o = createRawStringObject(decoded->ptr, sdslen(decoded->ptr)); + o = createRawStringObject(objectGetVal(decoded), sdslen(objectGetVal(decoded))); decrRefCount(decoded); dbReplaceValue(db, key, &o); } @@ -781,9 +781,9 @@ void signalFlushedDb(int dbid, int async) { * C_ERR is returned and the function sends an error to the client. */ int getFlushCommandFlags(client *c, int *flags) { /* Parse the optional ASYNC option. */ - if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "sync")) { + if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "sync")) { *flags = EMPTYDB_NO_FLAGS; - } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "async")) { + } else if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "async")) { *flags = EMPTYDB_ASYNC; } else if (c->argc == 1) { *flags = server.lazyfree_lazy_user_flush ? EMPTYDB_ASYNC : EMPTYDB_NO_FLAGS; @@ -917,7 +917,7 @@ void randomkeyCommand(client *c) { } void keysCommand(client *c) { - sds pattern = c->argv[1]->ptr; + sds pattern = objectGetVal(c->argv[1]); int plen = sdslen(pattern), allkeys, pslot = -1; unsigned long numkeys = 0; void *replylen = addReplyDeferredLen(c); @@ -982,7 +982,7 @@ int objectTypeCompare(robj *o, long long target) { return 1; } /* module type compare */ - long long mt = (long long)VALKEYMODULE_TYPE_SIGN(((moduleValue *)o->ptr)->type->id); + long long mt = (long long)VALKEYMODULE_TYPE_SIGN(((moduleValue *)objectGetVal(o))->type->id); if (target != -mt) return 0; else @@ -1118,7 +1118,7 @@ char *getObjectTypeName(robj *o) { serverAssert(o->type >= 0 && o->type < OBJ_TYPE_MAX); if (o->type == OBJ_MODULE) { - moduleValue *mv = o->ptr; + moduleValue *mv = objectGetVal(o); return mv->type->name; } else { return obj_type_name[o->type]; @@ -1155,7 +1155,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { /* Step 1: Parse options. */ while (i < c->argc) { j = c->argc - i; - if (!strcasecmp(c->argv[i]->ptr, "count") && j >= 2) { + if (!strcasecmp(objectGetVal(c->argv[i]), "count") && j >= 2) { if (getLongFromObjectOrReply(c, c->argv[i + 1], &count, NULL) != C_OK) { return; } @@ -1166,8 +1166,8 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { } i += 2; - } else if (!strcasecmp(c->argv[i]->ptr, "match") && j >= 2) { - pat = c->argv[i + 1]->ptr; + } else if (!strcasecmp(objectGetVal(c->argv[i]), "match") && j >= 2) { + pat = objectGetVal(c->argv[i + 1]); patlen = sdslen(pat); /* The pattern always matches if it is exactly "*", so it is @@ -1175,23 +1175,23 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { use_pattern = !(patlen == 1 && pat[0] == '*'); i += 2; - } else if (!strcasecmp(c->argv[i]->ptr, "type") && o == NULL && j >= 2) { + } else if (!strcasecmp(objectGetVal(c->argv[i]), "type") && o == NULL && j >= 2) { /* SCAN for a particular type only applies to the db dict */ - typename = c->argv[i + 1]->ptr; + typename = objectGetVal(c->argv[i + 1]); type = getObjectTypeByName(typename); if (type == LLONG_MAX) { addReplyErrorFormat(c, "unknown type name '%s'", typename); return; } i += 2; - } else if (!strcasecmp(c->argv[i]->ptr, "novalues")) { + } else if (!strcasecmp(objectGetVal(c->argv[i]), "novalues")) { if (!o || o->type != OBJ_HASH) { addReplyError(c, "NOVALUES option can only be used in HSCAN"); return; } only_keys = 1; i++; - } else if (!strcasecmp(c->argv[i]->ptr, "noscores")) { + } else if (!strcasecmp(objectGetVal(c->argv[i]), "noscores")) { if (!o || o->type != OBJ_ZSET) { addReplyError(c, "NOSCORES option can only be used in ZSCAN"); return; @@ -1221,13 +1221,13 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { if (o == NULL) { free_callback = NULL; } else if (o->type == OBJ_SET && o->encoding == OBJ_ENCODING_HASHTABLE) { - ht = o->ptr; + ht = objectGetVal(o); free_callback = NULL; } else if (o->type == OBJ_HASH && o->encoding == OBJ_ENCODING_HASHTABLE) { - ht = o->ptr; + ht = objectGetVal(o); free_callback = NULL; } else if (o->type == OBJ_ZSET && o->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = o->ptr; + zset *zs = objectGetVal(o); ht = zs->ht; /* scanning ZSET allocates temporary strings even though it's a dict */ free_callback = sdsfree; @@ -1299,7 +1299,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { setTypeReleaseIterator(si); cursor = 0; } else if ((o->type == OBJ_HASH || o->type == OBJ_ZSET) && o->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *p = lpFirst(o->ptr); + unsigned char *p = lpFirst(objectGetVal(o)); unsigned char *str; int64_t len; unsigned char intbuf[LP_INTBUF_SIZE]; @@ -1307,10 +1307,10 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { while (p) { str = lpGet(p, &len, intbuf); /* point to the value */ - p = lpNext(o->ptr, p); + p = lpNext(objectGetVal(o), p); if (use_pattern && !stringmatchlen(pat, sdslen(pat), (char *)str, len, 0)) { /* jump to the next key/val pair */ - p = lpNext(o->ptr, p); + p = lpNext(objectGetVal(o), p); continue; } /* add key object */ @@ -1322,7 +1322,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { item = vectorPush(&result); *item = sdsnewlen(str, len); } - p = lpNext(o->ptr, p); + p = lpNext(objectGetVal(o), p); } cursor = 0; } else { @@ -1348,7 +1348,7 @@ void scanGenericCommand(client *c, robj *o, unsigned long long cursor) { /* The SCAN command completely relies on scanGenericCommand. */ void scanCommand(client *c) { unsigned long long cursor; - if (parseScanCursorOrReply(c, c->argv[1]->ptr, &cursor) == C_ERR) return; + if (parseScanCursorOrReply(c, objectGetVal(c->argv[1]), &cursor) == C_ERR) return; scanGenericCommand(c, NULL, cursor); } @@ -1371,19 +1371,19 @@ void shutdownCommand(client *c) { int flags = SHUTDOWN_NOFLAGS; int abort = 0; for (int i = 1; i < c->argc; i++) { - if (!strcasecmp(c->argv[i]->ptr, "nosave")) { + if (!strcasecmp(objectGetVal(c->argv[i]), "nosave")) { flags |= SHUTDOWN_NOSAVE; - } else if (!strcasecmp(c->argv[i]->ptr, "save")) { + } else if (!strcasecmp(objectGetVal(c->argv[i]), "save")) { flags |= SHUTDOWN_SAVE; - } else if (!strcasecmp(c->argv[i]->ptr, "now")) { + } else if (!strcasecmp(objectGetVal(c->argv[i]), "now")) { flags |= SHUTDOWN_NOW; - } else if (!strcasecmp(c->argv[i]->ptr, "force")) { + } else if (!strcasecmp(objectGetVal(c->argv[i]), "force")) { flags |= SHUTDOWN_FORCE; - } else if (!strcasecmp(c->argv[i]->ptr, "abort")) { + } else if (!strcasecmp(objectGetVal(c->argv[i]), "abort")) { abort = 1; - } else if (!strcasecmp(c->argv[i]->ptr, "safe")) { + } else if (!strcasecmp(objectGetVal(c->argv[i]), "safe")) { flags |= SHUTDOWN_SAFE; - } else if (!strcasecmp(c->argv[i]->ptr, "failover")) { + } else if (!strcasecmp(objectGetVal(c->argv[i]), "failover")) { flags |= SHUTDOWN_FAILOVER; } else { addReplyErrorObject(c, shared.syntaxerr); @@ -1442,7 +1442,7 @@ void renameGenericCommand(client *c, int nx) { /* When source and dest key is the same, no operation is performed, * if the key exists, however we still return an error on unexisting key. */ - if (sdscmp(c->argv[1]->ptr, c->argv[2]->ptr) == 0) samekey = 1; + if (sdscmp(objectGetVal(c->argv[1]), objectGetVal(c->argv[2])) == 0) samekey = 1; if ((o = lookupKeyWriteOrReply(c, c->argv[1], shared.nokeyerr)) == NULL) return; @@ -1554,9 +1554,9 @@ void copyCommand(client *c) { dbid = c->db->id; for (j = 3; j < c->argc; j++) { int additional = c->argc - j - 1; - if (!strcasecmp(c->argv[j]->ptr, "replace")) { + if (!strcasecmp(objectGetVal(c->argv[j]), "replace")) { replace = 1; - } else if (!strcasecmp(c->argv[j]->ptr, "db") && additional >= 1) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "db") && additional >= 1) { if (getIntFromObjectOrReply(c, c->argv[j + 1], &dbid, NULL) != C_OK) return; if (selectDb(c, dbid) == C_ERR) { @@ -1577,7 +1577,7 @@ void copyCommand(client *c) { * it is probably an error. */ robj *key = c->argv[1]; robj *newkey = c->argv[2]; - if (src == dst && (sdscmp(key->ptr, newkey->ptr) == 0)) { + if (src == dst && (sdscmp(objectGetVal(key), objectGetVal(newkey)) == 0)) { addReplyErrorObject(c, shared.sameobjecterr); return; } @@ -1641,7 +1641,7 @@ void scanDatabaseForReadyKeys(serverDb *db) { dictIterator *di = dictGetSafeIterator(db->blocking_keys); while ((de = dictNext(di)) != NULL) { robj *key = dictGetKey(de); - robj *value = dbFind(db, key->ptr); + robj *value = dbFind(db, objectGetVal(key)); if (value) { signalKeyAsReady(db, key, value->type); } @@ -1660,14 +1660,14 @@ void scanDatabaseForDeletedKeys(serverDb *emptied, serverDb *replaced_with) { int existed = 0, exists = 0; int original_type = -1, curr_type = -1; - robj *value = dbFind(emptied, key->ptr); + robj *value = dbFind(emptied, objectGetVal(key)); if (value) { original_type = value->type; existed = 1; } if (replaced_with) { - value = dbFind(replaced_with, key->ptr); + value = dbFind(replaced_with, objectGetVal(key)); if (value) { curr_type = value->type; exists = 1; @@ -1819,9 +1819,9 @@ void swapdbCommand(client *c) { *----------------------------------------------------------------------------*/ int removeExpire(serverDb *db, robj *key) { - int dict_index = getKVStoreIndexForKey(key->ptr); + int dict_index = getKVStoreIndexForKey(objectGetVal(key)); void *popped; - if (kvstoreHashtablePop(db->expires, dict_index, key->ptr, &popped)) { + if (kvstoreHashtablePop(db->expires, dict_index, objectGetVal(key), &popped)) { robj *val = popped; robj *newval = objectSetExpire(val, -1); serverAssert(newval == val); @@ -1842,8 +1842,8 @@ robj *setExpire(client *c, serverDb *db, robj *key, long long when) { /* Reuse the object from the main dict in the expire dict. When setting * expire in an robj, it's potentially reallocated. We need to updates the * pointer(s) to it. */ - int dict_index = getKVStoreIndexForKey(key->ptr); - void **valref = kvstoreHashtableFindRef(db->keys, dict_index, key->ptr); + int dict_index = getKVStoreIndexForKey(objectGetVal(key)); + void **valref = kvstoreHashtableFindRef(db->keys, dict_index, objectGetVal(key)); serverAssertWithInfo(NULL, key, valref != NULL); val = *valref; long long old_when = objectGetExpire(val); @@ -1881,7 +1881,7 @@ robj *setExpire(client *c, serverDb *db, robj *key, long long when) { long long getExpireWithDictIndex(serverDb *db, robj *key, int dict_index) { robj *val; - if ((val = dbFindExpiresWithDictIndex(db, key->ptr, dict_index)) == NULL) return -1; + if ((val = dbFindExpiresWithDictIndex(db, objectGetVal(key), dict_index)) == NULL) return -1; return objectGetExpire(val); } @@ -1889,7 +1889,7 @@ long long getExpireWithDictIndex(serverDb *db, robj *key, int dict_index) { /* Return the expire time of the specified key, or -1 if no expire * is associated with this key (i.e. the key is non volatile) */ long long getExpire(serverDb *db, robj *key) { - int dict_index = getKVStoreIndexForKey(key->ptr); + int dict_index = getKVStoreIndexForKey(objectGetVal(key)); return getExpireWithDictIndex(db, key, dict_index); } @@ -1908,7 +1908,7 @@ void deleteExpiredKeyAndPropagateWithDictIndex(serverDb *db, robj *keyobj, int d /* Delete the specified expired key and propagate expire. */ void deleteExpiredKeyAndPropagate(serverDb *db, robj *keyobj) { - int dict_index = getKVStoreIndexForKey(keyobj->ptr); + int dict_index = getKVStoreIndexForKey(objectGetVal(keyobj)); deleteExpiredKeyAndPropagateWithDictIndex(db, keyobj, dict_index); } @@ -2072,7 +2072,7 @@ static int keyIsExpiredWithDictIndex(serverDb *db, robj *key, int dict_index) { /* Check if the key is expired. */ int keyIsExpired(serverDb *db, robj *key) { - int dict_index = getKVStoreIndexForKey(key->ptr); + int dict_index = getKVStoreIndexForKey(objectGetVal(key)); return keyIsExpiredWithDictIndex(db, key, dict_index); } @@ -2093,7 +2093,7 @@ static keyStatus expireIfNeededWithDictIndex(serverDb *db, robj *key, robj *val, /* The key needs to be converted from static to heap before deleted */ int static_key = key->refcount == OBJ_STATIC_REFCOUNT; if (static_key) { - key = createStringObject(key->ptr, sdslen(key->ptr)); + key = createStringObject(objectGetVal(key), sdslen(objectGetVal(key))); } /* Delete the key */ deleteExpiredKeyAndPropagateWithDictIndex(db, key, dict_index); @@ -2139,7 +2139,7 @@ static keyStatus expireIfNeededWithDictIndex(serverDb *db, robj *key, robj *val, * or returns KEY_DELETED if the key is expired and deleted. */ static keyStatus expireIfNeeded(serverDb *db, robj *key, robj *val, int flags) { if (val != NULL && !objectIsExpired(val)) return KEY_VALID; /* shortcut */ - int dict_index = getKVStoreIndexForKey(key->ptr); + int dict_index = getKVStoreIndexForKey(objectGetVal(key)); return expireIfNeededWithDictIndex(db, key, val, flags, dict_index); } @@ -2289,7 +2289,7 @@ int getKeysUsingKeySpecs(struct serverCommand *cmd, robj **argv, int argc, int s int end_index = spec->bs.keyword.startfrom > 0 ? argc - 1 : 1; for (i = start_index; i != end_index; i = start_index <= end_index ? i + 1 : i - 1) { if (i >= argc || i < 1) break; - if (!strcasecmp((char *)argv[i]->ptr, spec->bs.keyword.keyword)) { + if (!strcasecmp((char *)objectGetVal(argv[i]), spec->bs.keyword.keyword)) { first = i + 1; break; } @@ -2320,7 +2320,7 @@ int getKeysUsingKeySpecs(struct serverCommand *cmd, robj **argv, int argc, int s long long numkeys; if (spec->fk.keynum.keynumidx >= argc) goto invalid_spec; - sds keynum_str = argv[first + spec->fk.keynum.keynumidx]->ptr; + sds keynum_str = objectGetVal(argv[first + spec->fk.keynum.keynumidx]); if (!string2ll(keynum_str, sdslen(keynum_str), &numkeys) || numkeys < 0) { /* Unable to parse the numkeys argument or it was invalid */ goto invalid_spec; @@ -2609,7 +2609,7 @@ int genericGetKeys(int storeKeyOfs, int i, num; keyReference *keys; - num = atoi(argv[keyCountOfs]->ptr); + num = atoi(objectGetVal(argv[keyCountOfs])); /* Sanity check. Don't return any key if the command is going to * reply with syntax error. (no input keys). */ if (num < 1 || num > (argc - firstKeyOfs) / keyStep) { @@ -2734,10 +2734,10 @@ int sortGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResult for (i = 2; i < argc; i++) { for (j = 0; skiplist[j].name != NULL; j++) { - if (!strcasecmp(argv[i]->ptr, skiplist[j].name)) { + if (!strcasecmp(objectGetVal(argv[i]), skiplist[j].name)) { i += skiplist[j].skip; break; - } else if (!strcasecmp(argv[i]->ptr, "store") && i + 1 < argc) { + } else if (!strcasecmp(objectGetVal(argv[i]), "store") && i + 1 < argc) { /* Note: we don't increment "num" here and continue the loop * to be sure to process the *last* "STORE" option if multiple * ones are provided. This is same behavior as SORT. */ @@ -2769,8 +2769,8 @@ int migrateGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResu } skip_keywords[] = {{"copy", 0}, {"replace", 0}, {"auth", 1}, {"auth2", 2}, {NULL, 0}}; if (argc > 6) { for (i = 6; i < argc; i++) { - if (!strcasecmp(argv[i]->ptr, "keys")) { - if (sdslen(argv[3]->ptr) > 0) { + if (!strcasecmp(objectGetVal(argv[i]), "keys")) { + if (sdslen(objectGetVal(argv[3])) > 0) { /* This is a syntax error. So ignore the keys and leave * the syntax error to be handled by migrateCommand. */ num = 0; @@ -2781,7 +2781,7 @@ int migrateGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResu break; } for (j = 0; skip_keywords[j].name != NULL; j++) { - if (!strcasecmp(argv[i]->ptr, skip_keywords[j].name)) { + if (!strcasecmp(objectGetVal(argv[i]), skip_keywords[j].name)) { i += skip_keywords[j].skip; break; } @@ -2812,7 +2812,7 @@ int georadiusGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysRe /* Check for the presence of the stored key in the command */ int stored_key = -1; for (i = 5; i < argc; i++) { - char *arg = argv[i]->ptr; + char *arg = objectGetVal(argv[i]); /* For the case when user specifies both "store" and "storedist" options, the * second key specified would override the first key. This behavior is kept * the same as in georadiusCommand method. @@ -2856,7 +2856,7 @@ int xreadGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResult * name of the stream key. */ int streams_pos = -1; for (i = 1; i < argc; i++) { - char *arg = argv[i]->ptr; + char *arg = objectGetVal(argv[i]); if (!strcasecmp(arg, "block")) { i++; /* Skip option argument. */ } else if (!strcasecmp(arg, "count")) { @@ -2902,7 +2902,7 @@ int setGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysResult * result->numkeys = 1; for (int i = 3; i < argc; i++) { - char *arg = argv[i]->ptr; + char *arg = objectGetVal(argv[i]); if ((arg[0] == 'g' || arg[0] == 'G') && (arg[1] == 'e' || arg[1] == 'E') && (arg[2] == 't' || arg[2] == 'T') && arg[3] == '\0') { keys[0].flags = CMD_KEY_RW | CMD_KEY_ACCESS | CMD_KEY_UPDATE; @@ -2927,7 +2927,7 @@ int bitfieldGetKeys(struct serverCommand *cmd, robj **argv, int argc, getKeysRes for (int i = 2; i < argc; i++) { int remargs = argc - i - 1; /* Remaining args other than current. */ - char *arg = argv[i]->ptr; + char *arg = objectGetVal(argv[i]); if (!strcasecmp(arg, "get") && remargs >= 2) { i += 2; } else if ((!strcasecmp(arg, "set") || !strcasecmp(arg, "incrby")) && remargs >= 3) { diff --git a/src/debug.c b/src/debug.c index 0f67d3ce3..99533602b 100644 --- a/src/debug.c +++ b/src/debug.c @@ -104,7 +104,7 @@ void xorDigest(unsigned char *digest, const void *ptr, size_t len) { void xorStringObjectDigest(unsigned char *digest, robj *o) { o = getDecodedObject(o); - xorDigest(digest, o->ptr, sdslen(o->ptr)); + xorDigest(digest, objectGetVal(o), sdslen(objectGetVal(o))); decrRefCount(o); } @@ -133,7 +133,7 @@ void mixDigest(unsigned char *digest, const void *ptr, size_t len) { void mixStringObjectDigest(unsigned char *digest, robj *o) { o = getDecodedObject(o); - mixDigest(digest, o->ptr, sdslen(o->ptr)); + mixDigest(digest, objectGetVal(o), sdslen(objectGetVal(o))); decrRefCount(o); } @@ -175,7 +175,7 @@ void xorObjectDigest(serverDb *db, robj *keyobj, unsigned char *digest, robj *o) unsigned char eledigest[20]; if (o->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = o->ptr; + unsigned char *zl = objectGetVal(o); unsigned char *eptr, *sptr; unsigned char *vstr; unsigned int vlen; @@ -205,7 +205,7 @@ void xorObjectDigest(serverDb *db, robj *keyobj, unsigned char *digest, robj *o) zzlNext(zl, &eptr, &sptr); } } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = o->ptr; + zset *zs = objectGetVal(o); hashtableIterator iter; hashtableInitIterator(&iter, zs->ht, 0); @@ -243,7 +243,7 @@ void xorObjectDigest(serverDb *db, robj *keyobj, unsigned char *digest, robj *o) hashTypeResetIterator(&hi); } else if (o->type == OBJ_STREAM) { streamIterator si; - streamIteratorStart(&si, o->ptr, NULL, NULL, 0); + streamIteratorStart(&si, objectGetVal(o), NULL, NULL, 0); streamID id; int64_t numfields; @@ -263,7 +263,7 @@ void xorObjectDigest(serverDb *db, robj *keyobj, unsigned char *digest, robj *o) streamIteratorStop(&si); } else if (o->type == OBJ_MODULE) { ValkeyModuleDigest md = {{0}, {0}, keyobj, db->id}; - moduleValue *mv = o->ptr; + moduleValue *mv = objectGetVal(o); moduleType *mt = mv->type; moduleInitDigestContext(&md); if (mt->digest) { @@ -334,10 +334,10 @@ void mallctl_int(client *c, robj **argv, int argc) { size_t sz = sizeof(old); while (sz > 0) { size_t zz = sz; - if ((ret = je_mallctl(argv[0]->ptr, &old, &zz, argc > 1 ? &val : NULL, argc > 1 ? sz : 0))) { + if ((ret = je_mallctl(objectGetVal(argv[0]), &old, &zz, argc > 1 ? &val : NULL, argc > 1 ? sz : 0))) { if (ret == EPERM && argc > 1) { /* if this option is write only, try just writing to it. */ - if (!(ret = je_mallctl(argv[0]->ptr, NULL, 0, &val, sz))) { + if (!(ret = je_mallctl(objectGetVal(argv[0]), NULL, 0, &val, sz))) { addReply(c, shared.ok); return; } @@ -368,7 +368,7 @@ void mallctl_string(client *c, robj **argv, int argc) { char *old; size_t sz = sizeof(old); /* for strings, it seems we need to first get the old value, before overriding it. */ - if ((rret = je_mallctl(argv[0]->ptr, &old, &sz, NULL, 0))) { + if ((rret = je_mallctl(objectGetVal(argv[0]), &old, &sz, NULL, 0))) { /* return error unless this option is write only. */ if (!(rret == EPERM && argc > 1)) { addReplyErrorFormat(c, "%s", strerror(rret)); @@ -376,10 +376,10 @@ void mallctl_string(client *c, robj **argv, int argc) { } } if (argc > 1) { - char *val = argv[1]->ptr; + char *val = objectGetVal(argv[1]); char **valref = &val; if ((!strcmp(val, "VOID"))) valref = NULL, sz = 0; - wret = je_mallctl(argv[0]->ptr, NULL, 0, valref, sz); + wret = je_mallctl(objectGetVal(argv[0]), NULL, 0, valref, sz); } if (!rret) addReplyBulkCString(c, old); @@ -391,7 +391,7 @@ void mallctl_string(client *c, robj **argv, int argc) { #endif void debugCommand(client *c) { - if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "help")) { + if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "help")) { const char *help[] = { "AOF-FLUSH-SLEEP ", " Server will sleep before flushing the AOF, this is used for testing.", @@ -520,45 +520,45 @@ void debugCommand(client *c) { " When set to 1, slot migrations will be prevented from performing the slot-level failover on the target node.", NULL}; addExtendedReplyHelp(c, help, clusterDebugCommandExtendedHelp()); - } else if (!strcasecmp(c->argv[1]->ptr, "segfault")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "segfault")) { /* Compiler gives warnings about writing to a random address * e.g "*((char*)-1) = 'x';". As a workaround, we map a read-only area * and try to write there to trigger segmentation fault. */ char *p = mmap(NULL, 4096, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0); *p = 'x'; - } else if (!strcasecmp(c->argv[1]->ptr, "panic")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "panic")) { serverPanic("DEBUG PANIC called at Unix time %lld", (long long)time(NULL)); - } else if (!strcasecmp(c->argv[1]->ptr, "restart") || !strcasecmp(c->argv[1]->ptr, "crash-and-recover")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "restart") || !strcasecmp(objectGetVal(c->argv[1]), "crash-and-recover")) { long long delay = 0; if (c->argc >= 3) { if (getLongLongFromObjectOrReply(c, c->argv[2], &delay, NULL) != C_OK) return; if (delay < 0) delay = 0; } - int flags = !strcasecmp(c->argv[1]->ptr, "restart") + int flags = !strcasecmp(objectGetVal(c->argv[1]), "restart") ? (RESTART_SERVER_GRACEFULLY | RESTART_SERVER_CONFIG_REWRITE) : RESTART_SERVER_NONE; restartServer(c, flags, delay); addReplyError(c, "failed to restart the server. Check server logs."); - } else if (!strcasecmp(c->argv[1]->ptr, "oom")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "oom")) { void *ptr = zmalloc(SIZE_MAX / 2); /* Should trigger an out of memory. */ zfree(ptr); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "assert")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "assert")) { serverAssertWithInfo(c, c->argv[0], 1 == 2); - } else if (!strcasecmp(c->argv[1]->ptr, "log") && c->argc == 3) { - serverLog(LL_WARNING, "DEBUG LOG: %s", (char *)c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "log") && c->argc == 3) { + serverLog(LL_WARNING, "DEBUG LOG: %s", (char *)objectGetVal(c->argv[2])); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "leak") && c->argc == 3) { - sdsdup(c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "leak") && c->argc == 3) { + sdsdup(objectGetVal(c->argv[2])); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "reload")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "reload")) { int flush = 1, save = 1; int flags = RDBFLAGS_NONE; /* Parse the additional options that modify the RELOAD * behavior. */ for (int j = 2; j < c->argc; j++) { - char *opt = c->argv[j]->ptr; + char *opt = objectGetVal(c->argv[j]); if (!strcasecmp(opt, "MERGE")) { flags |= RDBFLAGS_ALLOW_DUP; } else if (!strcasecmp(opt, "NOFLUSH")) { @@ -597,7 +597,7 @@ void debugCommand(client *c) { } serverLog(LL_NOTICE, "DB reloaded by DEBUG RELOAD"); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "loadaof")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "loadaof")) { if (server.aof_state != AOF_OFF) flushAppendOnlyFile(1); emptyData(-1, EMPTYDB_NO_FLAGS, NULL); protectClient(c); @@ -613,38 +613,38 @@ void debugCommand(client *c) { server.dirty = 0; /* Prevent AOF / replication */ serverLog(LL_NOTICE, "Append Only File loaded by DEBUG LOADAOF"); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "drop-cluster-packet-filter") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "drop-cluster-packet-filter") && c->argc == 3) { long packet_type; if (getLongFromObjectOrReply(c, c->argv[2], &packet_type, NULL) != C_OK) return; server.cluster_drop_packet_filter = packet_type; addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "close-cluster-link-on-packet-drop") && c->argc == 3) { - server.debug_cluster_close_link_on_packet_drop = atoi(c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "close-cluster-link-on-packet-drop") && c->argc == 3) { + server.debug_cluster_close_link_on_packet_drop = atoi(objectGetVal(c->argv[2])); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "disable-cluster-random-ping") && c->argc == 3) { - server.debug_cluster_disable_random_ping = atoi(c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "disable-cluster-random-ping") && c->argc == 3) { + server.debug_cluster_disable_random_ping = atoi(objectGetVal(c->argv[2])); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "disable-cluster-reconnection") && c->argc == 3) { - server.debug_cluster_disable_reconnection = atoi(c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "disable-cluster-reconnection") && c->argc == 3) { + server.debug_cluster_disable_reconnection = atoi(objectGetVal(c->argv[2])); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "slotmigration")) { - if (!strcasecmp(c->argv[2]->ptr, "prevent-pause")) { - server.debug_slot_migration_prevent_pause = atoi(c->argv[3]->ptr); - } else if (!strcasecmp(c->argv[2]->ptr, "prevent-failover")) { - server.debug_slot_migration_prevent_failover = atoi(c->argv[3]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "slotmigration")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "prevent-pause")) { + server.debug_slot_migration_prevent_pause = atoi(objectGetVal(c->argv[3])); + } else if (!strcasecmp(objectGetVal(c->argv[2]), "prevent-failover")) { + server.debug_slot_migration_prevent_failover = atoi(objectGetVal(c->argv[3])); } else { addReplySubcommandSyntaxError(c); return; } addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "object") && (c->argc == 3 || c->argc == 4)) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "object") && (c->argc == 3 || c->argc == 4)) { robj *val; char *strenc; int fast = 0; - if (c->argc == 4 && !strcasecmp(c->argv[3]->ptr, "fast")) fast = 1; + if (c->argc == 4 && !strcasecmp(objectGetVal(c->argv[3]), "fast")) fast = 1; - if ((val = dbFind(c->db, c->argv[2]->ptr)) == NULL) { + if ((val = dbFind(c->db, objectGetVal(c->argv[2]))) == NULL) { addReplyErrorObject(c, shared.nokeyerr); return; } @@ -654,7 +654,7 @@ void debugCommand(client *c) { if (val->encoding == OBJ_ENCODING_QUICKLIST) { char *nextra = extra; int remaining = sizeof(extra); - quicklist *ql = val->ptr; + quicklist *ql = objectGetVal(val); /* Add number of quicklist nodes */ int used = snprintf(nextra, remaining, " ql_nodes:%lu", ql->len); nextra += used; @@ -697,11 +697,11 @@ void debugCommand(client *c) { s = sdscatprintf(s, "%s", extra); addReplyStatusLength(c, s, sdslen(s)); sdsfree(s); - } else if (!strcasecmp(c->argv[1]->ptr, "sdslen") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "sdslen") && c->argc == 3) { robj *val; sds key; - if ((val = dbFind(c->db, c->argv[2]->ptr)) == NULL) { + if ((val = dbFind(c->db, objectGetVal(c->argv[2]))) == NULL) { addReplyErrorObject(c, shared.nokeyerr); return; } @@ -713,15 +713,15 @@ void debugCommand(client *c) { /* Report the complete robj allocation size as the key's allocation * size. Report 0 as allocation size for embedded values. */ size_t obj_alloc = zmalloc_usable_size(val); - size_t val_alloc = val->encoding == OBJ_ENCODING_RAW ? sdsAllocSize(val->ptr) : 0; + size_t val_alloc = val->encoding == OBJ_ENCODING_RAW ? sdsAllocSize(objectGetVal(val)) : 0; addReplyStatusFormat(c, "key_sds_len:%lld key_sds_avail:%lld obj_alloc:%lld " "val_sds_len:%lld val_sds_avail:%lld val_alloc:%lld", (long long)sdslen(key), (long long)sdsavail(key), (long long)obj_alloc, - (long long)sdslen(val->ptr), (long long)sdsavail(val->ptr), + (long long)sdslen(objectGetVal(val)), (long long)sdsavail(objectGetVal(val)), (long long)val_alloc); } - } else if (!strcasecmp(c->argv[1]->ptr, "listpack") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "listpack") && c->argc == 3) { robj *o; if ((o = objectCommandLookupOrReply(c, c->argv[2], shared.nokeyerr)) == NULL) return; @@ -729,23 +729,23 @@ void debugCommand(client *c) { if (o->encoding != OBJ_ENCODING_LISTPACK) { addReplyError(c, "Not a listpack encoded object."); } else { - lpRepr(o->ptr); + lpRepr(objectGetVal(o)); addReplyStatus(c, "Listpack structure printed on stdout"); } - } else if (!strcasecmp(c->argv[1]->ptr, "quicklist") && (c->argc == 3 || c->argc == 4)) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "quicklist") && (c->argc == 3 || c->argc == 4)) { robj *o; if ((o = objectCommandLookupOrReply(c, c->argv[2], shared.nokeyerr)) == NULL) return; int full = 0; - if (c->argc == 4) full = atoi(c->argv[3]->ptr); + if (c->argc == 4) full = atoi(objectGetVal(c->argv[3])); if (o->encoding != OBJ_ENCODING_QUICKLIST) { addReplyError(c, "Not a quicklist encoded object."); } else { - quicklistRepr(o->ptr, full); + quicklistRepr(objectGetVal(o), full); addReplyStatus(c, "Quicklist structure printed on stdout"); } - } else if (!strcasecmp(c->argv[1]->ptr, "populate") && c->argc >= 3 && c->argc <= 5) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "populate") && c->argc >= 3 && c->argc <= 5) { long keys, j; robj *key, *val; char buf[128]; @@ -765,7 +765,7 @@ void debugCommand(client *c) { if (c->argc == 5 && getPositiveLongFromObjectOrReply(c, c->argv[4], &valsize, NULL) != C_OK) return; for (j = 0; j < keys; j++) { - snprintf(buf, sizeof(buf), "%s:%lu", (c->argc == 3) ? "key" : (char *)c->argv[3]->ptr, j); + snprintf(buf, sizeof(buf), "%s:%lu", (c->argc == 3) ? "key" : (char *)objectGetVal(c->argv[3]), j); key = createStringObject(buf, strlen(buf)); if (lookupKeyWrite(c->db, key) != NULL) { decrRefCount(key); @@ -777,14 +777,14 @@ void debugCommand(client *c) { else { int buflen = strlen(buf); val = createStringObject(NULL, valsize); - memcpy(val->ptr, buf, valsize <= buflen ? valsize : buflen); + memcpy(objectGetVal(val), buf, valsize <= buflen ? valsize : buflen); } dbAdd(c->db, key, &val); signalModifiedKey(c, c->db, key); decrRefCount(key); } addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "digest") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "digest") && c->argc == 2) { /* DEBUG DIGEST (form without keys specified) */ unsigned char digest[20]; sds d = sdsempty(); @@ -793,7 +793,7 @@ void debugCommand(client *c) { for (int i = 0; i < 20; i++) d = sdscatprintf(d, "%02x", digest[i]); addReplyStatus(c, d); sdsfree(d); - } else if (!strcasecmp(c->argv[1]->ptr, "digest-value") && c->argc >= 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "digest-value") && c->argc >= 2) { /* DEBUG DIGEST-VALUE key key key ... key. */ addReplyArrayLen(c, c->argc - 2); for (int j = 2; j < c->argc; j++) { @@ -802,7 +802,7 @@ void debugCommand(client *c) { /* We don't use lookupKey because a debug command should * work on logically expired keys */ - robj *o = dbFind(c->db, c->argv[j]->ptr); + robj *o = dbFind(c->db, objectGetVal(c->argv[j])); if (o) xorObjectDigest(c->db, c->argv[j], digest, o); sds d = sdsempty(); @@ -810,10 +810,10 @@ void debugCommand(client *c) { addReplyStatus(c, d); sdsfree(d); } - } else if (!strcasecmp(c->argv[1]->ptr, "protocol") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "protocol") && c->argc == 3) { /* DEBUG PROTOCOL [string|integer|double|bignum|null|array|set|map| * attrib|push|verbatim|true|false] */ - char *name = c->argv[2]->ptr; + char *name = objectGetVal(c->argv[2]); if (!strcasecmp(name, "string")) { addReplyBulkCString(c, "Hello World"); } else if (!strcasecmp(name, "integer")) { @@ -872,8 +872,8 @@ void debugCommand(client *c) { 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"); } - } else if (!strcasecmp(c->argv[1]->ptr, "sleep") && c->argc == 3) { - double dtime = valkey_strtod(c->argv[2]->ptr, NULL); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "sleep") && c->argc == 3) { + double dtime = valkey_strtod(objectGetVal(c->argv[2]), NULL); long long utime = dtime * 1000000; struct timespec tv; @@ -881,34 +881,34 @@ void debugCommand(client *c) { tv.tv_nsec = (utime % 1000000) * 1000; nanosleep(&tv, NULL); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "set-active-expire") && c->argc == 3) { - server.active_expire_enabled = atoi(c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "set-active-expire") && c->argc == 3) { + server.active_expire_enabled = atoi(objectGetVal(c->argv[2])); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "quicklist-packed-threshold") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "quicklist-packed-threshold") && c->argc == 3) { int memerr; - unsigned long long sz = memtoull((const char *)c->argv[2]->ptr, &memerr); + unsigned long long sz = memtoull((const char *)objectGetVal(c->argv[2]), &memerr); if (memerr || !quicklistSetPackedThreshold(sz)) { addReplyError(c, "argument must be a memory value bigger than 1 and smaller than 4gb"); } else { addReply(c, shared.ok); } - } else if (!strcasecmp(c->argv[1]->ptr, "set-skip-checksum-validation") && c->argc == 3) { - server.skip_checksum_validation = atoi(c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "set-skip-checksum-validation") && c->argc == 3) { + server.skip_checksum_validation = atoi(objectGetVal(c->argv[2])); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "aof-flush-sleep") && c->argc == 3) { - server.aof_flush_sleep = atoi(c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "aof-flush-sleep") && c->argc == 3) { + server.aof_flush_sleep = atoi(objectGetVal(c->argv[2])); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "replicate") && c->argc >= 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "replicate") && c->argc >= 3) { replicationFeedReplicas(-1, c->argv + 2, c->argc - 2); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "error") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "error") && c->argc == 3) { sds errstr = sdsnewlen("-", 1); - errstr = sdscatsds(errstr, c->argv[2]->ptr); + errstr = sdscatsds(errstr, objectGetVal(c->argv[2])); errstr = sdsmapchars(errstr, "\n\r", " ", 2); /* no newlines in errors. */ errstr = sdscatlen(errstr, "\r\n", 2); addReplySds(c, errstr); - } else if (!strcasecmp(c->argv[1]->ptr, "structsize") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "structsize") && c->argc == 2) { sds sizes = sdsempty(); sizes = sdscatprintf(sizes, "bits:%d ", (sizeof(void *) == 8) ? 64 : 32); sizes = sdscatprintf(sizes, "robj:%d ", (int)sizeof(robj)); @@ -919,7 +919,7 @@ void debugCommand(client *c) { sizes = sdscatprintf(sizes, "sdshdr32:%d ", (int)sizeof(struct sdshdr32)); sizes = sdscatprintf(sizes, "sdshdr64:%d ", (int)sizeof(struct sdshdr64)); addReplyBulkSds(c, sizes); - } else if (!strcasecmp(c->argv[1]->ptr, "htstats") && c->argc >= 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "htstats") && c->argc >= 3) { long dbid; sds stats = sdsempty(); char buf[4096]; @@ -934,7 +934,7 @@ void debugCommand(client *c) { addReplyError(c, "Out of range database"); return; } - if (c->argc >= 4 && !strcasecmp(c->argv[3]->ptr, "full")) full = 1; + if (c->argc >= 4 && !strcasecmp(objectGetVal(c->argv[3]), "full")) full = 1; stats = sdscatprintf(stats, "[Dictionary HT]\n"); serverDb *db = server.db[dbid]; @@ -952,9 +952,9 @@ void debugCommand(client *c) { addReplyVerbatim(c, stats, sdslen(stats), "txt"); sdsfree(stats); - } else if (!strcasecmp(c->argv[1]->ptr, "htstats-key") && c->argc >= 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "htstats-key") && c->argc >= 3) { int full = 0; - if (c->argc >= 4 && !strcasecmp(c->argv[3]->ptr, "full")) full = 1; + if (c->argc >= 4 && !strcasecmp(objectGetVal(c->argv[3]), "full")) full = 1; robj *o = objectCommandLookupOrReply(c, c->argv[2], shared.nokeyerr); if (o == NULL) return; @@ -963,10 +963,10 @@ void debugCommand(client *c) { hashtable *ht = NULL; switch (o->encoding) { case OBJ_ENCODING_SKIPLIST: { - zset *zs = o->ptr; + zset *zs = objectGetVal(o); ht = zs->ht; } break; - case OBJ_ENCODING_HASHTABLE: ht = o->ptr; break; + case OBJ_ENCODING_HASHTABLE: ht = objectGetVal(o); break; } if (ht != NULL) { @@ -977,23 +977,23 @@ void debugCommand(client *c) { addReplyError(c, "The value stored at the specified key is not " "represented using an hash table"); } - } else if (!strcasecmp(c->argv[1]->ptr, "change-repl-id") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "change-repl-id") && c->argc == 2) { serverLog(LL_NOTICE, "Changing replication IDs after receiving DEBUG change-repl-id"); changeReplicationId(); clearReplicationId2(); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "stringmatch-test") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "stringmatch-test") && c->argc == 2) { stringmatchlen_fuzz_test(); addReplyStatus(c, "Apparently the server did not crash: test passed"); - } else if (!strcasecmp(c->argv[1]->ptr, "set-disable-deny-scripts") && c->argc == 3) { - server.script_disable_deny_script = atoi(c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "set-disable-deny-scripts") && c->argc == 3) { + server.script_disable_deny_script = atoi(objectGetVal(c->argv[2])); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "config-rewrite-force-all") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "config-rewrite-force-all") && c->argc == 2) { if (rewriteConfig(server.configfile, 1) == -1) addReplyErrorFormat(c, "CONFIG-REWRITE-FORCE-ALL failed: %s", strerror(errno)); else addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "client-eviction") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "client-eviction") && c->argc == 2) { if (!server.client_mem_usage_buckets) { addReplyError(c, "maxmemory-clients is disabled."); return; @@ -1017,44 +1017,44 @@ void debugCommand(client *c) { addReplyVerbatim(c, bucket_info, sdslen(bucket_info), "txt"); sdsfree(bucket_info); #ifdef USE_JEMALLOC - } else if (!strcasecmp(c->argv[1]->ptr, "mallctl") && c->argc >= 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "mallctl") && c->argc >= 3) { mallctl_int(c, c->argv + 2, c->argc - 2); return; - } else if (!strcasecmp(c->argv[1]->ptr, "mallctl-str") && c->argc >= 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "mallctl-str") && c->argc >= 3) { mallctl_string(c, c->argv + 2, c->argc - 2); return; #endif - } else if (!strcasecmp(c->argv[1]->ptr, "pause-cron") && c->argc == 3) { - server.pause_cron = atoi(c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "pause-cron") && c->argc == 3) { + server.pause_cron = atoi(objectGetVal(c->argv[2])); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "replybuffer") && c->argc == 4) { - if (!strcasecmp(c->argv[2]->ptr, "peak-reset-time")) { - if (!strcasecmp(c->argv[3]->ptr, "never")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "replybuffer") && c->argc == 4) { + if (!strcasecmp(objectGetVal(c->argv[2]), "peak-reset-time")) { + if (!strcasecmp(objectGetVal(c->argv[3]), "never")) { server.reply_buffer_peak_reset_time = -1; - } else if (!strcasecmp(c->argv[3]->ptr, "reset")) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "reset")) { server.reply_buffer_peak_reset_time = REPLY_BUFFER_DEFAULT_PEAK_RESET_TIME; } else { if (getLongFromObjectOrReply(c, c->argv[3], &server.reply_buffer_peak_reset_time, NULL) != C_OK) return; } - } else if (!strcasecmp(c->argv[2]->ptr, "resizing")) { - server.reply_buffer_resizing_enabled = atoi(c->argv[3]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[2]), "resizing")) { + server.reply_buffer_resizing_enabled = atoi(objectGetVal(c->argv[3])); } else { addReplySubcommandSyntaxError(c); return; } addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "pause-after-fork") && c->argc == 3) { - server.debug_pause_after_fork = atoi(c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "pause-after-fork") && c->argc == 3) { + server.debug_pause_after_fork = atoi(objectGetVal(c->argv[2])); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "delay-rdb-client-free-seconds") && c->argc == 3) { - server.wait_before_rdb_client_free = atoi(c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "delay-rdb-client-free-seconds") && c->argc == 3) { + server.wait_before_rdb_client_free = atoi(objectGetVal(c->argv[2])); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "dict-resizing") && c->argc == 3) { - server.dict_resizing = atoi(c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "dict-resizing") && c->argc == 3) { + server.dict_resizing = atoi(objectGetVal(c->argv[2])); updateDictResizePolicy(); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "client-enforce-reply-list") && c->argc == 3) { - server.debug_client_enforce_reply_list = atoi(c->argv[2]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "client-enforce-reply-list") && c->argc == 3) { + server.debug_client_enforce_reply_list = atoi(objectGetVal(c->argv[2])); addReply(c, shared.ok); } else if (!handleDebugClusterCommand(c)) { addReplySubcommandSyntaxError(c); @@ -1086,7 +1086,7 @@ __attribute__((noinline, weak)) void _serverAssert(const char *estr, const char /* Returns the argv argument in binary representation, limited to length 128. */ sds getArgvReprString(robj *argv) { robj *decoded = getDecodedObject(argv); - sds repr = sdscatrepr(sdsempty(), decoded->ptr, min(sdslen(decoded->ptr), 128)); + sds repr = sdscatrepr(sdsempty(), objectGetVal(decoded), min(sdslen(objectGetVal(decoded)), 128)); decrRefCount(decoded); return repr; } @@ -1112,13 +1112,13 @@ void _serverAssertPrintClientInfo(const client *c) { serverLog(LL_WARNING, "client->argc = %d", c->argc); for (j = 0; j < c->argc; j++) { if (shouldRedactArg(c, j)) { - serverLog(LL_WARNING, "client->argv[%d]: %zu bytes", j, sdslen((sds)c->argv[j]->ptr)); + serverLog(LL_WARNING, "client->argv[%d]: %zu bytes", j, sdslen((sds)objectGetVal(c->argv[j]))); continue; } sds repr = getArgvReprString(c->argv[j]); serverLog(LL_WARNING, "client->argv[%d] = %s (refcount: %d)", j, repr, c->argv[j]->refcount); sdsfree(repr); - if (!strcasecmp(c->argv[j]->ptr, "auth") || !strcasecmp(c->argv[j]->ptr, "auth2")) { + if (!strcasecmp(objectGetVal(c->argv[j]), "auth") || !strcasecmp(objectGetVal(c->argv[j]), "auth2")) { break; } } @@ -1931,13 +1931,13 @@ void logCurrentClient(client *cc, const char *title) { serverLog(LL_WARNING | LL_RAW, "argc: %d\n", cc->argc); for (j = 0; j < cc->argc; j++) { if (shouldRedactArg(cc, j)) { - serverLog(LL_WARNING | LL_RAW, "argv[%d]: %zu bytes\n", j, sdslen((sds)cc->argv[j]->ptr)); + serverLog(LL_WARNING | LL_RAW, "argv[%d]: %zu bytes\n", j, sdslen((sds)objectGetVal(cc->argv[j]))); continue; } sds repr = getArgvReprString(cc->argv[j]); serverLog(LL_WARNING | LL_RAW, "argv[%d]: %s\n", j, repr); sdsfree(repr); - if (!strcasecmp(cc->argv[j]->ptr, "auth") || !strcasecmp(cc->argv[j]->ptr, "auth2")) { + if (!strcasecmp(objectGetVal(cc->argv[j]), "auth") || !strcasecmp(objectGetVal(cc->argv[j]), "auth2")) { break; } } @@ -1947,9 +1947,9 @@ void logCurrentClient(client *cc, const char *title) { robj *val, *key; key = getDecodedObject(cc->argv[1]); - val = dbFind(cc->db, key->ptr); + val = dbFind(cc->db, objectGetVal(key)); if (val) { - serverLog(LL_WARNING, "key '%s' found in DB containing the following object:", (char *)key->ptr); + serverLog(LL_WARNING, "key '%s' found in DB containing the following object:", (char *)objectGetVal(key)); serverLogObjectDebugInfo(val); } decrRefCount(key); diff --git a/src/defrag.c b/src/defrag.c index b612a6bae..03f1654f9 100644 --- a/src/defrag.c +++ b/src/defrag.c @@ -214,17 +214,11 @@ sds activeDefragSds(sds sdsptr) { static robj *activeDefragStringObWithoutFree(robj *ob, size_t *allocation_size) { if (ob->type == OBJ_STRING && ob->encoding == OBJ_ENCODING_RAW) { // Try to defrag the linked sds, regardless of if robj will be moved - sds newsds = activeDefragSds((sds)ob->ptr); - if (newsds) ob->ptr = newsds; + sds newsds = activeDefragSds((sds)objectGetVal(ob)); + if (newsds) objectSetVal(ob, newsds); } robj *new_robj = activeDefragAllocWithoutFree(ob, allocation_size); - - if (new_robj && ob->type == OBJ_STRING && ob->encoding == OBJ_ENCODING_EMBSTR) { - // If the robj is moved, correct the internal pointer - long embstr_offset = (intptr_t)ob->ptr - (intptr_t)ob; - new_robj->ptr = (void *)((intptr_t)new_robj + embstr_offset); - } return new_robj; } @@ -371,7 +365,7 @@ static void defragLater(robj *obj) { /* returns 0 if no more work needs to be been done, and 1 if time is up and more work is needed. */ static long scanLaterList(robj *ob, unsigned long *cursor, monotime endtime) { - quicklist *ql = ob->ptr; + quicklist *ql = objectGetVal(ob); quicklistNode *node; serverAssert(ob->type == OBJ_LIST && ob->encoding == OBJ_ENCODING_QUICKLIST); @@ -395,7 +389,7 @@ static long scanLaterList(robj *ob, unsigned long *cursor, monotime endtime) { /* Check time limit after processing each node */ if (getMonotonicUs() > endtime) { if (quicklistBookmarkCreate(&ql, "_AD", node)) { - ob->ptr = ql; /* bookmark creation may have re-allocated the quicklist */ + objectSetVal(ob, ql); /* bookmark creation may have re-allocated the quicklist */ (*cursor)++; return 1; } @@ -417,7 +411,7 @@ static void scanLaterZsetCallback(void *privdata, void *element_ref) { static void scanLaterZset(robj *ob, unsigned long *cursor) { serverAssert(ob->type == OBJ_ZSET && ob->encoding == OBJ_ENCODING_SKIPLIST); - zset *zs = (zset *)ob->ptr; + zset *zs = (zset *)objectGetVal(ob); *cursor = hashtableScanDefrag(zs->ht, *cursor, scanLaterZsetCallback, zs->zsl, activeDefragAlloc, HASHTABLE_SCAN_EMIT_REF); } @@ -431,7 +425,7 @@ static void scanHashtableCallbackCountScanned(void *privdata, void *elemref) { static void scanLaterSet(robj *ob, unsigned long *cursor) { serverAssert(ob->type == OBJ_SET && ob->encoding == OBJ_ENCODING_HASHTABLE); - hashtable *ht = ob->ptr; + hashtable *ht = objectGetVal(ob); *cursor = hashtableScanDefrag(ht, *cursor, activeDefragSdsHashtableCallback, NULL, activeDefragAlloc, HASHTABLE_SCAN_EMIT_REF); } @@ -441,9 +435,12 @@ static void scanLaterHash(robj *ob, unsigned long *cursor) { } static void defragQuicklist(robj *ob) { - quicklist *ql = ob->ptr, *newql; + quicklist *ql = objectGetVal(ob), *newql; serverAssert(ob->type == OBJ_LIST && ob->encoding == OBJ_ENCODING_QUICKLIST); - if ((newql = activeDefragAlloc(ql))) ob->ptr = ql = newql; + if ((newql = activeDefragAlloc(ql))) { + objectSetVal(ob, newql); + ql = newql; + } if (ql->len > server.active_defrag_max_scan_fields) defragLater(ob); else @@ -452,12 +449,15 @@ static void defragQuicklist(robj *ob) { static void defragZsetSkiplist(robj *ob) { serverAssert(ob->type == OBJ_ZSET && ob->encoding == OBJ_ENCODING_SKIPLIST); - zset *zs = (zset *)ob->ptr; + zset *zs = (zset *)objectGetVal(ob); zset *newzs; zskiplist *newzsl; struct zskiplistNode *newheader; - if ((newzs = activeDefragAlloc(zs))) ob->ptr = zs = newzs; + if ((newzs = activeDefragAlloc(zs))) { + objectSetVal(ob, newzs); + zs = newzs; + } if ((newzsl = activeDefragAlloc(zs->zsl))) zs->zsl = newzsl; if ((newheader = activeDefragAlloc(zs->zsl->header))) zs->zsl->header = newheader; @@ -480,7 +480,7 @@ static void defragZsetSkiplist(robj *ob) { * Smaller ones are defragmented immediately, possibly over multiple passes. * Listpack-encoded hashes are always handled in a single pass. */ static void defragHash(robj *ob) { - hashtable *ht = ob->ptr; + hashtable *ht = objectGetVal(ob); if (ob->encoding == OBJ_ENCODING_HASHTABLE && hashtableSize(ht) > server.active_defrag_max_scan_fields) { /* Large hashtable-encoded hashes are deferred via `defrag_later` */ defragLater(ob); @@ -496,7 +496,7 @@ static void defragHash(robj *ob) { static void defragSet(robj *ob) { serverAssert(ob->type == OBJ_SET && ob->encoding == OBJ_ENCODING_HASHTABLE); - hashtable *ht = ob->ptr; + hashtable *ht = objectGetVal(ob); if (hashtableSize(ht) > server.active_defrag_max_scan_fields) { defragLater(ob); } else { @@ -507,7 +507,7 @@ static void defragSet(robj *ob) { } /* defrag the hashtable struct and tables */ hashtable *new_hashtable = hashtableDefragTables(ht, activeDefragAlloc); - if (new_hashtable) ob->ptr = new_hashtable; + if (new_hashtable) objectSetVal(ob, new_hashtable); } /* Defrag callback for radix tree iterator, called for each node, @@ -528,7 +528,7 @@ static int scanLaterStreamListpacks(robj *ob, unsigned long *cursor, monotime en long iterations = 0; serverAssert(ob->type == OBJ_STREAM && ob->encoding == OBJ_ENCODING_STREAM); - stream *s = ob->ptr; + stream *s = objectGetVal(ob); raxStart(&ri, s->rax); if (*cursor == 0) { /* if cursor is 0, we start new iteration */ @@ -640,10 +640,13 @@ static void *defragStreamConsumerGroup(raxIterator *ri, void *privdata) { static void defragStream(robj *ob) { serverAssert(ob->type == OBJ_STREAM && ob->encoding == OBJ_ENCODING_STREAM); - stream *s = ob->ptr, *news; + stream *s = objectGetVal(ob), *news; /* handle the main struct */ - if ((news = activeDefragAlloc(s))) ob->ptr = s = news; + if ((news = activeDefragAlloc(s))) { + objectSetVal(ob, news); + s = news; + } if (raxSize(s->rax) > server.active_defrag_max_scan_fields) { rax *newrax = activeDefragAlloc(s->rax); @@ -704,7 +707,7 @@ static void defragKey(defragKeysCtx *ctx, robj **elemref) { if (ob->encoding == OBJ_ENCODING_QUICKLIST) { defragQuicklist(ob); } else if (ob->encoding == OBJ_ENCODING_LISTPACK) { - if ((newzl = activeDefragAlloc(ob->ptr))) ob->ptr = newzl; + if ((newzl = activeDefragAlloc(objectGetVal(ob)))) objectSetVal(ob, newzl); } else { serverPanic("Unknown list encoding"); } @@ -712,14 +715,14 @@ static void defragKey(defragKeysCtx *ctx, robj **elemref) { if (ob->encoding == OBJ_ENCODING_HASHTABLE) { defragSet(ob); } else if (ob->encoding == OBJ_ENCODING_INTSET || ob->encoding == OBJ_ENCODING_LISTPACK) { - void *newptr, *ptr = ob->ptr; - if ((newptr = activeDefragAlloc(ptr))) ob->ptr = newptr; + void *newptr, *ptr = objectGetVal(ob); + if ((newptr = activeDefragAlloc(ptr))) objectSetVal(ob, newptr); } else { serverPanic("Unknown set encoding"); } } else if (ob->type == OBJ_ZSET) { if (ob->encoding == OBJ_ENCODING_LISTPACK) { - if ((newzl = activeDefragAlloc(ob->ptr))) ob->ptr = newzl; + if ((newzl = activeDefragAlloc(objectGetVal(ob)))) objectSetVal(ob, newzl); } else if (ob->encoding == OBJ_ENCODING_SKIPLIST) { defragZsetSkiplist(ob); } else { diff --git a/src/eval.c b/src/eval.c index bbfe080f9..0007489f8 100644 --- a/src/eval.c +++ b/src/eval.c @@ -289,13 +289,13 @@ int evalExtractShebangFlags(sds body, uint64_t evalGetCommandFlags(client *c, uint64_t cmd_flags) { char sha[41]; int evalsha = c->cmd->proc == evalShaCommand || c->cmd->proc == evalShaRoCommand; - if (evalsha && sdslen(c->argv[1]->ptr) != 40) return cmd_flags; + if (evalsha && sdslen(objectGetVal(c->argv[1])) != 40) return cmd_flags; uint64_t script_flags; - evalCalcScriptHash(evalsha, c->argv[1]->ptr, sha); + evalCalcScriptHash(evalsha, objectGetVal(c->argv[1]), sha); c->cur_script = dictFind(evalCtx.scripts, sha); if (!c->cur_script) { if (evalsha) return cmd_flags; - if (evalExtractShebangFlags(c->argv[1]->ptr, NULL, &script_flags, NULL, NULL) == C_ERR) return cmd_flags; + if (evalExtractShebangFlags(objectGetVal(c->argv[1]), NULL, &script_flags, NULL, NULL) == C_ERR) return cmd_flags; } else { evalScript *es = dictGetVal(c->cur_script); script_flags = es->flags; @@ -353,7 +353,7 @@ static int evalRegisterNewScript(client *c, robj *body, char **sha) { if (is_script_load) { *sha = (char *)zcalloc(41); - evalCalcScriptHash(0, body->ptr, *sha); + evalCalcScriptHash(0, objectGetVal(body), *sha); /* If the script was previously added via EVAL, we promote it to * SCRIPT LOAD, prevent it from being evicted later. */ @@ -374,7 +374,7 @@ static int evalRegisterNewScript(client *c, robj *body, char **sha) { uint64_t script_flags; sds err = NULL; char *engine_name = NULL; - if (evalExtractShebangFlags(body->ptr, &engine_name, &script_flags, &shebang_len, &err) == C_ERR) { + if (evalExtractShebangFlags(objectGetVal(body), &engine_name, &script_flags, &shebang_len, &err) == C_ERR) { if (c != NULL) { addReplyErrorSds(c, err); } @@ -408,15 +408,15 @@ static int evalRegisterNewScript(client *c, robj *body, char **sha) { compiledFunction **functions = scriptingEngineCallCompileCode(engine, VMSE_EVAL, - (sds)body->ptr + shebang_len, - sdslen(body->ptr) - shebang_len, + (sds)objectGetVal(body) + shebang_len, + sdslen(objectGetVal(body)) - shebang_len, 0, &num_compiled_functions, &_err); if (functions == NULL) { serverAssert(_err != NULL); if (c != NULL) { - addReplyErrorFormat(c, "%s", (char *)_err->ptr); + addReplyErrorFormat(c, "%s", (char *)objectGetVal(_err)); } decrRefCount(_err); if (is_script_load) { @@ -468,7 +468,7 @@ static void evalGenericCommand(client *c, int evalsha) { memcpy(sha, dictGetKey(c->cur_script), 40); sha[40] = '\0'; } else { - evalCalcScriptHash(evalsha, c->argv[1]->ptr, sha); + evalCalcScriptHash(evalsha, objectGetVal(c->argv[1]), sha); } dictEntry *entry = dictFind(evalCtx.scripts, sha); @@ -537,7 +537,7 @@ void evalShaCommand(client *c) { /* Explicitly feed monitor here so that lua commands appear after their * script command. */ replicationFeedMonitors(c, server.monitors, c->db->id, c->argv, c->argc); - if (sdslen(c->argv[1]->ptr) != 40) { + if (sdslen(objectGetVal(c->argv[1])) != 40) { /* We know that a match is not possible if the provided SHA is * not the right length. So we return an error ASAP, this way * evalGenericCommand() can be implemented without string length @@ -558,7 +558,7 @@ void evalShaRoCommand(client *c) { } void scriptCommand(client *c) { - if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "help")) { + if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "help")) { const char *help[] = { "DEBUG (YES|SYNC|NO) []", " Set the debug mode for subsequent scripts executed of the specified engine.", @@ -580,11 +580,11 @@ void scriptCommand(client *c) { NULL, }; addReplyHelp(c, help); - } else if (c->argc >= 2 && !strcasecmp(c->argv[1]->ptr, "flush")) { + } else if (c->argc >= 2 && !strcasecmp(objectGetVal(c->argv[1]), "flush")) { int async = 0; - if (c->argc == 3 && !strcasecmp(c->argv[2]->ptr, "sync")) { + if (c->argc == 3 && !strcasecmp(objectGetVal(c->argv[2]), "sync")) { async = 0; - } else if (c->argc == 3 && !strcasecmp(c->argv[2]->ptr, "async")) { + } else if (c->argc == 3 && !strcasecmp(objectGetVal(c->argv[2]), "async")) { async = 1; } else if (c->argc == 2) { async = server.lazyfree_lazy_user_flush ? 1 : 0; @@ -594,17 +594,17 @@ void scriptCommand(client *c) { } evalReset(async); addReply(c, shared.ok); - } else if (c->argc >= 2 && !strcasecmp(c->argv[1]->ptr, "exists")) { + } else if (c->argc >= 2 && !strcasecmp(objectGetVal(c->argv[1]), "exists")) { int j; addReplyArrayLen(c, c->argc - 2); for (j = 2; j < c->argc; j++) { - if (dictFind(evalCtx.scripts, c->argv[j]->ptr)) + if (dictFind(evalCtx.scripts, objectGetVal(c->argv[j]))) addReply(c, shared.cone); else addReply(c, shared.czero); } - } else if (c->argc == 3 && !strcasecmp(c->argv[1]->ptr, "load")) { + } else if (c->argc == 3 && !strcasecmp(objectGetVal(c->argv[1]), "load")) { char *sha = NULL; if (evalRegisterNewScript(c, c->argv[2], &sha) != C_OK) { serverAssert(sha == NULL); @@ -612,15 +612,15 @@ void scriptCommand(client *c) { } addReplyBulkCBuffer(c, sha, 40); zfree(sha); - } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "kill")) { + } else if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "kill")) { scriptKill(c, 1); - } else if ((c->argc == 3 || c->argc == 4) && !strcasecmp(c->argv[1]->ptr, "debug")) { + } else if ((c->argc == 3 || c->argc == 4) && !strcasecmp(objectGetVal(c->argv[1]), "debug")) { if (clientHasPendingReplies(c)) { addReplyError(c, "SCRIPT DEBUG must be called outside a pipeline"); return; } - const char *engine_name = c->argc == 4 ? c->argv[3]->ptr : "lua"; + const char *engine_name = c->argc == 4 ? objectGetVal(c->argv[3]) : "lua"; scriptingEngine *en = scriptingEngineManagerFind(engine_name); if (en == NULL) { addReplyErrorFormat(c, "No scripting engine found with name '%s' to enable debug", engine_name); @@ -629,16 +629,16 @@ void scriptCommand(client *c) { serverAssert(en != NULL); sds err; - if (!strcasecmp(c->argv[2]->ptr, "no")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "no")) { scriptingEngineDebuggerDisable(c); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[2]->ptr, "yes")) { + } else if (!strcasecmp(objectGetVal(c->argv[2]), "yes")) { if (scriptingEngineDebuggerEnable(c, en, &err) != C_OK) { addReplyErrorSds(c, err); return; } addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[2]->ptr, "sync")) { + } else if (!strcasecmp(objectGetVal(c->argv[2]), "sync")) { if (scriptingEngineDebuggerEnable(c, en, &err) != C_OK) { addReplyErrorSds(c, err); return; @@ -649,11 +649,11 @@ void scriptCommand(client *c) { addReplyError(c, "Use SCRIPT DEBUG YES/SYNC/NO"); return; } - } else if (c->argc == 3 && !strcasecmp(c->argv[1]->ptr, "show")) { + } else if (c->argc == 3 && !strcasecmp(objectGetVal(c->argv[1]), "show")) { dictEntry *de; evalScript *es; - if (sdslen(c->argv[2]->ptr) == 40 && (de = dictFind(evalCtx.scripts, c->argv[2]->ptr))) { + if (sdslen(objectGetVal(c->argv[2])) == 40 && (de = dictFind(evalCtx.scripts, objectGetVal(c->argv[2])))) { es = dictGetVal(de); addReplyBulk(c, es->body); } else { diff --git a/src/expire.c b/src/expire.c index f1330ee8a..f2539153c 100644 --- a/src/expire.c +++ b/src/expire.c @@ -615,13 +615,13 @@ void rememberReplicaKeyWithExpire(serverDb *db, robj *key) { } if (db->id > 63) return; - dictEntry *de = dictAddOrFind(replicaKeysWithExpire, key->ptr); + dictEntry *de = dictAddOrFind(replicaKeysWithExpire, objectGetVal(key)); /* If the entry was just created, set it to a copy of the SDS string * representing the key: we don't want to need to take those keys * in sync with the main DB. The keys will be removed by expireReplicaKeys() * as it scans to find keys to remove. */ - if (dictGetKey(de) == key->ptr) { - dictSetKey(replicaKeysWithExpire, de, sdsdup(key->ptr)); + if (dictGetKey(de) == objectGetVal(key)) { + dictSetKey(replicaKeysWithExpire, de, sdsdup(objectGetVal(key))); dictSetUnsignedIntegerVal(de, 0); } @@ -685,7 +685,7 @@ int parseExtendedExpireArgumentsOrReply(client *c, int *flags, int max_args) { int j = 3; while (j < max_args) { - char *opt = c->argv[j]->ptr; + char *opt = objectGetVal(c->argv[j]); if (!strcasecmp(opt, "nx")) { *flags |= EXPIRE_NX; nx = 1; diff --git a/src/functions.c b/src/functions.c index fda376a27..1017f0882 100644 --- a/src/functions.c +++ b/src/functions.c @@ -277,13 +277,13 @@ static int functionLibCreateFunction(compiledFunction *function, serverAssert(function->name->type == OBJ_STRING); serverAssert(function->desc == NULL || function->desc->type == OBJ_STRING); - if (functionsVerifyName(function->name->ptr) != C_OK) { + if (functionsVerifyName(objectGetVal(function->name)) != C_OK) { *err = sdsnew("Function names can only contain letters, numbers, or " "underscores(_) and must be at least one character long"); return C_ERR; } - sds name_sds = sdsdup(function->name->ptr); + sds name_sds = sdsdup(objectGetVal(function->name)); if (dictFetchValue(li->functions, name_sds)) { *err = sdsnew("Function already exists in the library"); sdsfree(name_sds); @@ -319,7 +319,7 @@ static void libraryUnlink(functionsLibCtx *lib_ctx, functionLibInfo *li) { while ((entry = dictNext(iter))) { functionInfo *fi = dictGetVal(entry); int ret = dictDelete(lib_ctx->functions, - fi->compiled_function->name->ptr); + objectGetVal(fi->compiled_function->name)); serverAssert(ret == DICT_OK); lib_ctx->cache_memory -= functionMallocSize(fi); } @@ -343,7 +343,7 @@ static void libraryLink(functionsLibCtx *lib_ctx, functionLibInfo *li) { while ((entry = dictNext(iter))) { functionInfo *fi = dictGetVal(entry); dictAdd(lib_ctx->functions, - sdsnew(fi->compiled_function->name->ptr), + sdsnew(objectGetVal(fi->compiled_function->name)), fi); lib_ctx->cache_memory += functionMallocSize(fi); } @@ -400,10 +400,10 @@ libraryJoin(functionsLibCtx *functions_lib_ctx_dst, functionsLibCtx *functions_l while ((entry = dictNext(iter))) { functionInfo *fi = dictGetVal(entry); if (dictFetchValue(functions_lib_ctx_dst->functions, - fi->compiled_function->name->ptr)) { + objectGetVal(fi->compiled_function->name))) { *err = sdscatfmt(sdsempty(), "Function %s already exists", - fi->compiled_function->name->ptr); + objectGetVal(fi->compiled_function->name)); goto done; } } @@ -490,7 +490,7 @@ void functionStatsCommand(client *c) { client *script_client = scriptGetCaller(); addReplyArrayLen(c, script_client->argc); for (int i = 0; i < script_client->argc; ++i) { - addReplyBulkCBuffer(c, script_client->argv[i]->ptr, sdslen(script_client->argv[i]->ptr)); + addReplyBulkCBuffer(c, objectGetVal(script_client->argv[i]), sdslen(objectGetVal(script_client->argv[i]))); } addReplyBulkCString(c, "duration_ms"); addReplyLongLong(c, scriptRunDuration()); @@ -537,19 +537,19 @@ void functionListCommand(client *c) { sds library_name = NULL; for (int i = 2; i < c->argc; ++i) { robj *next_arg = c->argv[i]; - if (!with_code && !strcasecmp(next_arg->ptr, "withcode")) { + if (!with_code && !strcasecmp(objectGetVal(next_arg), "withcode")) { with_code = 1; continue; } - if (!library_name && !strcasecmp(next_arg->ptr, "libraryname")) { + if (!library_name && !strcasecmp(objectGetVal(next_arg), "libraryname")) { if (i >= c->argc - 1) { addReplyError(c, "library name argument was not given"); return; } - library_name = c->argv[++i]->ptr; + library_name = objectGetVal(c->argv[++i]); continue; } - addReplyErrorSds(c, sdscatfmt(sdsempty(), "Unknown argument %s", next_arg->ptr)); + addReplyErrorSds(c, sdscatfmt(sdsempty(), "Unknown argument %s", objectGetVal(next_arg))); return; } size_t reply_len = 0; @@ -585,10 +585,10 @@ void functionListCommand(client *c) { functionInfo *fi = dictGetVal(function_entry); addReplyMapLen(c, 3); addReplyBulkCString(c, "name"); - addReplyBulkCString(c, fi->compiled_function->name->ptr); + addReplyBulkCString(c, objectGetVal(fi->compiled_function->name)); addReplyBulkCString(c, "description"); if (fi->compiled_function->desc) { - addReplyBulkCString(c, fi->compiled_function->desc->ptr); + addReplyBulkCString(c, objectGetVal(fi->compiled_function->desc)); } else { addReplyNull(c); } @@ -613,7 +613,7 @@ void functionListCommand(client *c) { */ void functionDeleteCommand(client *c) { robj *function_name = c->argv[2]; - functionLibInfo *li = dictFetchValue(curr_functions_lib_ctx->libraries, function_name->ptr); + functionLibInfo *li = dictFetchValue(curr_functions_lib_ctx->libraries, objectGetVal(function_name)); if (!li) { addReplyError(c, "Library not found"); return; @@ -636,7 +636,7 @@ void functionKillCommand(client *c) { * Note that it does not guarantee the command arguments are right. */ uint64_t fcallGetCommandFlags(client *c, uint64_t cmd_flags) { robj *function_name = c->argv[1]; - c->cur_script = dictFind(curr_functions_lib_ctx->functions, function_name->ptr); + c->cur_script = dictFind(curr_functions_lib_ctx->functions, objectGetVal(function_name)); if (!c->cur_script) return cmd_flags; functionInfo *fi = dictGetVal(c->cur_script); uint64_t script_flags = fi->compiled_function->f_flags; @@ -649,7 +649,7 @@ static void fcallCommandGeneric(client *c, int ro) { robj *function_name = c->argv[1]; dictEntry *de = c->cur_script; - if (!de) de = dictFind(curr_functions_lib_ctx->functions, function_name->ptr); + if (!de) de = dictFind(curr_functions_lib_ctx->functions, objectGetVal(function_name)); if (!de) { addReplyError(c, "Function not found"); return; @@ -675,7 +675,7 @@ static void fcallCommandGeneric(client *c, int ro) { if (scriptPrepareForRun(&run_ctx, engine, c, - fi->compiled_function->name->ptr, + objectGetVal(fi->compiled_function->name), fi->compiled_function->f_flags, ro) != C_OK) return; @@ -760,13 +760,13 @@ void functionRestoreCommand(client *c) { } restorePolicy restore_replicy = restorePolicy_Append; /* default policy: APPEND */ - sds data = c->argv[2]->ptr; + sds data = objectGetVal(c->argv[2]); size_t data_len = sdslen(data); rio payload; sds err = NULL; if (c->argc == 4) { - const char *restore_policy_str = c->argv[3]->ptr; + const char *restore_policy_str = objectGetVal(c->argv[3]); if (!strcasecmp(restore_policy_str, "append")) { restore_replicy = restorePolicy_Append; } else if (!strcasecmp(restore_policy_str, "replace")) { @@ -843,9 +843,9 @@ void functionFlushCommand(client *c) { return; } int async = 0; - if (c->argc == 3 && !strcasecmp(c->argv[2]->ptr, "sync")) { + if (c->argc == 3 && !strcasecmp(objectGetVal(c->argv[2]), "sync")) { async = 0; - } else if (c->argc == 3 && !strcasecmp(c->argv[2]->ptr, "async")) { + } else if (c->argc == 3 && !strcasecmp(objectGetVal(c->argv[2]), "async")) { async = 1; } else if (c->argc == 2) { async = server.lazyfree_lazy_user_flush ? 1 : 0; @@ -1049,7 +1049,7 @@ sds functionsCreateWithLibraryCtx(sds code, int replace, sds *err, functionsLibC if (compiled_functions == NULL) { serverAssert(num_compiled_functions == 0); serverAssert(compile_error != NULL); - *err = sdsdup(compile_error->ptr); + *err = sdsdup(objectGetVal(compile_error)); decrRefCount(compile_error); goto error; } @@ -1078,10 +1078,10 @@ sds functionsCreateWithLibraryCtx(sds code, int replace, sds *err, functionsLibC while ((entry = dictNext(iter))) { functionInfo *fi = dictGetVal(entry); if (dictFetchValue(lib_ctx->functions, - fi->compiled_function->name->ptr)) { + objectGetVal(fi->compiled_function->name))) { /* functions name collision, abort. */ *err = sdscatfmt(sdsempty(), "Function %s already exists", - fi->compiled_function->name->ptr); + objectGetVal(fi->compiled_function->name)); goto error; } } @@ -1118,11 +1118,11 @@ void functionLoadCommand(client *c) { int argc_pos = 2; while (argc_pos < c->argc - 1) { robj *next_arg = c->argv[argc_pos++]; - if (!strcasecmp(next_arg->ptr, "replace")) { + if (!strcasecmp(objectGetVal(next_arg), "replace")) { replace = 1; continue; } - addReplyErrorFormat(c, "Unknown option given: %s", (char *)next_arg->ptr); + addReplyErrorFormat(c, "Unknown option given: %s", (char *)objectGetVal(next_arg)); return; } @@ -1138,7 +1138,7 @@ void functionLoadCommand(client *c) { if (mustObeyClient(c)) { timeout = 0; } - if (!(library_name = functionsCreateWithLibraryCtx(code->ptr, replace, &err, curr_functions_lib_ctx, timeout))) { + if (!(library_name = functionsCreateWithLibraryCtx(objectGetVal(code), replace, &err, curr_functions_lib_ctx, timeout))) { serverAssert(err != NULL); addReplyErrorSds(c, err); return; diff --git a/src/geo.c b/src/geo.c index 38027476b..e1b9c0a90 100644 --- a/src/geo.c +++ b/src/geo.c @@ -125,12 +125,12 @@ int extractLongLatOrReply(client *c, robj **argv, double *xy) { int longLatFromMemberOrReply(client *c, robj *zobj, robj *member, double *xy) { double score = 0; - if (zsetScore(zobj, member->ptr, &score) == C_ERR) { - addReplyErrorFormat(c, "member %s does not exist", (char *)member->ptr); + if (zsetScore(zobj, objectGetVal(member), &score) == C_ERR) { + addReplyErrorFormat(c, "member %s does not exist", (char *)objectGetVal(member)); return C_ERR; } if (!decodeGeohash(score, xy)) { - addReplyErrorFormat(c, "failed to decode, member %s is not a valid geohash", (char *)member->ptr); + addReplyErrorFormat(c, "failed to decode, member %s is not a valid geohash", (char *)objectGetVal(member)); return C_ERR; } return C_OK; @@ -143,7 +143,7 @@ int longLatFromMemberOrReply(client *c, robj *zobj, robj *member, double *xy) { * If the unit is not valid, an error is reported to the client, and a value * less than zero is returned. */ double extractUnitOrReply(client *c, robj *unit) { - char *u = unit->ptr; + char *u = objectGetVal(unit); if (!strcasecmp(u, "m")) { return 1; @@ -275,7 +275,7 @@ int geoGetPointsInRange(robj *zobj, double min, double max, GeoShape *shape, geo zrangespec range = {.min = min, .max = max, .minex = 0, .maxex = 1}; size_t origincount = ga->used; if (zobj->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = zobj->ptr; + unsigned char *zl = objectGetVal(zobj); unsigned char *eptr, *sptr; unsigned char *vstr = NULL; unsigned int vlen = 0; @@ -306,7 +306,7 @@ int geoGetPointsInRange(robj *zobj, double min, double max, GeoShape *shape, geo zzlNext(zl, &eptr, &sptr); } } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zobj->ptr; + zset *zs = objectGetVal(zobj); zskiplist *zsl = zs->zsl; zskiplistNode *ln; @@ -456,7 +456,7 @@ void geoaddCommand(client *c) { /* Parse options. At the end 'longidx' is set to the argument position * of the longitude of the first element. */ while (longidx < c->argc) { - char *opt = c->argv[longidx]->ptr; + char *opt = objectGetVal(c->argv[longidx]); if (!strcasecmp(opt, "nx")) nx = 1; else if (!strcasecmp(opt, "xx")) @@ -581,7 +581,7 @@ void georadiusGeneric(client *c, int srcKeyIndex, int flags) { if (c->argc > base_args) { int remaining = c->argc - base_args; for (int i = 0; i < remaining; i++) { - char *arg = c->argv[base_args + i]->ptr; + char *arg = objectGetVal(c->argv[base_args + i]); if (!strcasecmp(arg, "withdist")) { withdist = 1; } else if (!strcasecmp(arg, "withhash")) { @@ -685,13 +685,13 @@ void georadiusGeneric(client *c, int srcKeyIndex, int flags) { if ((flags & GEOSEARCH) && !(frommember || fromloc) && !bypolygon) { addReplyErrorFormat(c, "exactly one of FROMMEMBER or FROMLONLAT can be specified for %s", - (char *)c->argv[0]->ptr); + (char *)objectGetVal(c->argv[0])); geoPolygonPointsFree(&shape); return; } if ((flags & GEOSEARCH) && !(byradius || bybox || bypolygon)) { - addReplyErrorFormat(c, "exactly one of BYRADIUS, BYBOX and BYPOLYGON can be specified for %s", (char *)c->argv[0]->ptr); + addReplyErrorFormat(c, "exactly one of BYRADIUS, BYBOX and BYPOLYGON can be specified for %s", (char *)objectGetVal(c->argv[0])); geoPolygonPointsFree(&shape); return; } @@ -812,7 +812,7 @@ void georadiusGeneric(client *c, int srcKeyIndex, int flags) { if (returned_items) { zobj = createZsetObject(); - zs = zobj->ptr; + zs = objectGetVal(zobj); } for (i = 0; i < returned_items; i++) { @@ -892,7 +892,7 @@ void geohashCommand(client *c) { addReplyArrayLen(c, c->argc - 2); for (j = 2; j < c->argc; j++) { double score; - if (!zobj || zsetScore(zobj, c->argv[j]->ptr, &score) == C_ERR) { + if (!zobj || zsetScore(zobj, objectGetVal(c->argv[j]), &score) == C_ERR) { addReplyNull(c); } else { /* The internal format we use for geocoding is a bit different @@ -953,7 +953,7 @@ void geoposCommand(client *c) { addReplyArrayLen(c, c->argc - 2); for (j = 2; j < c->argc; j++) { double score; - if (!zobj || zsetScore(zobj, c->argv[j]->ptr, &score) == C_ERR) { + if (!zobj || zsetScore(zobj, objectGetVal(c->argv[j]), &score) == C_ERR) { addReplyNullArray(c); } else { /* Decode... */ @@ -993,7 +993,7 @@ void geodistCommand(client *c) { /* Get the scores. We need both otherwise NULL is returned. */ double score1, score2, xyxy[4]; - if (zsetScore(zobj, c->argv[2]->ptr, &score1) == C_ERR || zsetScore(zobj, c->argv[3]->ptr, &score2) == C_ERR) { + if (zsetScore(zobj, objectGetVal(c->argv[2]), &score1) == C_ERR || zsetScore(zobj, objectGetVal(c->argv[3]), &score2) == C_ERR) { addReplyNull(c); return; } diff --git a/src/hyperloglog.c b/src/hyperloglog.c index cd3e122cd..039d95c72 100644 --- a/src/hyperloglog.c +++ b/src/hyperloglog.c @@ -542,7 +542,7 @@ int hllDenseSet(uint8_t *registers, long index, uint8_t count) { * * This is just a wrapper to hllDenseSet(), performing the hashing of the * element in order to retrieve the index and zero-run count. */ -int hllDenseAdd(uint8_t *registers, unsigned char *ele, size_t elesize) { +static int hllDenseAdd(uint8_t *registers, unsigned char *ele, size_t elesize) { long index; uint8_t count = hllPatLen(ele, elesize, &index); /* Update the register if this element produced a longer run of zeroes. */ @@ -615,7 +615,7 @@ void hllDenseRegHisto(uint8_t *registers, int *reghisto) { * The function returns C_OK if the sparse representation was valid, * otherwise C_ERR is returned if the representation was corrupted. */ int hllSparseToDense(robj *o) { - sds sparse = o->ptr, dense; + sds sparse = objectGetVal(o), dense; struct hllhdr *hdr, *oldhdr = (struct hllhdr *)sparse; int idx = 0, runlen, regval; uint8_t *p = (uint8_t *)sparse, *end = p + sdslen(sparse); @@ -676,8 +676,8 @@ int hllSparseToDense(robj *o) { } /* Free the old representation and set the new one. */ - sdsfree(o->ptr); - o->ptr = dense; + sdsfree(objectGetVal(o)); + objectSetVal(o, dense); return C_OK; } @@ -696,7 +696,7 @@ int hllSparseToDense(robj *o) { * sparse to dense: this happens when a register requires to be set to a value * not representable with the sparse representation, or when the resulting * size would be greater than server.hll_sparse_max_bytes. */ -int hllSparseSet(robj *o, long index, uint8_t count) { +static bool hllSparseSet(robj *o, long index, uint8_t count) { struct hllhdr *hdr; uint8_t oldcount, *sparse, *end, *p, *prev, *next; long first, span; @@ -715,19 +715,19 @@ int hllSparseSet(robj *o, long index, uint8_t count) { * If the available size of hyperloglog sds string is not enough for the increment * we need, we promote the hyperloglog to dense representation in 'step 3'. */ - if (sdsalloc(o->ptr) < server.hll_sparse_max_bytes && sdsavail(o->ptr) < 3) { - size_t newlen = sdslen(o->ptr) + 3; + if (sdsalloc(objectGetVal(o)) < server.hll_sparse_max_bytes && sdsavail(objectGetVal(o)) < 3) { + size_t newlen = sdslen(objectGetVal(o)) + 3; newlen += min(newlen, 300); /* Greediness: double 'newlen' if it is smaller than 300, or add 300 to it when it exceeds 300 */ if (newlen > server.hll_sparse_max_bytes) newlen = server.hll_sparse_max_bytes; - o->ptr = sdsResize(o->ptr, newlen, 1); + objectSetVal(o, sdsResize(objectGetVal(o), newlen, 1)); } /* Step 1: we need to locate the opcode we need to modify to check * if a value update is actually needed. */ - sparse = p = ((uint8_t *)o->ptr) + HLL_HDR_SIZE; - end = p + sdslen(o->ptr) - HLL_HDR_SIZE; + sparse = p = ((uint8_t *)objectGetVal(o)) + HLL_HDR_SIZE; + end = p + sdslen(objectGetVal(o)) - HLL_HDR_SIZE; first = 0; prev = NULL; /* Points to previous opcode at the end of the loop. */ @@ -884,10 +884,10 @@ int hllSparseSet(robj *o, long index, uint8_t count) { int oldlen = is_xzero ? 2 : 1; int deltalen = seqlen - oldlen; - if (deltalen > 0 && sdslen(o->ptr) + deltalen > server.hll_sparse_max_bytes) goto promote; - serverAssert(sdslen(o->ptr) + deltalen <= sdsalloc(o->ptr)); + if (deltalen > 0 && sdslen(objectGetVal(o)) + deltalen > server.hll_sparse_max_bytes) goto promote; + serverAssert(sdslen(objectGetVal(o)) + deltalen <= sdsalloc(objectGetVal(o))); if (deltalen && next) memmove(next + deltalen, next, end - next); - sdsIncrLen(o->ptr, deltalen); + sdsIncrLen(objectGetVal(o), deltalen); memcpy(p, seq, seqlen); end += deltalen; @@ -917,7 +917,7 @@ updated: if (len <= HLL_SPARSE_VAL_MAX_LEN) { HLL_SPARSE_VAL_SET(p + 1, v1, len); memmove(p, p + 1, end - p); - sdsIncrLen(o->ptr, -1); + sdsIncrLen(objectGetVal(o), -1); end--; /* After a merge we reiterate without incrementing 'p' * in order to try to merge the just merged value with @@ -930,13 +930,13 @@ updated: } /* Invalidate the cached cardinality. */ - hdr = o->ptr; + hdr = objectGetVal(o); HLL_INVALIDATE_CACHE(hdr); return 1; promote: /* Promote to dense representation. */ if (hllSparseToDense(o) == C_ERR) return -1; /* Corrupted HLL. */ - hdr = o->ptr; + hdr = objectGetVal(o); /* We need to call hllDenseAdd() to perform the operation after the * conversion. However the result must be 1, since if we need to @@ -956,7 +956,7 @@ promote: /* Promote to dense representat * * This function is actually a wrapper for hllSparseSet(), it only performs * the hashing of the element to obtain the index and zeros run length. */ -int hllSparseAdd(robj *o, unsigned char *ele, size_t elesize) { +static int hllSparseAdd(robj *o, unsigned char *ele, size_t elesize) { long index; uint8_t count = hllPatLen(ele, elesize, &index); /* Update the register if this element produced a longer run of zeroes. */ @@ -1116,8 +1116,8 @@ uint64_t hllCount(struct hllhdr *hdr, int *invalid) { } /* Call hllDenseAdd() or hllSparseAdd() according to the HLL encoding. */ -int hllAdd(robj *o, unsigned char *ele, size_t elesize) { - struct hllhdr *hdr = o->ptr; +static int hllAdd(robj *o, unsigned char *ele, size_t elesize) { + struct hllhdr *hdr = objectGetVal(o); switch (hdr->encoding) { case HLL_DENSE: return hllDenseAdd(hdr->registers, ele, elesize); case HLL_SPARSE: return hllSparseAdd(o, ele, elesize); @@ -1359,13 +1359,13 @@ void hllMergeDense(uint8_t *reg_raw, const uint8_t *reg_dense) { * If the HyperLogLog is sparse and is found to be invalid, C_ERR * is returned, otherwise the function always succeeds. */ int hllMerge(uint8_t *max, robj *hll) { - struct hllhdr *hdr = hll->ptr; + struct hllhdr *hdr = objectGetVal(hll); int i; if (hdr->encoding == HLL_DENSE) { hllMergeDense(max, hdr->registers); } else { - uint8_t *p = hll->ptr, *end = p + sdslen(hll->ptr); + uint8_t *p = objectGetVal(hll), *end = p + sdslen(objectGetVal(hll)); long runlen, regval; int valid = 1; @@ -1624,7 +1624,7 @@ robj *createHLLObject(void) { /* Create the actual object. */ o = createObject(OBJ_STRING, s); - hdr = o->ptr; + hdr = objectGetVal(o); memcpy(hdr->magic, "HYLL", 4); hdr->encoding = HLL_SPARSE; return o; @@ -1641,7 +1641,7 @@ int isHLLObjectOrReply(client *c, robj *o) { if (!sdsEncodedObject(o)) goto invalid; if (stringObjectLen(o) < sizeof(*hdr)) goto invalid; - hdr = o->ptr; + hdr = objectGetVal(o); /* Magic should be "HYLL". */ if (hdr->magic[0] != 'H' || hdr->magic[1] != 'Y' || hdr->magic[2] != 'L' || hdr->magic[3] != 'L') goto invalid; @@ -1679,13 +1679,13 @@ void pfaddCommand(client *c) { } /* Perform the low level ADD operation for every element. */ for (j = 2; j < c->argc; j++) { - int retval = hllAdd(o, (unsigned char *)c->argv[j]->ptr, sdslen(c->argv[j]->ptr)); + int retval = hllAdd(o, (unsigned char *)objectGetVal(c->argv[j]), sdslen(objectGetVal(c->argv[j]))); switch (retval) { case 1: updated++; break; case -1: addReplyError(c, invalid_hll_err); return; } } - hdr = o->ptr; + hdr = objectGetVal(o); if (updated) { HLL_INVALIDATE_CACHE(hdr); signalModifiedKey(c, c->db, c->argv[1]); @@ -1754,7 +1754,7 @@ void pfcountCommand(client *c) { o = dbUnshareStringValue(c->db, c->argv[1], o); /* Check if the cached cardinality is valid. */ - hdr = o->ptr; + hdr = objectGetVal(o); if (HLL_VALID_CACHE(hdr)) { /* Just return the cached value. */ card = (uint64_t)hdr->card[0]; @@ -1810,7 +1810,7 @@ void pfmergeCommand(client *c) { /* If at least one involved HLL is dense, use the dense representation * as target ASAP to save time and avoid the conversion step. */ - hdr = o->ptr; + hdr = objectGetVal(o); if (hdr->encoding == HLL_DENSE) use_dense = 1; /* Merge with this HLL with our 'max' HLL by setting max[i] @@ -1846,19 +1846,19 @@ void pfmergeCommand(client *c) { /* Write the resulting HLL to the destination HLL registers and * invalidate the cached value. */ if (use_dense) { - hdr = o->ptr; + hdr = objectGetVal(o); hllDenseCompress(hdr->registers, max); } else { for (j = 0; j < HLL_REGISTERS; j++) { if (max[j] == 0) continue; - hdr = o->ptr; + hdr = objectGetVal(o); switch (hdr->encoding) { case HLL_DENSE: hllDenseSet(hdr->registers, j, max[j]); break; case HLL_SPARSE: hllSparseSet(o, j, max[j]); break; } } } - hdr = o->ptr; /* o->ptr may be different now, as a side effect of + hdr = objectGetVal(o); /* o->ptr may be different now, as a side effect of last hllSparseSet() call. */ HLL_INVALIDATE_CACHE(hdr); @@ -1933,7 +1933,7 @@ void pfselftestCommand(client *c) { /* Make sure that for small cardinalities we use sparse * encoding. */ if (j == checkpoint && j < server.hll_sparse_max_bytes / 2) { - hdr2 = o->ptr; + hdr2 = objectGetVal(o); if (hdr2->encoding != HLL_SPARSE) { addReplyError(c, "TESTFAILED sparse encoding not used"); goto cleanup; @@ -1941,7 +1941,7 @@ void pfselftestCommand(client *c) { } /* Check that dense and sparse representations agree. */ - if (j == checkpoint && hllCount(hdr, NULL) != hllCount(o->ptr, NULL)) { + if (j == checkpoint && hllCount(hdr, NULL) != hllCount(objectGetVal(o), NULL)) { addReplyError(c, "TESTFAILED dense/sparse disagree"); goto cleanup; } @@ -1984,7 +1984,7 @@ cleanup: * PFDEBUG SIMD (ON|OFF) */ void pfdebugCommand(client *c) { - char *cmd = c->argv[1]->ptr; + char *cmd = objectGetVal(c->argv[1]); struct hllhdr *hdr; robj *o; int j; @@ -1992,11 +1992,11 @@ void pfdebugCommand(client *c) { if (!strcasecmp(cmd, "simd")) { if (c->argc != 3) goto arityerr; - if (!strcasecmp(c->argv[2]->ptr, "on")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "on")) { #if SIMD_SUPPORTED simd_enabled = 1; #endif - } else if (!strcasecmp(c->argv[2]->ptr, "off")) { + } else if (!strcasecmp(objectGetVal(c->argv[2]), "off")) { #if SIMD_SUPPORTED simd_enabled = 0; #endif @@ -2016,7 +2016,7 @@ void pfdebugCommand(client *c) { } if (isHLLObjectOrReply(c, o) != C_OK) return; o = dbUnshareStringValue(c->db, c->argv[2], o); - hdr = o->ptr; + hdr = objectGetVal(o); /* PFDEBUG GETREG */ if (!strcasecmp(cmd, "getreg")) { @@ -2030,7 +2030,7 @@ void pfdebugCommand(client *c) { server.dirty++; /* Force propagation on encoding change. */ } - hdr = o->ptr; + hdr = objectGetVal(o); addReplyArrayLen(c, HLL_REGISTERS); for (j = 0; j < HLL_REGISTERS; j++) { uint8_t val; @@ -2043,7 +2043,7 @@ void pfdebugCommand(client *c) { else if (!strcasecmp(cmd, "decode")) { if (c->argc != 3) goto arityerr; - uint8_t *p = o->ptr, *end = p + sdslen(o->ptr); + uint8_t *p = objectGetVal(o), *end = p + sdslen(objectGetVal(o)); sds decoded = sdsempty(); if (hdr->encoding != HLL_SPARSE) { diff --git a/src/io_threads.c b/src/io_threads.c index b5c9d1f03..1d51e520e 100644 --- a/src/io_threads.c +++ b/src/io_threads.c @@ -567,8 +567,8 @@ int tryOffloadFreeObjToIOThreads(robj *obj) { /* We offload only the free of the ptr that may be allocated by the I/O thread. * The object itself was allocated by the main thread and will be freed by the main thread. */ - IOJobQueue_push(jq, sdsfreeVoid, obj->ptr); - obj->ptr = NULL; + IOJobQueue_push(jq, sdsfreeVoid, objectGetVal(obj)); + objectSetVal(obj, NULL); decrRefCount(obj); server.stat_io_freed_objects++; diff --git a/src/latency.c b/src/latency.c index 7f7951053..d69f86981 100644 --- a/src/latency.c +++ b/src/latency.c @@ -556,7 +556,7 @@ void latencySpecificCommandsFillCDF(client *c) { void *replylen = addReplyDeferredLen(c); int command_with_data = 0; for (int j = 2; j < c->argc; j++) { - struct serverCommand *cmd = lookupCommandBySds(c->argv[j]->ptr); + struct serverCommand *cmd = lookupCommandBySds(objectGetVal(c->argv[j])); /* If the command does not exist we skip the reply */ if (cmd == NULL) { continue; @@ -684,21 +684,21 @@ sds latencyCommandGenSparkeline(char *event, struct latencyTimeSeries *ts) { void latencyCommand(client *c) { struct latencyTimeSeries *ts; - if (!strcasecmp(c->argv[1]->ptr, "history") && c->argc == 3) { + if (!strcasecmp(objectGetVal(c->argv[1]), "history") && c->argc == 3) { /* LATENCY HISTORY */ - ts = dictFetchValue(server.latency_events, c->argv[2]->ptr); + ts = dictFetchValue(server.latency_events, objectGetVal(c->argv[2])); if (ts == NULL) { addReplyArrayLen(c, 0); } else { latencyCommandReplyWithSamples(c, ts); } - } else if (!strcasecmp(c->argv[1]->ptr, "graph") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "graph") && c->argc == 3) { /* LATENCY GRAPH */ sds graph; dictEntry *de; char *event; - de = dictFind(server.latency_events, c->argv[2]->ptr); + de = dictFind(server.latency_events, objectGetVal(c->argv[2])); if (de == NULL) goto nodataerr; ts = dictGetVal(de); event = dictGetKey(de); @@ -706,26 +706,26 @@ void latencyCommand(client *c) { graph = latencyCommandGenSparkeline(event, ts); addReplyVerbatim(c, graph, sdslen(graph), "txt"); sdsfree(graph); - } else if (!strcasecmp(c->argv[1]->ptr, "latest") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "latest") && c->argc == 2) { /* LATENCY LATEST */ latencyCommandReplyWithLatestEvents(c); - } else if (!strcasecmp(c->argv[1]->ptr, "doctor") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "doctor") && c->argc == 2) { /* LATENCY DOCTOR */ sds report = createLatencyReport(); addReplyVerbatim(c, report, sdslen(report), "txt"); sdsfree(report); - } else if (!strcasecmp(c->argv[1]->ptr, "reset") && c->argc >= 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "reset") && c->argc >= 2) { /* LATENCY RESET */ if (c->argc == 2) { addReplyLongLong(c, latencyResetEvent(NULL)); } else { int j, resets = 0; - for (j = 2; j < c->argc; j++) resets += latencyResetEvent(c->argv[j]->ptr); + for (j = 2; j < c->argc; j++) resets += latencyResetEvent(objectGetVal(c->argv[j])); addReplyLongLong(c, resets); } - } else if (!strcasecmp(c->argv[1]->ptr, "histogram") && c->argc >= 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "histogram") && c->argc >= 2) { /* LATENCY HISTOGRAM*/ if (c->argc == 2) { int command_with_data = 0; @@ -735,7 +735,7 @@ void latencyCommand(client *c) { } else { latencySpecificCommandsFillCDF(c); } - } else if (!strcasecmp(c->argv[1]->ptr, "help") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "help") && c->argc == 2) { const char *help[] = { "DOCTOR", " Return a human readable latency analysis report.", @@ -762,7 +762,7 @@ void latencyCommand(client *c) { nodataerr: /* Common error when the user asks for an event we have no latency * information about. */ - addReplyErrorFormat(c, "No samples available for event '%s'", (char *)c->argv[2]->ptr); + addReplyErrorFormat(c, "No samples available for event '%s'", (char *)objectGetVal(c->argv[2])); } void durationAddSample(int type, monotime duration) { diff --git a/src/lazyfree.c b/src/lazyfree.c index 3ee403aeb..07d6ef295 100644 --- a/src/lazyfree.c +++ b/src/lazyfree.c @@ -127,20 +127,20 @@ void lazyfreeResetStats(void) { * representing the list. */ size_t lazyfreeGetFreeEffort(robj *key, robj *obj, int dbid) { if (obj->type == OBJ_LIST && obj->encoding == OBJ_ENCODING_QUICKLIST) { - quicklist *ql = obj->ptr; + quicklist *ql = objectGetVal(obj); return ql->len; } else if (obj->type == OBJ_SET && obj->encoding == OBJ_ENCODING_HASHTABLE) { - hashtable *ht = obj->ptr; + hashtable *ht = objectGetVal(obj); return hashtableSize(ht); } else if (obj->type == OBJ_ZSET && obj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = obj->ptr; + zset *zs = objectGetVal(obj); return zs->zsl->length; } else if (obj->type == OBJ_HASH && obj->encoding == OBJ_ENCODING_HASHTABLE) { - hashtable *ht = obj->ptr; + hashtable *ht = objectGetVal(obj); return hashtableSize(ht); } else if (obj->type == OBJ_STREAM) { size_t effort = 0; - stream *s = obj->ptr; + stream *s = objectGetVal(obj); /* Make a best effort estimate to maintain constant runtime. Every macro * node in the Stream is one allocation. */ diff --git a/src/logreqres.c b/src/logreqres.c index 72b182bcb..a233de083 100644 --- a/src/logreqres.c +++ b/src/logreqres.c @@ -178,7 +178,7 @@ size_t reqresAppendRequest(client *c) { if (!reqresShouldLog(c)) return 0; /* Ignore commands that have streaming non-standard response */ - sds cmd = argv[0]->ptr; + sds cmd = objectGetVal(argv[0]); if (!strcasecmp(cmd, "debug") || /* because of DEBUG SEGFAULT */ !strcasecmp(cmd, "sync") || !strcasecmp(cmd, "psync") || !strcasecmp(cmd, "monitor") || !strcasecmp(cmd, "subscribe") || !strcasecmp(cmd, "unsubscribe") || !strcasecmp(cmd, "ssubscribe") || @@ -191,10 +191,10 @@ size_t reqresAppendRequest(client *c) { size_t ret = 0; for (int i = 0; i < argc; i++) { if (sdsEncodedObject(argv[i])) { - ret += reqresAppendArg(c, argv[i]->ptr, sdslen(argv[i]->ptr)); + ret += reqresAppendArg(c, objectGetVal(argv[i]), sdslen(objectGetVal(argv[i]))); } else if (argv[i]->encoding == OBJ_ENCODING_INT) { char buf[LONG_STR_SIZE]; - size_t len = ll2string(buf, sizeof(buf), (long)argv[i]->ptr); + size_t len = ll2string(buf, sizeof(buf), (long)objectGetVal(argv[i])); ret += reqresAppendArg(c, buf, len); } else { serverPanic("Wrong encoding in reqresAppendRequest()"); diff --git a/src/lolwut.c b/src/lolwut.c index a1d7ef17a..636975476 100644 --- a/src/lolwut.c +++ b/src/lolwut.c @@ -56,7 +56,7 @@ void lolwutCommand(client *c) { char *v = VALKEY_VERSION; char verstr[64]; - if (c->argc >= 3 && !strcasecmp(c->argv[1]->ptr, "version")) { + if (c->argc >= 3 && !strcasecmp(objectGetVal(c->argv[1]), "version")) { long ver; if (getLongFromObjectOrReply(c, c->argv[2], &ver, NULL) != C_OK) return; snprintf(verstr, sizeof(verstr), "%u.0.0", (unsigned int)ver); diff --git a/src/lua/debug_lua.c b/src/lua/debug_lua.c index 9b295fb71..360ac02e5 100644 --- a/src/lua/debug_lua.c +++ b/src/lua/debug_lua.c @@ -66,7 +66,7 @@ void ldbStart(robj *source) { /* First argument of EVAL is the script itself. We split it into different * lines since this is the way the debugger accesses the source code. */ - sds srcstring = sdsdup(source->ptr); + sds srcstring = sdsdup(objectGetVal(source)); size_t srclen = sdslen(srcstring); while (srclen && (srcstring[srclen - 1] == '\n' || srcstring[srclen - 1] == '\r')) { srcstring[--srclen] = '\0'; @@ -340,7 +340,7 @@ static void ldbBreak(robj **argv, int argc) { } else { int j; for (j = 1; j < argc; j++) { - char *arg = argv[j]->ptr; + char *arg = objectGetVal(argv[j]); long line; if (!string2l(arg, sdslen(arg), &line)) { ldbLog(sdscatfmt(sdsempty(), "Invalid argument:'%s'", arg)); @@ -374,7 +374,7 @@ static void ldbEval(lua_State *lua, robj **argv, int argc) { /* Glue the script together if it is composed of multiple arguments. */ sds code = sdsempty(); for (int j = 1; j < argc; j++) { - code = sdscatsds(code, argv[j]->ptr); + code = sdscatsds(code, objectGetVal(argv[j])); if (j != argc - 1) code = sdscatlen(code, " ", 1); } sds expr = sdscatsds(sdsnew("return "), code); @@ -426,7 +426,7 @@ static void ldbServer(lua_State *lua, robj **argv, int argc) { lua_pushstring(lua, "call"); lua_gettable(lua, -2); /* Stack: server, server.call */ for (j = 1; j < argc; j++) - lua_pushlstring(lua, argv[j]->ptr, sdslen(argv[j]->ptr)); + lua_pushlstring(lua, objectGetVal(argv[j]), sdslen(objectGetVal(argv[j]))); ldb.step = 1; /* Force server.call() to log. */ lua_pcall(lua, argc - 1, 1, 0); /* Stack: server, result */ ldb.step = 0; /* Disable logging. */ @@ -474,10 +474,10 @@ static int listCommandHandler(robj **argv, size_t argc, void *context) { UNUSED(context); int around = ldb.currentline, ctx = 5; if (argc > 1) { - int num = atoi(argv[1]->ptr); + int num = atoi(objectGetVal(argv[1])); if (num > 0) around = num; } - if (argc > 2) ctx = atoi(argv[2]->ptr); + if (argc > 2) ctx = atoi(objectGetVal(argv[2])); ldbList(around, ctx); scriptingEngineDebuggerFlushLogs(); return CONTINUE_READ_NEXT_COMMAND; @@ -496,7 +496,7 @@ static int printCommandHandler(robj **argv, size_t argc, void *context) { serverAssert(context != NULL); lua_State *lua = context; if (argc == 2) { - ldbPrint(lua, argv[1]->ptr); + ldbPrint(lua, objectGetVal(argv[1])); } else { ldbPrintAll(lua); } @@ -612,7 +612,7 @@ int ldbRepl(lua_State *lua) { scriptingEngineDebuggerProcessCommands(&client_disconnected, &err); if (err) { - luaPushError(lua, err->ptr); + luaPushError(lua, objectGetVal(err)); decrRefCount(err); luaError(lua); } else if (client_disconnected) { diff --git a/src/lua/script_lua.c b/src/lua/script_lua.c index 5fafddd40..4c9c87a46 100644 --- a/src/lua/script_lua.c +++ b/src/lua/script_lua.c @@ -848,7 +848,7 @@ static robj **luaArgsToServerArgv(lua_State *lua, int *argc, int *argv_len) { } /* Try to use a cached object. */ if (j < LUA_CMD_OBJCACHE_SIZE && lua_args_cached_objects[j] && lua_args_cached_objects_len[j] >= obj_len) { - sds s = lua_args_cached_objects[j]->ptr; + sds s = objectGetVal(lua_args_cached_objects[j]); lua_argv[j] = lua_args_cached_objects[j]; lua_args_cached_objects[j] = NULL; memcpy(s, obj_s, obj_len + 1); @@ -884,8 +884,8 @@ void freeLuaServerArgv(robj **argv, int argc, int argv_len) { * (we must be the only owner) for us to cache it. */ if (j < LUA_CMD_OBJCACHE_SIZE && o->refcount == 1 && (o->encoding == OBJ_ENCODING_RAW || o->encoding == OBJ_ENCODING_EMBSTR) && - sdslen(o->ptr) <= LUA_CMD_OBJCACHE_MAX_LEN) { - sds s = o->ptr; + sdslen(objectGetVal(o)) <= LUA_CMD_OBJCACHE_MAX_LEN) { + sds s = objectGetVal(o); if (lua_args_cached_objects[j]) decrRefCount(lua_args_cached_objects[j]); lua_args_cached_objects[j] = o; lua_args_cached_objects_len[j] = sdsalloc(s); @@ -938,7 +938,7 @@ static int luaServerGenericCommand(lua_State *lua, int raise_error) { break; } else { cmdlog = sdscatlen(cmdlog, " ", 1); - cmdlog = sdscatsds(cmdlog, c->argv[j]->ptr); + cmdlog = sdscatsds(cmdlog, objectGetVal(c->argv[j])); } } ldbLog(cmdlog); @@ -1599,7 +1599,7 @@ static void luaCreateArray(lua_State *lua, robj **elev, int elec) { lua_createtable(lua, elec, 0); for (j = 0; j < elec; j++) { - lua_pushlstring(lua, (char *)elev[j]->ptr, sdslen(elev[j]->ptr)); + lua_pushlstring(lua, (char *)objectGetVal(elev[j]), sdslen(objectGetVal(elev[j]))); lua_rawseti(lua, -2, j + 1); } } diff --git a/src/memory_prefetch.c b/src/memory_prefetch.c index 62ec47f37..963514937 100644 --- a/src/memory_prefetch.c +++ b/src/memory_prefetch.c @@ -138,7 +138,7 @@ static void prefetchValue(KeyPrefetchInfo *info) { if (hashtableIncrementalFindGetResult(&info->hashtab_state, &entry)) { robj *val = entry; if (val->encoding == OBJ_ENCODING_RAW && val->type == OBJ_STRING) { - valkey_prefetch(val->ptr); + valkey_prefetch(objectGetVal(val)); } } @@ -195,14 +195,14 @@ static void prefetchCommands(void) { if (!c || c->argc <= 1) continue; for (int j = 1; j < c->argc; j++) { if (c->argv[j]->encoding == OBJ_ENCODING_RAW) { - valkey_prefetch(c->argv[j]->ptr); + valkey_prefetch(objectGetVal(c->argv[j])); } } } /* Get the keys ptrs - we do it here after the key obj was prefetched. */ for (size_t i = 0; i < batch->key_count; i++) { - batch->keys[i] = ((robj *)batch->keys[i])->ptr; + batch->keys[i] = objectGetVal((robj *)batch->keys[i]); } /* Prefetch hashtable keys for all commands. Prefetching is beneficial only if there are more than one key. */ diff --git a/src/module.c b/src/module.c index dfec1a907..dd0a80533 100644 --- a/src/module.c +++ b/src/module.c @@ -695,7 +695,7 @@ sds moduleLoadQueueEntryToLoadmoduleOptionStr(ValkeyModule *module, line = sdscatsds(line, module->loadmod->path); for (int i = 0; i < module->loadmod->argc; i++) { line = sdscatlen(line, " ", 1); - line = sdscatsds(line, module->loadmod->argv[i]->ptr); + line = sdscatsds(line, objectGetVal(module->loadmod->argv[i])); } return line; @@ -2977,8 +2977,8 @@ const char *VM_StringPtrLen(const ValkeyModuleString *str, size_t *len) { if (len) *len = strlen(errmsg); return errmsg; } - if (len) *len = sdslen(str->ptr); - return str->ptr; + if (len) *len = sdslen(objectGetVal(str)); + return objectGetVal(str); } /* -------------------------------------------------------------------------- @@ -2990,7 +2990,7 @@ const char *VM_StringPtrLen(const ValkeyModuleString *str, size_t *len) { * as a valid, strict `long long` (no spaces before/after), VALKEYMODULE_ERR * is returned. */ int VM_StringToLongLong(const ValkeyModuleString *str, long long *ll) { - return string2ll(str->ptr, sdslen(str->ptr), ll) ? VALKEYMODULE_OK : VALKEYMODULE_ERR; + return string2ll(objectGetVal(str), sdslen(objectGetVal(str)), ll) ? VALKEYMODULE_OK : VALKEYMODULE_ERR; } /* Convert the string into a `unsigned long long` integer, storing it at `*ull`. @@ -2998,7 +2998,7 @@ int VM_StringToLongLong(const ValkeyModuleString *str, long long *ll) { * as a valid, strict `unsigned long long` (no spaces before/after), VALKEYMODULE_ERR * is returned. */ int VM_StringToULongLong(const ValkeyModuleString *str, unsigned long long *ull) { - return string2ull(str->ptr, sdslen(str->ptr), ull) ? VALKEYMODULE_OK : VALKEYMODULE_ERR; + return string2ull(objectGetVal(str), sdslen(objectGetVal(str)), ull) ? VALKEYMODULE_OK : VALKEYMODULE_ERR; } /* Convert the string into a double, storing it at `*d`. @@ -3013,7 +3013,7 @@ int VM_StringToDouble(const ValkeyModuleString *str, double *d) { * Returns VALKEYMODULE_OK on success or VALKEYMODULE_ERR if the string is * not a valid string representation of a double value. */ int VM_StringToLongDouble(const ValkeyModuleString *str, long double *ld) { - int retval = string2ld(str->ptr, sdslen(str->ptr), ld); + int retval = string2ld(objectGetVal(str), sdslen(objectGetVal(str)), ld); return retval ? VALKEYMODULE_OK : VALKEYMODULE_ERR; } @@ -3042,7 +3042,7 @@ int VM_StringCompare(const ValkeyModuleString *a, const ValkeyModuleString *b) { /* Return the (possibly modified in encoding) input 'str' object if * the string is unshared, otherwise NULL is returned. */ -ValkeyModuleString *moduleAssertUnsharedString(ValkeyModuleString *str) { +static ValkeyModuleString *moduleAssertUnsharedString(ValkeyModuleString *str) { if (str->refcount != 1) { serverLog(LL_WARNING, "Module attempted to use an in-place string modify operation " "with a string referenced multiple times. Please check the code " @@ -3052,11 +3052,10 @@ ValkeyModuleString *moduleAssertUnsharedString(ValkeyModuleString *str) { if (str->encoding == OBJ_ENCODING_EMBSTR) { /* Note: here we "leak" the additional allocation that was * used in order to store the embedded string in the object. */ - str->ptr = sdsnewlen(str->ptr, sdslen(str->ptr)); - str->encoding = OBJ_ENCODING_RAW; + objectUnembedVal(str); } else if (str->encoding == OBJ_ENCODING_INT) { /* Convert the string from integer to raw encoding. */ - str->ptr = sdsfromlonglong((long)str->ptr); + objectSetVal(str, sdsfromlonglong((long)objectGetVal(str))); str->encoding = OBJ_ENCODING_RAW; } return str; @@ -3069,7 +3068,7 @@ int VM_StringAppendBuffer(ValkeyModuleCtx *ctx, ValkeyModuleString *str, const c UNUSED(ctx); str = moduleAssertUnsharedString(str); if (str == NULL) return VALKEYMODULE_ERR; - str->ptr = sdscatlen(str->ptr, buf, len); + objectSetVal(str, sdscatlen(objectGetVal(str), buf, len)); return VALKEYMODULE_OK; } @@ -4513,8 +4512,8 @@ char *VM_StringDMA(ValkeyModuleKey *key, size_t *len, int mode) { if ((mode & VALKEYMODULE_WRITE) || key->value->encoding != OBJ_ENCODING_RAW) key->value = dbUnshareStringValue(key->db, key->key, key->value); - *len = sdslen(key->value->ptr); - return key->value->ptr; + *len = sdslen(objectGetVal(key->value)); + return objectGetVal(key->value); } /* If the key is open for writing and is of string type, resize it, padding @@ -4546,14 +4545,14 @@ int VM_StringTruncate(ValkeyModuleKey *key, size_t newlen) { } else { /* Unshare and resize. */ key->value = dbUnshareStringValue(key->db, key->key, key->value); - size_t curlen = sdslen(key->value->ptr); + size_t curlen = sdslen(objectGetVal(key->value)); if (newlen > curlen) { - key->value->ptr = sdsgrowzero(key->value->ptr, newlen); + objectSetVal(key->value, sdsgrowzero(objectGetVal(key->value), newlen)); } else if (newlen < curlen) { - sdssubstr(key->value->ptr, 0, newlen); + sdssubstr(objectGetVal(key->value), 0, newlen); /* If the string is too wasteful, reallocate it. */ - if (sdslen(key->value->ptr) < sdsavail(key->value->ptr)) - key->value->ptr = sdsRemoveFreeSpace(key->value->ptr, 0); + if (sdslen(objectGetVal(key->value)) < sdsavail(objectGetVal(key->value))) + objectSetVal(key->value, sdsRemoveFreeSpace(objectGetVal(key->value), 0)); } } return VALKEYMODULE_OK; @@ -4915,7 +4914,7 @@ int VM_ZsetAdd(ValkeyModuleKey *key, double score, ValkeyModuleString *ele, int if (key->value && key->value->type != OBJ_ZSET) return VALKEYMODULE_ERR; if (key->value == NULL) moduleCreateEmptyKey(key, VALKEYMODULE_KEYTYPE_ZSET); if (flagsptr) in_flags = moduleZsetAddFlagsToCoreFlags(*flagsptr); - if (zsetAdd(key->value, score, ele->ptr, in_flags, &out_flags, NULL) == 0) { + if (zsetAdd(key->value, score, objectGetVal(ele), in_flags, &out_flags, NULL) == 0) { if (flagsptr) *flagsptr = 0; moduleDelKeyIfEmpty(key); return VALKEYMODULE_ERR; @@ -4944,7 +4943,7 @@ int VM_ZsetIncrby(ValkeyModuleKey *key, double score, ValkeyModuleString *ele, i if (key->value == NULL) moduleCreateEmptyKey(key, VALKEYMODULE_KEYTYPE_ZSET); if (flagsptr) in_flags = moduleZsetAddFlagsToCoreFlags(*flagsptr); in_flags |= ZADD_IN_INCR; - if (zsetAdd(key->value, score, ele->ptr, in_flags, &out_flags, newscore) == 0) { + if (zsetAdd(key->value, score, objectGetVal(ele), in_flags, &out_flags, newscore) == 0) { if (flagsptr) *flagsptr = 0; moduleDelKeyIfEmpty(key); return VALKEYMODULE_ERR; @@ -4974,7 +4973,7 @@ int VM_ZsetIncrby(ValkeyModuleKey *key, double score, ValkeyModuleString *ele, i int VM_ZsetRem(ValkeyModuleKey *key, ValkeyModuleString *ele, int *deleted) { if (!(key->mode & VALKEYMODULE_WRITE)) return VALKEYMODULE_ERR; if (key->value && key->value->type != OBJ_ZSET) return VALKEYMODULE_ERR; - if (key->value != NULL && zsetDel(key->value, ele->ptr)) { + if (key->value != NULL && zsetDel(key->value, objectGetVal(ele))) { if (deleted) *deleted = 1; moduleDelKeyIfEmpty(key); } else { @@ -4994,7 +4993,7 @@ int VM_ZsetRem(ValkeyModuleKey *key, ValkeyModuleString *ele, int *deleted) { int VM_ZsetScore(ValkeyModuleKey *key, ValkeyModuleString *ele, double *score) { if (key->value == NULL) return VALKEYMODULE_ERR; if (key->value->type != OBJ_ZSET) return VALKEYMODULE_ERR; - if (zsetScore(key->value, ele->ptr, score) == C_ERR) return VALKEYMODULE_ERR; + if (zsetScore(key->value, objectGetVal(ele), score) == C_ERR) return VALKEYMODULE_ERR; return VALKEYMODULE_OK; } @@ -5047,9 +5046,9 @@ int zsetInitScoreRange(ValkeyModuleKey *key, double min, double max, int minex, zrs->maxex = maxex; if (key->value->encoding == OBJ_ENCODING_LISTPACK) { - key->u.zset.current = first ? zzlFirstInRange(key->value->ptr, zrs) : zzlLastInRange(key->value->ptr, zrs); + key->u.zset.current = first ? zzlFirstInRange(objectGetVal(key->value), zrs) : zzlLastInRange(objectGetVal(key->value), zrs); } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = key->value->ptr; + zset *zs = objectGetVal(key->value); zskiplist *zsl = zs->zsl; key->u.zset.current = first ? zslNthInRange(zsl, zrs, 0, NULL) : zslNthInRange(zsl, zrs, -1, NULL); } else { @@ -5110,9 +5109,9 @@ int zsetInitLexRange(ValkeyModuleKey *key, ValkeyModuleString *min, ValkeyModule if (key->value->encoding == OBJ_ENCODING_LISTPACK) { key->u.zset.current = - first ? zzlFirstInLexRange(key->value->ptr, zlrs) : zzlLastInLexRange(key->value->ptr, zlrs); + first ? zzlFirstInLexRange(objectGetVal(key->value), zlrs) : zzlLastInLexRange(objectGetVal(key->value), zlrs); } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = key->value->ptr; + zset *zs = objectGetVal(key->value); zskiplist *zsl = zs->zsl; key->u.zset.current = first ? zslNthInLexRange(zsl, zlrs, 0) : zslNthInLexRange(zsl, zlrs, -1); } else { @@ -5158,7 +5157,7 @@ ValkeyModuleString *VM_ZsetRangeCurrentElement(ValkeyModuleKey *key, double *sco eptr = key->u.zset.current; sds ele = lpGetObject(eptr); if (score) { - sptr = lpNext(key->value->ptr, eptr); + sptr = lpNext(objectGetVal(key->value), eptr); *score = zzlGetScore(sptr); } str = createObject(OBJ_STRING, ele); @@ -5182,7 +5181,7 @@ int VM_ZsetRangeNext(ValkeyModuleKey *key) { if (!key->u.zset.type || !key->u.zset.current) return 0; /* No active iterator. */ if (key->value->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = key->value->ptr; + unsigned char *zl = objectGetVal(key->value); unsigned char *eptr = key->u.zset.current; unsigned char *next; next = lpNext(zl, eptr); /* Skip element. */ @@ -5244,7 +5243,7 @@ int VM_ZsetRangePrev(ValkeyModuleKey *key) { if (!key->u.zset.type || !key->u.zset.current) return 0; /* No active iterator. */ if (key->value->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = key->value->ptr; + unsigned char *zl = objectGetVal(key->value); unsigned char *eptr = key->u.zset.current; unsigned char *prev; prev = lpPrev(zl, eptr); /* Go back to previous score. */ @@ -5403,7 +5402,7 @@ int VM_HashSet(ValkeyModuleKey *key, int flags, ...) { /* Handle XX and NX */ if (flags & (VALKEYMODULE_HASH_XX | VALKEYMODULE_HASH_NX)) { - int exists = hashTypeExists(key->value, field->ptr); + int exists = hashTypeExists(key->value, objectGetVal(field)); if (((flags & VALKEYMODULE_HASH_XX) && !exists) || ((flags & VALKEYMODULE_HASH_NX) && exists)) { if (flags & VALKEYMODULE_HASH_CFIELDS) decrRefCount(field); continue; @@ -5412,7 +5411,7 @@ int VM_HashSet(ValkeyModuleKey *key, int flags, ...) { /* Handle deletion if value is VALKEYMODULE_HASH_DELETE. */ if (value == VALKEYMODULE_HASH_DELETE) { - count += hashTypeDelete(key->value, field->ptr); + count += hashTypeDelete(key->value, objectGetVal(field)); if (flags & VALKEYMODULE_HASH_CFIELDS) decrRefCount(field); continue; } @@ -5425,13 +5424,13 @@ int VM_HashSet(ValkeyModuleKey *key, int flags, ...) { robj *argv[2] = {field, value}; hashTypeTryConversion(key->value, argv, 0, 1); - int updated = hashTypeSet(key->value, field->ptr, value->ptr, EXPIRY_NONE, low_flags); + int updated = hashTypeSet(key->value, objectGetVal(field), objectGetVal(value), EXPIRY_NONE, low_flags); count += (flags & VALKEYMODULE_HASH_COUNT_ALL) ? 1 : updated; /* If CFIELDS is active, SDS string ownership is now of hashTypeSet(), * however we still have to release the 'field' object shell. */ if (flags & VALKEYMODULE_HASH_CFIELDS) { - field->ptr = NULL; /* Prevent the SDS string from being freed. */ + objectSetVal(field, NULL); /* Prevent the SDS string from being freed. */ decrRefCount(field); } } @@ -5505,13 +5504,13 @@ int VM_HashGet(ValkeyModuleKey *key, int flags, ...) { if (flags & VALKEYMODULE_HASH_EXISTS) { existsptr = va_arg(ap, int *); if (key->value) - *existsptr = hashTypeExists(key->value, field->ptr); + *existsptr = hashTypeExists(key->value, objectGetVal(field)); else *existsptr = 0; } else { valueptr = va_arg(ap, ValkeyModuleString **); if (key->value) { - *valueptr = hashTypeGetValueObject(key->value, field->ptr); + *valueptr = hashTypeGetValueObject(key->value, objectGetVal(field)); if (*valueptr) { robj *decoded = getDecodedObject(*valueptr); decrRefCount(*valueptr); @@ -5596,7 +5595,7 @@ int VM_StreamAdd(ValkeyModuleKey *key, int flags, ValkeyModuleStreamID *id, Valk created = 1; } - stream *s = key->value->ptr; + stream *s = objectGetVal(key->value); if (s->last_id.ms == UINT64_MAX && s->last_id.seq == UINT64_MAX) { /* The stream has reached the last possible ID */ errno = EFBIG; @@ -5660,7 +5659,7 @@ int VM_StreamDelete(ValkeyModuleKey *key, ValkeyModuleStreamID *id) { errno = EBADF; /* key not opened for writing or iterator started */ return VALKEYMODULE_ERR; } - stream *s = key->value->ptr; + stream *s = objectGetVal(key->value); streamID streamid = {id->ms, id->seq}; if (streamDeleteItem(s, &streamid)) { return VALKEYMODULE_OK; @@ -5744,7 +5743,7 @@ int VM_StreamIteratorStart(ValkeyModuleKey *key, int flags, ValkeyModuleStreamID } /* create iterator */ - stream *s = key->value->ptr; + stream *s = objectGetVal(key->value); int rev = flags & VALKEYMODULE_STREAM_ITERATOR_REVERSE; streamIterator *si = zmalloc(sizeof(*si)); streamIteratorStart(si, s, start ? &lower : NULL, end ? &upper : NULL, rev); @@ -5957,7 +5956,7 @@ long long VM_StreamTrimByLength(ValkeyModuleKey *key, int flags, long long lengt return -1; } int approx = flags & VALKEYMODULE_STREAM_TRIM_APPROX ? 1 : 0; - return streamTrimByLength((stream *)key->value->ptr, length, approx); + return streamTrimByLength((stream *)objectGetVal(key->value), length, approx); } /* Trim a stream by ID, similar to XTRIM with MINID. @@ -5988,7 +5987,7 @@ long long VM_StreamTrimByID(ValkeyModuleKey *key, int flags, ValkeyModuleStreamI } int approx = flags & VALKEYMODULE_STREAM_TRIM_APPROX ? 1 : 0; streamID minid = (streamID){id->ms, id->seq}; - return streamTrimByID((stream *)key->value->ptr, minid, approx); + return streamTrimByID((stream *)objectGetVal(key->value), minid, approx); } /* -------------------------------------------------------------------------- @@ -6240,7 +6239,7 @@ robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int } else if (*p == 's') { robj *obj = va_arg(ap, void *); if (obj->refcount == OBJ_STATIC_REFCOUNT) - obj = createStringObject(obj->ptr, sdslen(obj->ptr)); + obj = createStringObject(objectGetVal(obj), sdslen(objectGetVal(obj))); else incrRefCount(obj); argv[argc++] = obj; @@ -6541,7 +6540,7 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const if (oom_state) { errno = ENOSPC; if (error_as_call_replies) { - reply_error_msg = sdsdup(shared.oomerr->ptr); + reply_error_msg = sdsdup(objectGetVal(shared.oomerr)); } goto cleanup; } @@ -6577,11 +6576,11 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const acl_retval = ACLCheckAllUserCommandPerm(user, c->cmd, c->argv, c->argc, &acl_errpos); if (acl_retval != ACL_OK) { int context = scriptIsRunning() ? ACL_LOG_CTX_SCRIPT : ACL_LOG_CTX_MODULE; - sds object = (acl_retval == ACL_DENIED_CMD) ? sdsdup(c->cmd->fullname) : sdsdup(c->argv[acl_errpos]->ptr); + sds object = (acl_retval == ACL_DENIED_CMD) ? sdsdup(c->cmd->fullname) : sdsdup(objectGetVal(c->argv[acl_errpos])); addACLLogEntry(ctx->client, acl_retval, context, -1, c->user->name, object); if (error_as_call_replies) { /* verbosity should be same as processCommand() in server.c */ - sds acl_msg = getAclErrorMessage(acl_retval, c->user, c->cmd, c->argv[acl_errpos]->ptr, 0); + sds acl_msg = getAclErrorMessage(acl_retval, c->user, c->cmd, objectGetVal(c->argv[acl_errpos]), 0); reply_error_msg = sdscatfmt(sdsempty(), "-NOPERM %S\r\n", acl_msg); sdsfree(acl_msg); } @@ -6647,7 +6646,7 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const if (!checkGoodReplicasStatus()) { errno = ESPIPE; if (error_as_call_replies) { - reply_error_msg = sdsdup(shared.noreplicaserr->ptr); + reply_error_msg = sdsdup(objectGetVal(shared.noreplicaserr)); } goto cleanup; } @@ -6666,7 +6665,7 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const if (server.primary_host && server.repl_replica_ro && !obey_client) { errno = ESPIPE; if (error_as_call_replies) { - reply_error_msg = sdsdup(shared.roreplicaerr->ptr); + reply_error_msg = sdsdup(objectGetVal(shared.roreplicaerr)); } goto cleanup; } @@ -6683,7 +6682,7 @@ ValkeyModuleCallReply *VM_Call(ValkeyModuleCtx *ctx, const char *cmdname, const if (is_running_script) { reply_error_msg = sdsnew("Can not execute the command on a stale replica"); } else { - reply_error_msg = sdsdup(shared.primarydownerr->ptr); + reply_error_msg = sdsdup(objectGetVal(shared.primarydownerr)); } } goto cleanup; @@ -6958,7 +6957,7 @@ const char *moduleNameFromCommand(struct serverCommand *cmd) { * or not supported, produce an error reply and return NULL. */ robj *moduleTypeDupOrReply(client *c, robj *fromkey, robj *tokey, int todb, robj *value) { - moduleValue *mv = value->ptr; + moduleValue *mv = objectGetVal(value); moduleType *mt = mv->type; if (!mt->copy && !mt->copy2) { addReplyError(c, "not supported for this module key"); @@ -7193,7 +7192,7 @@ int VM_ModuleTypeSetValue(ValkeyModuleKey *key, moduleType *mt, void *value) { * then NULL is returned instead. */ moduleType *VM_ModuleTypeGetType(ValkeyModuleKey *key) { if (key == NULL || key->value == NULL || VM_KeyType(key) != VALKEYMODULE_KEYTYPE_MODULE) return NULL; - moduleValue *mv = key->value->ptr; + moduleValue *mv = objectGetVal(key->value); return mv->type; } @@ -7205,7 +7204,7 @@ moduleType *VM_ModuleTypeGetType(ValkeyModuleKey *key) { * then NULL is returned instead. */ void *VM_ModuleTypeGetValue(ValkeyModuleKey *key) { if (key == NULL || key->value == NULL || VM_KeyType(key) != VALKEYMODULE_KEYTYPE_MODULE) return NULL; - moduleValue *mv = key->value->ptr; + moduleValue *mv = objectGetVal(key->value); return mv->value; } @@ -7226,7 +7225,7 @@ void moduleRDBLoadError(ValkeyModuleIO *io) { "after reading '%llu' bytes of a value " "for key named: '%s'.", io->type->module->name, io->type->name, (unsigned long long)io->bytes, - io->key ? (server.hide_user_data_from_log ? "*redacted*" : (char *)io->key->ptr) : "(null)"); + io->key ? (server.hide_user_data_from_log ? "*redacted*" : (char *)objectGetVal(io->key)) : "(null)"); } /* Returns 0 if there's at least one registered data type that did not declare @@ -7646,7 +7645,7 @@ void *VM_LoadDataTypeFromStringEncver(const ValkeyModuleString *str, const modul ValkeyModuleIO io; void *ret; - rioInitWithBuffer(&payload, str->ptr); + rioInitWithBuffer(&payload, objectGetVal(str)); moduleInitIOContext(&io, (moduleType *)mt, &payload, NULL, -1); /* All VM_Save*() calls always write a version 2 compatible format, so we @@ -8250,7 +8249,7 @@ int checkModuleAuthentication(client *c, robj *username, robj *password, robj ** const char *module_name = auth_ctx ? auth_ctx->module->name : NULL; moduleFireAuthenticationEvent(c->id, - username->ptr, + objectGetVal(username), module_name, auth_result == AUTH_OK); @@ -9474,7 +9473,7 @@ void VM_SetClusterFlags(ValkeyModuleCtx *ctx, uint64_t flags) { /* Returns the cluster slot of a key, similar to the `CLUSTER KEYSLOT` command. * This function works even if cluster mode is not enabled. */ unsigned int VM_ClusterKeySlot(ValkeyModuleString *key) { - return keyHashSlot(key->ptr, sdslen(key->ptr)); + return keyHashSlot(objectGetVal(key), sdslen(objectGetVal(key))); } /* Returns a short string that can be used as a key or as a hash tag in a key, @@ -10056,7 +10055,7 @@ ValkeyModuleString *VM_GetCurrentUserName(ValkeyModuleCtx *ctx) { * The caller should later free the user using the function VM_FreeModuleUser().*/ ValkeyModuleUser *VM_GetModuleUserFromUserName(ValkeyModuleString *name) { /* First, verify that the user exist */ - user *acl_user = ACLGetUserByName(name->ptr, sdslen(name->ptr)); + user *acl_user = ACLGetUserByName(objectGetVal(name), sdslen(objectGetVal(name))); if (acl_user == NULL) { return NULL; } @@ -10118,7 +10117,7 @@ int VM_ACLCheckKeyPermissions(ValkeyModuleUser *user, ValkeyModuleString *key, i } int keyspec_flags = moduleConvertKeySpecsFlags(flags, 0); - if (ACLUserCheckKeyPerm(user->user, key->ptr, sdslen(key->ptr), keyspec_flags, false) != ACL_OK) { + if (ACLUserCheckKeyPerm(user->user, objectGetVal(key), sdslen(objectGetVal(key)), keyspec_flags, false) != ACL_OK) { errno = EACCES; return VALKEYMODULE_ERR; } @@ -10151,7 +10150,7 @@ int VM_ACLCheckChannelPermissions(ValkeyModuleUser *user, ValkeyModuleString *ch } int is_pattern = flags & VALKEYMODULE_CMD_CHANNEL_PATTERN; - if (ACLUserCheckChannelPerm(user->user, ch->ptr, is_pattern) != ACL_OK) return VALKEYMODULE_ERR; + if (ACLUserCheckChannelPerm(user->user, objectGetVal(ch), is_pattern) != ACL_OK) return VALKEYMODULE_ERR; return VALKEYMODULE_OK; } @@ -10179,7 +10178,7 @@ int VM_ACLAddLogEntry(ValkeyModuleCtx *ctx, ValkeyModuleACLLogEntryReason reason) { int acl_reason = moduleGetACLLogEntryReason(reason); if (!acl_reason) return VALKEYMODULE_ERR; - addACLLogEntry(ctx->client, acl_reason, ACL_LOG_CTX_MODULE, -1, user->user->name, sdsdup(object->ptr)); + addACLLogEntry(ctx->client, acl_reason, ACL_LOG_CTX_MODULE, -1, user->user->name, sdsdup(objectGetVal(object))); return VALKEYMODULE_OK; } @@ -10193,7 +10192,7 @@ int VM_ACLAddLogEntryByUserName(ValkeyModuleCtx *ctx, ValkeyModuleACLLogEntryReason reason) { int acl_reason = moduleGetACLLogEntryReason(reason); if (!acl_reason) return VALKEYMODULE_ERR; - addACLLogEntry(ctx->client, acl_reason, ACL_LOG_CTX_MODULE, -1, username->ptr, sdsdup(object->ptr)); + addACLLogEntry(ctx->client, acl_reason, ACL_LOG_CTX_MODULE, -1, objectGetVal(username), sdsdup(objectGetVal(object))); return VALKEYMODULE_OK; } @@ -10411,12 +10410,12 @@ int VM_DictReplaceC(ValkeyModuleDict *d, void *key, size_t keylen, void *ptr) { /* Like ValkeyModule_DictSetC() but takes the key as a ValkeyModuleString. */ int VM_DictSet(ValkeyModuleDict *d, ValkeyModuleString *key, void *ptr) { - return VM_DictSetC(d, key->ptr, sdslen(key->ptr), ptr); + return VM_DictSetC(d, objectGetVal(key), sdslen(objectGetVal(key)), ptr); } /* Like ValkeyModule_DictReplaceC() but takes the key as a ValkeyModuleString. */ int VM_DictReplace(ValkeyModuleDict *d, ValkeyModuleString *key, void *ptr) { - return VM_DictReplaceC(d, key->ptr, sdslen(key->ptr), ptr); + return VM_DictReplaceC(d, objectGetVal(key), sdslen(objectGetVal(key)), ptr); } /* Return the value stored at the specified key. The function returns NULL @@ -10433,7 +10432,7 @@ void *VM_DictGetC(ValkeyModuleDict *d, void *key, size_t keylen, int *nokey) { /* Like ValkeyModule_DictGetC() but takes the key as a ValkeyModuleString. */ void *VM_DictGet(ValkeyModuleDict *d, ValkeyModuleString *key, int *nokey) { - return VM_DictGetC(d, key->ptr, sdslen(key->ptr), nokey); + return VM_DictGetC(d, objectGetVal(key), sdslen(objectGetVal(key)), nokey); } /* Remove the specified key from the dictionary, returning VALKEYMODULE_OK if @@ -10450,7 +10449,7 @@ int VM_DictDelC(ValkeyModuleDict *d, void *key, size_t keylen, void *oldval) { /* Like ValkeyModule_DictDelC() but gets the key as a ValkeyModuleString. */ int VM_DictDel(ValkeyModuleDict *d, ValkeyModuleString *key, void *oldval) { - return VM_DictDelC(d, key->ptr, sdslen(key->ptr), oldval); + return VM_DictDelC(d, objectGetVal(key), sdslen(objectGetVal(key)), oldval); } /* Return an iterator, setup in order to start iterating from the specified @@ -10484,7 +10483,7 @@ ValkeyModuleDictIter *VM_DictIteratorStartC(ValkeyModuleDict *d, const char *op, /* Exactly like ValkeyModule_DictIteratorStartC, but the key is passed as a * ValkeyModuleString. */ ValkeyModuleDictIter *VM_DictIteratorStart(ValkeyModuleDict *d, const char *op, ValkeyModuleString *key) { - return VM_DictIteratorStartC(d, op, key->ptr, sdslen(key->ptr)); + return VM_DictIteratorStartC(d, op, objectGetVal(key), sdslen(objectGetVal(key))); } /* Release the iterator created with ValkeyModule_DictIteratorStart(). This call @@ -10508,7 +10507,7 @@ int VM_DictIteratorReseekC(ValkeyModuleDictIter *di, const char *op, void *key, /* Like ValkeyModule_DictIteratorReseekC() but takes the key as a * ValkeyModuleString. */ int VM_DictIteratorReseek(ValkeyModuleDictIter *di, const char *op, ValkeyModuleString *key) { - return VM_DictIteratorReseekC(di, op, key->ptr, sdslen(key->ptr)); + return VM_DictIteratorReseekC(di, op, objectGetVal(key), sdslen(objectGetVal(key))); } /* Return the current item of the dictionary iterator `di` and steps to the @@ -10599,7 +10598,7 @@ int VM_DictCompareC(ValkeyModuleDictIter *di, const char *op, void *key, size_t * iterator key as a ValkeyModuleString. */ int VM_DictCompare(ValkeyModuleDictIter *di, const char *op, ValkeyModuleString *key) { if (raxEOF(&di->ri)) return VALKEYMODULE_ERR; - int res = raxCompare(&di->ri, op, key->ptr, sdslen(key->ptr)); + int res = raxCompare(&di->ri, op, objectGetVal(key), sdslen(objectGetVal(key))); return res ? VALKEYMODULE_OK : VALKEYMODULE_ERR; } @@ -10673,10 +10672,10 @@ int VM_InfoEndDictField(ValkeyModuleInfoCtx *ctx) { int VM_InfoAddFieldString(ValkeyModuleInfoCtx *ctx, const char *field, ValkeyModuleString *value) { if (!ctx->in_section) return VALKEYMODULE_ERR; if (ctx->in_dict_field) { - ctx->info = sdscatfmt(ctx->info, "%s=%S,", field, (sds)value->ptr); + ctx->info = sdscatfmt(ctx->info, "%s=%S,", field, (sds)objectGetVal(value)); return VALKEYMODULE_OK; } - ctx->info = sdscatfmt(ctx->info, "%s_%s:%S\r\n", ctx->module->name, field, (sds)value->ptr); + ctx->info = sdscatfmt(ctx->info, "%s_%s:%S\r\n", ctx->module->name, field, (sds)objectGetVal(value)); return VALKEYMODULE_OK; } @@ -11491,11 +11490,11 @@ int VM_ScanKey(ValkeyModuleKey *key, ValkeyModuleScanCursor *cursor, ValkeyModul hashtable *ht = NULL; robj *o = key->value; if (o->type == OBJ_SET) { - if (o->encoding == OBJ_ENCODING_HASHTABLE) ht = o->ptr; + if (o->encoding == OBJ_ENCODING_HASHTABLE) ht = objectGetVal(o); } else if (o->type == OBJ_HASH) { - if (o->encoding == OBJ_ENCODING_HASHTABLE) ht = o->ptr; + if (o->encoding == OBJ_ENCODING_HASHTABLE) ht = objectGetVal(o); } else if (o->type == OBJ_ZSET) { - if (o->encoding == OBJ_ENCODING_SKIPLIST) ht = ((zset *)o->ptr)->ht; + if (o->encoding == OBJ_ENCODING_SKIPLIST) ht = ((zset *)objectGetVal(o))->ht; } else { errno = EINVAL; return 0; @@ -11525,7 +11524,7 @@ int VM_ScanKey(ValkeyModuleKey *key, ValkeyModuleScanCursor *cursor, ValkeyModul cursor->done = 1; ret = 0; } else if (o->type == OBJ_ZSET || o->type == OBJ_HASH) { - unsigned char *p = lpSeek(o->ptr, 0); + unsigned char *p = lpSeek(objectGetVal(o), 0); unsigned char *vstr; unsigned int vlen; long long vll; @@ -11533,12 +11532,12 @@ int VM_ScanKey(ValkeyModuleKey *key, ValkeyModuleScanCursor *cursor, ValkeyModul vstr = lpGetValue(p, &vlen, &vll); robj *field = (vstr != NULL) ? createStringObject((char *)vstr, vlen) : createStringObjectFromLongLongWithSds(vll); - p = lpNext(o->ptr, p); + p = lpNext(objectGetVal(o), p); vstr = lpGetValue(p, &vlen, &vll); robj *value = (vstr != NULL) ? createStringObject((char *)vstr, vlen) : createStringObjectFromLongLongWithSds(vll); fn(key, field, value, privdata); - p = lpNext(o->ptr, p); + p = lpNext(objectGetVal(o), p); decrRefCount(field); decrRefCount(value); } @@ -12231,7 +12230,7 @@ void moduleNotifyKeyUnlink(robj *key, robj *val, int dbid, int flags) { moduleFireServerEvent(VALKEYMODULE_EVENT_KEY, subevent, &info); if (val->type == OBJ_MODULE) { - moduleValue *mv = val->ptr; + moduleValue *mv = objectGetVal(val); moduleType *mt = mv->type; /* We prefer to use the enhanced version. */ if (mt->unlink2 != NULL) { @@ -12248,7 +12247,7 @@ void moduleNotifyKeyUnlink(robj *key, robj *val, int dbid, int flags) { * `free_effort` or `free_effort2`, and the default return value is 1. * value of 0 means very high effort (always asynchronous freeing). */ size_t moduleGetFreeEffort(robj *key, robj *val, int dbid) { - moduleValue *mv = val->ptr; + moduleValue *mv = objectGetVal(val); moduleType *mt = mv->type; size_t effort = 1; /* We prefer to use the enhanced version. */ @@ -12265,7 +12264,7 @@ size_t moduleGetFreeEffort(robj *key, robj *val, int dbid) { /* Return the memory usage of the module, it will automatically choose to call * `mem_usage` or `mem_usage2`, and the default return value is 0. */ size_t moduleGetMemUsage(robj *key, robj *val, size_t sample_size, int dbid) { - moduleValue *mv = val->ptr; + moduleValue *mv = objectGetVal(val); moduleType *mt = mv->type; size_t size = 0; /* We prefer to use the enhanced version. */ @@ -12582,14 +12581,14 @@ int parseLoadexArguments(ValkeyModuleString ***module_argv, int *module_argc) { ValkeyModuleString **argv = *module_argv; int argc = *module_argc; for (int i = 0; i < argc; i++) { - char *arg_val = argv[i]->ptr; + char *arg_val = objectGetVal(argv[i]); if (!strcasecmp(arg_val, "CONFIG")) { if (i + 2 >= argc) { serverLog(LL_NOTICE, "CONFIG specified without name value pair"); return VALKEYMODULE_ERR; } - sds name = sdsdup(argv[i + 1]->ptr); - sds value = sdsdup(argv[i + 2]->ptr); + sds name = sdsdup(objectGetVal(argv[i + 1])); + sds value = sdsdup(objectGetVal(argv[i + 2])); if (!dictReplace(server.module_configs_queue, name, value)) sdsfree(name); i += 2; } else if (!strcasecmp(arg_val, "ARGS")) { @@ -12975,7 +12974,7 @@ int moduleVerifyResourceName(const char *name) { static char configerr[CONFIG_ERR_SIZE]; static void propagateErrorString(ValkeyModuleString *err_in, const char **err) { if (err_in) { - valkey_strlcpy(configerr, err_in->ptr, CONFIG_ERR_SIZE); + valkey_strlcpy(configerr, objectGetVal(err_in), CONFIG_ERR_SIZE); decrRefCount(err_in); *err = configerr; } @@ -13019,7 +13018,7 @@ int getModuleBoolConfig(ModuleConfig *module_config) { sds getModuleStringConfig(ModuleConfig *module_config) { ValkeyModuleString *val = module_config->get_fn.get_string(module_config->name, module_config->privdata); - return val ? sdsdup(val->ptr) : NULL; + return val ? sdsdup(objectGetVal(val)) : NULL; } int getModuleEnumConfig(ModuleConfig *module_config) { @@ -13663,7 +13662,7 @@ void VM_ScriptingEngineDebuggerProcessCommands(int *client_disconnected, * MODULE UNLOAD */ void moduleCommand(client *c) { - char *subcmd = c->argv[1]->ptr; + char *subcmd = objectGetVal(c->argv[1]); if (c->argc == 2 && !strcasecmp(subcmd, "help")) { const char *help[] = { @@ -13686,7 +13685,7 @@ void moduleCommand(client *c) { argv = &c->argv[3]; } - if (moduleLoad(c->argv[2]->ptr, (void **)argv, argc, 0) == C_OK) + if (moduleLoad(objectGetVal(c->argv[2]), (void **)argv, argc, 0) == C_OK) addReply(c, shared.ok); else addReplyError(c, "Error loading the extension. Please check the server logs."); @@ -13701,7 +13700,7 @@ void moduleCommand(client *c) { /* If this is a loadex command we want to populate server.module_configs_queue with * sds NAME VALUE pairs. We also want to increment argv to just after ARGS, if supplied. */ if (parseLoadexArguments((ValkeyModuleString ***)&argv, &argc) == VALKEYMODULE_OK && - moduleLoad(c->argv[2]->ptr, (void **)argv, argc, 1) == C_OK) + moduleLoad(objectGetVal(c->argv[2]), (void **)argv, argc, 1) == C_OK) addReply(c, shared.ok); else { dictEmpty(server.module_configs_queue, NULL); @@ -13710,12 +13709,12 @@ void moduleCommand(client *c) { } else if (!strcasecmp(subcmd, "unload") && c->argc == 3) { const char *errmsg = NULL; - if (moduleUnload(c->argv[2]->ptr, &errmsg) == C_OK) + if (moduleUnload(objectGetVal(c->argv[2]), &errmsg) == C_OK) addReply(c, shared.ok); else { if (errmsg == NULL) errmsg = "operation not possible."; addReplyErrorFormat(c, "Error unloading module: %s", errmsg); - serverLog(LL_WARNING, "Error unloading module %s: %s", (sds)c->argv[2]->ptr, errmsg); + serverLog(LL_WARNING, "Error unloading module %s: %s", (sds)objectGetVal(c->argv[2]), errmsg); } } else if (!strcasecmp(subcmd, "list") && c->argc == 2) { addReplyLoadedModules(c); @@ -13869,7 +13868,7 @@ int VM_ModuleTypeReplaceValue(ValkeyModuleKey *key, moduleType *mt, void *new_va if (!(key->mode & VALKEYMODULE_WRITE) || key->iter) return VALKEYMODULE_ERR; if (!key->value || key->value->type != OBJ_MODULE) return VALKEYMODULE_ERR; - moduleValue *mv = key->value->ptr; + moduleValue *mv = objectGetVal(key->value); if (mv->type != mt) return VALKEYMODULE_ERR; if (old_value) *old_value = mv->value; @@ -14079,7 +14078,7 @@ ValkeyModuleString *VM_DefragValkeyModuleString(ValkeyModuleDefragCtx *ctx, Valk * or a non-zero value otherwise. */ int moduleLateDefrag(robj *key, robj *value, unsigned long *cursor, monotime endtime, int dbid) { - moduleValue *mv = value->ptr; + moduleValue *mv = objectGetVal(value); moduleType *mt = mv->type; ValkeyModuleDefragCtx defrag_ctx = {endtime, cursor, key, dbid}; @@ -14105,7 +14104,7 @@ int moduleLateDefrag(robj *key, robj *value, unsigned long *cursor, monotime end * be scheduled for late defrag. */ int moduleDefragValue(robj *key, robj *value, int dbid) { - moduleValue *mv = value->ptr; + moduleValue *mv = objectGetVal(value); moduleType *mt = mv->type; /* Try to defrag moduleValue itself regardless of whether or not @@ -14113,7 +14112,8 @@ int moduleDefragValue(robj *key, robj *value, int dbid) { */ moduleValue *newmv = activeDefragAlloc(mv); if (newmv) { - value->ptr = mv = newmv; + objectSetVal(value, newmv); + mv = newmv; } if (!mt->defrag) return 1; diff --git a/src/multi.c b/src/multi.c index c859368c6..77c52cb33 100644 --- a/src/multi.c +++ b/src/multi.c @@ -406,7 +406,7 @@ void touchWatchedKey(serverDb *db, robj *key) { if (wk->expired) { /* The key was already expired when WATCH was called. */ - if (db == wk->db && equalStringObjects(key, wk->key) && dbFind(db, key->ptr) == NULL) { + if (db == wk->db && equalStringObjects(key, wk->key) && dbFind(db, objectGetVal(key)) == NULL) { /* Already expired key is deleted, so logically no change. Clear * the flag. Deleted keys are not flagged as expired. */ wk->expired = 0; @@ -444,15 +444,15 @@ void touchAllWatchedKeysInDb(serverDb *emptied, serverDb *replaced_with) { dictIterator *di = dictGetSafeIterator(emptied->watched_keys); while ((de = dictNext(di)) != NULL) { robj *key = dictGetKey(de); - int exists_in_emptied = dbFind(emptied, key->ptr) != NULL; - if (exists_in_emptied || (replaced_with && dbFind(replaced_with, key->ptr) != NULL)) { + int exists_in_emptied = dbFind(emptied, objectGetVal(key)) != NULL; + if (exists_in_emptied || (replaced_with && dbFind(replaced_with, objectGetVal(key)) != NULL)) { list *clients = dictGetVal(de); if (!clients) continue; listRewind(clients, &li); while ((ln = listNext(&li))) { watchedKey *wk = server_member2struct(watchedKey, node, ln); if (wk->expired) { - if (!replaced_with || !dbFind(replaced_with, key->ptr)) { + if (!replaced_with || !dbFind(replaced_with, objectGetVal(key))) { /* Expired key now deleted. No logical change. Clear the * flag. Deleted keys are not flagged as expired. */ wk->expired = 0; diff --git a/src/networking.c b/src/networking.c index b36a7e1e3..b8e24befa 100644 --- a/src/networking.c +++ b/src/networking.c @@ -164,7 +164,7 @@ typedef enum { size_t getStringObjectSdsUsedMemory(robj *o) { serverAssertWithInfo(NULL, o, o->type == OBJ_STRING); if (o->encoding != OBJ_ENCODING_INT) { - return sdsAllocSize(o->ptr); + return sdsAllocSize(objectGetVal(o)); } return 0; } @@ -174,8 +174,8 @@ size_t getStringObjectSdsUsedMemory(robj *o) { size_t getStringObjectLen(robj *o) { serverAssertWithInfo(NULL, o, o->type == OBJ_STRING); switch (o->encoding) { - case OBJ_ENCODING_RAW: return sdslen(o->ptr); - case OBJ_ENCODING_EMBSTR: return sdslen(o->ptr); + case OBJ_ENCODING_RAW: return sdslen(objectGetVal(o)); + case OBJ_ENCODING_EMBSTR: return sdslen(objectGetVal(o)); default: return 0; /* Just integer encoding for now. */ } } @@ -268,10 +268,10 @@ static int isCopyAvoidPreferred(client *c, robj *obj) { /* Main thread only. No I/O threads */ if (server.io_threads_num == 1) { /* Copy avoidance is preferred starting certain string size */ - return server.min_string_size_copy_avoid && sdslen(obj->ptr) >= (size_t)server.min_string_size_copy_avoid; + return server.min_string_size_copy_avoid && sdslen(objectGetVal(obj)) >= (size_t)server.min_string_size_copy_avoid; } /* Main thread + I/O threads */ - return server.min_string_size_copy_avoid_threaded && sdslen(obj->ptr) >= (size_t)server.min_string_size_copy_avoid_threaded; + return server.min_string_size_copy_avoid_threaded && sdslen(objectGetVal(obj)) >= (size_t)server.min_string_size_copy_avoid_threaded; } client *createClient(connection *conn) { @@ -720,7 +720,7 @@ static void _addBulkStrRefToBufferOrList(client *c, robj *obj) { /* Refcount will be decremented in write completion handler by the main thread */ incrRefCount(obj); - bulkStrRef str_ref = {.obj = obj, .str = obj->ptr}; + bulkStrRef str_ref = {.obj = obj, .str = objectGetVal(obj)}; if (!_addBulkStrRefToBuffer(c, (void *)&str_ref, sizeof(str_ref))) { _addBulkStrRefToToList(c, (void *)&str_ref, sizeof(str_ref)); } @@ -736,13 +736,13 @@ void addReply(client *c, robj *obj) { if (prepareClientToWrite(c) != C_OK) return; if (sdsEncodedObject(obj)) { - _addReplyToBufferOrList(c, obj->ptr, sdslen(obj->ptr)); + _addReplyToBufferOrList(c, objectGetVal(obj), sdslen(objectGetVal(obj))); } else if (obj->encoding == OBJ_ENCODING_INT) { /* For integer encoded strings we just convert it into a string * using our optimized function, and attach the resulting string * to the output buffer. */ char buf[32]; - size_t len = ll2string(buf, sizeof(buf), (long)obj->ptr); + size_t len = ll2string(buf, sizeof(buf), (long)objectGetVal(obj)); _addReplyToBufferOrList(c, buf, len); } else { serverPanic("Wrong obj->encoding in addReply()"); @@ -908,7 +908,7 @@ void afterErrorReply(client *c, const char *s, size_t len, int flags) { * Unlike addReplyErrorSds and others alike which rely on addReplyErrorLength. */ void addReplyErrorObject(client *c, robj *err) { addReply(c, err); - afterErrorReply(c, err->ptr, sdslen(err->ptr) - 2, 0); /* Ignore trailing \r\n */ + afterErrorReply(c, objectGetVal(err), sdslen(objectGetVal(err)) - 2, 0); /* Ignore trailing \r\n */ } /* Sends either a reply or an error reply by checking the first char. @@ -918,7 +918,7 @@ void addReplyErrorObject(client *c, robj *err) { * logging and stats update. */ void addReplyOrErrorObject(client *c, robj *reply) { serverAssert(sdsEncodedObject(reply)); - sds rep = reply->ptr; + sds rep = objectGetVal(reply); if (sdslen(rep) > 1 && rep[0] == '-') { addReplyErrorObject(c, reply); } else { @@ -1144,15 +1144,15 @@ void setDeferredAggregateLen(client *c, void *node, long length, char prefix) { const size_t hdr_len = OBJ_SHARED_HDR_STRLEN(length); const int opt_hdr = length < OBJ_SHARED_BULKHDR_LEN; if (prefix == '*' && opt_hdr) { - setDeferredReply(c, node, shared.mbulkhdr[length]->ptr, hdr_len); + setDeferredReply(c, node, objectGetVal(shared.mbulkhdr[length]), hdr_len); return; } if (prefix == '%' && opt_hdr) { - setDeferredReply(c, node, shared.maphdr[length]->ptr, hdr_len); + setDeferredReply(c, node, objectGetVal(shared.maphdr[length]), hdr_len); return; } if (prefix == '~' && opt_hdr) { - setDeferredReply(c, node, shared.sethdr[length]->ptr, hdr_len); + setDeferredReply(c, node, objectGetVal(shared.sethdr[length]), hdr_len); return; } @@ -1274,16 +1274,16 @@ static void _addReplyLongLongWithPrefix(client *c, long long ll, char prefix) { const int opt_hdr = ll < OBJ_SHARED_BULKHDR_LEN && ll >= 0; const size_t hdr_len = OBJ_SHARED_HDR_STRLEN(ll); if (prefix == '*' && opt_hdr) { - _addReplyToBufferOrList(c, shared.mbulkhdr[ll]->ptr, hdr_len); + _addReplyToBufferOrList(c, objectGetVal(shared.mbulkhdr[ll]), hdr_len); return; } else if (prefix == '$' && opt_hdr) { - _addReplyToBufferOrList(c, shared.bulkhdr[ll]->ptr, hdr_len); + _addReplyToBufferOrList(c, objectGetVal(shared.bulkhdr[ll]), hdr_len); return; } else if (prefix == '%' && opt_hdr) { - _addReplyToBufferOrList(c, shared.maphdr[ll]->ptr, hdr_len); + _addReplyToBufferOrList(c, objectGetVal(shared.maphdr[ll]), hdr_len); return; } else if (prefix == '~' && opt_hdr) { - _addReplyToBufferOrList(c, shared.sethdr[ll]->ptr, hdr_len); + _addReplyToBufferOrList(c, objectGetVal(shared.sethdr[ll]), hdr_len); return; } @@ -1401,7 +1401,7 @@ void addReplyBulk(client *c, robj *obj) { if (tryAvoidBulkStrCopyToReply(c, obj) == C_OK) { /* If copy avoidance allowed, then we explicitly maintain net_output_bytes_curr_cmd. */ serverAssert(obj->encoding == OBJ_ENCODING_RAW); - size_t str_len = sdslen(obj->ptr); + size_t str_len = sdslen(objectGetVal(obj)); uint32_t num_len = digits10(str_len); /* RESP encodes bulk strings as $\r\n\r\n */ c->net_output_bytes_curr_cmd += (num_len + 3); /* $\r\n */ @@ -1520,7 +1520,7 @@ void addReplyVerbatim(client *c, const char *s, size_t len, const char *ext) { * specific subcommands in `extended_help`. */ void addExtendedReplyHelp(client *c, const char **help, const char **extended_help) { - sds cmd = sdsnew((char *)c->argv[0]->ptr); + sds cmd = sdsnew((char *)objectGetVal(c->argv[0])); void *blenp = addReplyDeferredLen(c); int blen = 0; int idx = 0; @@ -1555,10 +1555,10 @@ void addReplyHelp(client *c, const char **help) { * This function is typically invoked by from commands that support * subcommands in response to an unknown subcommand or argument error. */ void addReplySubcommandSyntaxError(client *c) { - sds cmd = sdsnew((char *)c->argv[0]->ptr); + sds cmd = sdsnew((char *)objectGetVal(c->argv[0])); sdstoupper(cmd); addReplyErrorFormat(c, "unknown subcommand or wrong number of arguments for '%.128s'. Try %s HELP.", - (char *)c->argv[1]->ptr, cmd); + (char *)objectGetVal(c->argv[1]), cmd); sdsfree(cmd); } @@ -3927,14 +3927,14 @@ static int addKeysToIncrFindBatch(client *c, int kvstore_idx = 0; if (server.cluster_enabled) { robj *first_key = argv[result.keys[0].pos]; - kvstore_idx = keyHashSlot(first_key->ptr, sdslen(first_key->ptr)); + kvstore_idx = keyHashSlot(objectGetVal(first_key), sdslen(objectGetVal(first_key))); } hashtable *ht = kvstoreGetHashtable(c->db->keys, kvstore_idx); if (ht != NULL) { for (int i = 0; i < numkeys && num < max; i++) { hashtableIncrementalFindState *incr_state = &incr_states[num++]; robj *keyobj = argv[result.keys[i].pos]; - hashtableIncrementalFindInit(incr_state, ht, keyobj->ptr); + hashtableIncrementalFindInit(incr_state, ht, objectGetVal(keyobj)); } } } @@ -4003,7 +4003,7 @@ static void prefetchCommandQueueKeys(client *c) { /* TODO? Prefetch all types and encodings except OBJ_ENCODING_EMBSTR * and OBJ_ENCODING_INT. */ if (val->encoding == OBJ_ENCODING_RAW && val->type == OBJ_STRING) { - valkey_prefetch(val->ptr); + valkey_prefetch(objectGetVal(val)); } } } @@ -4290,7 +4290,7 @@ sds catClientInfoString(sds s, client *client, int hide_user_data) { " addr=%s", getClientPeerId(client), " laddr=%s", getClientSockname(client), " %s", connGetInfo(client->conn, conninfo, sizeof(conninfo)), - " name=%s", hide_user_data ? "*redacted*" : (client->name ? (char *)client->name->ptr : ""), + " name=%s", hide_user_data ? "*redacted*" : (client->name ? (char *)objectGetVal(client->name) : ""), " age=%I", (long long)(commandTimeSnapshot() / 1000 - client->ctime), " idle=%I", (long long)(server.unixtime - client->last_interaction), " flags=%s", flags, @@ -4316,8 +4316,8 @@ sds catClientInfoString(sds s, client *client, int hide_user_data) { " user=%s", hide_user_data ? "*redacted*" : (client->user ? client->user->name : "(superuser)"), " redir=%I", (client->flag.tracking) ? (long long)client->pubsub_data->client_tracking_redirection : -1, " resp=%i", client->resp, - " lib-name=%s", client->lib_name ? (char *)client->lib_name->ptr : "", - " lib-ver=%s", client->lib_ver ? (char *)client->lib_ver->ptr : "", + " lib-name=%s", client->lib_name ? (char *)objectGetVal(client->lib_name) : "", + " lib-ver=%s", client->lib_ver ? (char *)objectGetVal(client->lib_ver) : "", " tot-net-in=%U", client->net_input_bytes, " tot-net-out=%U", client->net_output_bytes, " tot-cmds=%U", client->commands_processed)); @@ -4340,10 +4340,10 @@ sds catClientInfoShortString(sds s, client *client, int hide_user_data) { " addr=%s", getClientPeerId(client), " laddr=%s", getClientSockname(client), " %s", connGetInfo(client->conn, conninfo, sizeof(conninfo)), - " name=%s", hide_user_data ? "*redacted*" : (client->name ? (char *)client->name->ptr : ""), + " name=%s", hide_user_data ? "*redacted*" : (client->name ? (char *)objectGetVal(client->name) : ""), " user=%s", hide_user_data ? "*redacted*" : (client->user ? client->user->name : "(superuser)"), - " lib-name=%s", client->lib_name ? (char *)client->lib_name->ptr : "", - " lib-ver=%s", client->lib_ver ? (char *)client->lib_ver->ptr : "")); + " lib-name=%s", client->lib_name ? (char *)objectGetVal(client->lib_name) : "", + " lib-ver=%s", client->lib_ver ? (char *)objectGetVal(client->lib_ver) : "")); return ret; } @@ -4396,10 +4396,10 @@ int validateClientAttr(const char *val) { /* Returns C_OK if the name is valid. Returns C_ERR & sets `err` (when provided) otherwise. */ int validateClientName(robj *name, const char **err) { const char *err_msg = "Client names cannot contain spaces, newlines or special characters."; - int len = (name != NULL) ? sdslen(name->ptr) : 0; + int len = (name != NULL) ? sdslen(objectGetVal(name)) : 0; /* We allow setting the client name to an empty string. */ if (len == 0) return C_OK; - if (validateClientAttr(name->ptr) == C_ERR) { + if (validateClientAttr(objectGetVal(name)) == C_ERR) { if (err) *err = err_msg; return C_ERR; } @@ -4411,7 +4411,7 @@ int clientSetName(client *c, robj *name, const char **err) { if (validateClientName(name, err) == C_ERR) { return C_ERR; } - int len = (name != NULL) ? sdslen(name->ptr) : 0; + int len = (name != NULL) ? sdslen(objectGetVal(name)) : 0; /* Setting the client name to an empty string actually removes * the current name. */ if (len == 0) { @@ -4445,9 +4445,9 @@ int clientSetNameOrReply(client *c, robj *name) { /* Set client or connection related info */ void clientSetinfoCommand(client *c) { - sds attr = c->argv[2]->ptr; + sds attr = objectGetVal(c->argv[2]); robj *valob = c->argv[3]; - sds val = valob->ptr; + sds val = objectGetVal(valob); robj **destvar = NULL; if (!strcasecmp(attr, "lib-name")) { destvar = &c->lib_name; @@ -4502,7 +4502,7 @@ static int parseClientFiltersOrReply(client *c, int index, clientFilter *filter) while (index < c->argc) { int moreargs = c->argc > index + 1; - if (!strcasecmp(c->argv[index]->ptr, "id")) { + if (!strcasecmp(objectGetVal(c->argv[index]), "id")) { if (filter->ids == NULL) { /* Initialize the intset for IDs */ filter->ids = intsetNew(); @@ -4512,7 +4512,7 @@ static int parseClientFiltersOrReply(client *c, int index, clientFilter *filter) /* Process all IDs until a non-numeric argument or end of args */ while (index < c->argc) { long long id; - if (!string2ll(c->argv[index]->ptr, sdslen(c->argv[index]->ptr), &id)) { + if (!string2ll(objectGetVal(c->argv[index]), sdslen(objectGetVal(c->argv[index])), &id)) { break; /* Stop processing IDs if a non-numeric argument is encountered */ } if (id < 1) { @@ -4524,7 +4524,7 @@ static int parseClientFiltersOrReply(client *c, int index, clientFilter *filter) filter->ids = intsetAdd(filter->ids, id, &added); index++; /* Move to the next argument */ } - } else if (!strcasecmp(c->argv[index]->ptr, "not-id")) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "not-id")) { if (filter->not_ids == NULL) { /* Initialize the intset for NOT-IDs */ filter->not_ids = intsetNew(); @@ -4534,7 +4534,7 @@ static int parseClientFiltersOrReply(client *c, int index, clientFilter *filter) /* Process all NOT-IDs until a non-numeric argument or end of args */ while (index < c->argc) { long long not_id; - if (!string2ll(c->argv[index]->ptr, sdslen(c->argv[index]->ptr), ¬_id)) { + if (!string2ll(objectGetVal(c->argv[index]), sdslen(objectGetVal(c->argv[index])), ¬_id)) { break; /* Stop processing NOT-IDs if a non-numeric argument is encountered */ } if (not_id < 1) { @@ -4546,7 +4546,7 @@ static int parseClientFiltersOrReply(client *c, int index, clientFilter *filter) filter->not_ids = intsetAdd(filter->not_ids, not_id, &added); index++; /* Move to the next argument */ } - } else if (!strcasecmp(c->argv[index]->ptr, "maxage") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "maxage") && moreargs) { long long maxage; if (getLongLongFromObjectOrReply(c, c->argv[index + 1], &maxage, @@ -4559,57 +4559,57 @@ static int parseClientFiltersOrReply(client *c, int index, clientFilter *filter) filter->max_age = maxage; index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "type") && moreargs) { - filter->type = getClientTypeByName(c->argv[index + 1]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[index]), "type") && moreargs) { + filter->type = getClientTypeByName(objectGetVal(c->argv[index + 1])); if (filter->type == -1) { - addReplyErrorFormat(c, "Unknown client type '%s'", (char *)c->argv[index + 1]->ptr); + addReplyErrorFormat(c, "Unknown client type '%s'", (char *)objectGetVal(c->argv[index + 1])); return C_ERR; } index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "not-type") && moreargs) { - filter->not_type = getClientTypeByName(c->argv[index + 1]->ptr); + } else if (!strcasecmp(objectGetVal(c->argv[index]), "not-type") && moreargs) { + filter->not_type = getClientTypeByName(objectGetVal(c->argv[index + 1])); if (filter->not_type == -1) { - addReplyErrorFormat(c, "Unknown client type '%s'", (char *)c->argv[index + 1]->ptr); + addReplyErrorFormat(c, "Unknown client type '%s'", (char *)objectGetVal(c->argv[index + 1])); return C_ERR; } index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "addr") && moreargs) { - filter->addr = c->argv[index + 1]->ptr; + } else if (!strcasecmp(objectGetVal(c->argv[index]), "addr") && moreargs) { + filter->addr = objectGetVal(c->argv[index + 1]); index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "not-addr") && moreargs) { - filter->not_addr = c->argv[index + 1]->ptr; + } else if (!strcasecmp(objectGetVal(c->argv[index]), "not-addr") && moreargs) { + filter->not_addr = objectGetVal(c->argv[index + 1]); index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "laddr") && moreargs) { - filter->laddr = c->argv[index + 1]->ptr; + } else if (!strcasecmp(objectGetVal(c->argv[index]), "laddr") && moreargs) { + filter->laddr = objectGetVal(c->argv[index + 1]); index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "not-laddr") && moreargs) { - filter->not_laddr = c->argv[index + 1]->ptr; + } else if (!strcasecmp(objectGetVal(c->argv[index]), "not-laddr") && moreargs) { + filter->not_laddr = objectGetVal(c->argv[index + 1]); index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "user") && moreargs) { - filter->user = ACLGetUserByName(c->argv[index + 1]->ptr, sdslen(c->argv[index + 1]->ptr)); + } else if (!strcasecmp(objectGetVal(c->argv[index]), "user") && moreargs) { + filter->user = ACLGetUserByName(objectGetVal(c->argv[index + 1]), sdslen(objectGetVal(c->argv[index + 1]))); if (filter->user == NULL) { - addReplyErrorFormat(c, "No such user '%s'", (char *)c->argv[index + 1]->ptr); + addReplyErrorFormat(c, "No such user '%s'", (char *)objectGetVal(c->argv[index + 1])); return C_ERR; } index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "not-user") && moreargs) { - filter->not_user = ACLGetUserByName(c->argv[index + 1]->ptr, sdslen(c->argv[index + 1]->ptr)); + } else if (!strcasecmp(objectGetVal(c->argv[index]), "not-user") && moreargs) { + filter->not_user = ACLGetUserByName(objectGetVal(c->argv[index + 1]), sdslen(objectGetVal(c->argv[index + 1]))); if (filter->not_user == NULL) { - addReplyErrorFormat(c, "No such user '%s'", (char *)c->argv[index + 1]->ptr); + addReplyErrorFormat(c, "No such user '%s'", (char *)objectGetVal(c->argv[index + 1])); return C_ERR; } index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "skipme") && moreargs) { - if (!strcasecmp(c->argv[index + 1]->ptr, "yes")) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "skipme") && moreargs) { + if (!strcasecmp(objectGetVal(c->argv[index + 1]), "yes")) { filter->skipme = 1; - } else if (!strcasecmp(c->argv[index + 1]->ptr, "no")) { + } else if (!strcasecmp(objectGetVal(c->argv[index + 1]), "no")) { filter->skipme = 0; } else { addReplyErrorObject(c, shared.syntaxerr); return C_ERR; } index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "idle") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "idle") && moreargs) { long long idle_time; if (getLongLongFromObjectOrReply(c, c->argv[index + 1], &idle_time, @@ -4622,35 +4622,35 @@ static int parseClientFiltersOrReply(client *c, int index, clientFilter *filter) filter->idle = idle_time; index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "flags") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "flags") && moreargs) { if (filter->flags) { sdsfree(filter->flags); filter->flags = NULL; } - filter->flags = sdsnew(c->argv[index + 1]->ptr); + filter->flags = sdsnew(objectGetVal(c->argv[index + 1])); if (validateClientFlagFilter(filter->flags) == C_ERR) { addReplyErrorFormat(c, "Unknown flags found in the provided filter: %s", filter->flags); return C_ERR; } index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "not-flags") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "not-flags") && moreargs) { if (filter->not_flags) { sdsfree(filter->not_flags); filter->not_flags = NULL; } - filter->not_flags = sdsnew(c->argv[index + 1]->ptr); + filter->not_flags = sdsnew(objectGetVal(c->argv[index + 1])); if (validateClientFlagFilter(filter->not_flags) == C_ERR) { addReplyErrorFormat(c, "Unknown flags found in the NOT-FLAGS filter: %s", filter->not_flags); return C_ERR; } index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "name") && moreargs) { - filter->name = c->argv[index + 1]->ptr; + } else if (!strcasecmp(objectGetVal(c->argv[index]), "name") && moreargs) { + filter->name = objectGetVal(c->argv[index + 1]); index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "not-name") && moreargs) { - filter->not_name = c->argv[index + 1]->ptr; + } else if (!strcasecmp(objectGetVal(c->argv[index]), "not-name") && moreargs) { + filter->not_name = objectGetVal(c->argv[index + 1]); index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "lib-name") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "lib-name") && moreargs) { if (filter->lib_name) { decrRefCount(filter->lib_name); filter->lib_name = NULL; @@ -4658,7 +4658,7 @@ static int parseClientFiltersOrReply(client *c, int index, clientFilter *filter) filter->lib_name = c->argv[index + 1]; incrRefCount(filter->lib_name); index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "not-lib-name") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "not-lib-name") && moreargs) { if (filter->not_lib_name) { decrRefCount(filter->not_lib_name); filter->not_lib_name = NULL; @@ -4666,7 +4666,7 @@ static int parseClientFiltersOrReply(client *c, int index, clientFilter *filter) filter->not_lib_name = c->argv[index + 1]; incrRefCount(filter->not_lib_name); index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "lib-ver") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "lib-ver") && moreargs) { if (filter->lib_ver) { decrRefCount(filter->lib_ver); filter->lib_ver = NULL; @@ -4674,7 +4674,7 @@ static int parseClientFiltersOrReply(client *c, int index, clientFilter *filter) filter->lib_ver = c->argv[index + 1]; incrRefCount(filter->lib_ver); index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "not-lib-ver") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "not-lib-ver") && moreargs) { if (filter->not_lib_ver) { decrRefCount(filter->not_lib_ver); filter->not_lib_ver = NULL; @@ -4682,7 +4682,7 @@ static int parseClientFiltersOrReply(client *c, int index, clientFilter *filter) filter->not_lib_ver = c->argv[index + 1]; incrRefCount(filter->not_lib_ver); index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "db") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "db") && moreargs) { int db_id; if (getIntFromObjectOrReply(c, c->argv[index + 1], &db_id, "DB is not an integer or out of range") != C_OK) @@ -4693,7 +4693,7 @@ static int parseClientFiltersOrReply(client *c, int index, clientFilter *filter) } filter->db_number = db_id; index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "not-db") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "not-db") && moreargs) { int not_db_id; if (getIntFromObjectOrReply(c, c->argv[index + 1], ¬_db_id, "NOT-DB is not an integer or out of range") != C_OK) @@ -4704,41 +4704,41 @@ static int parseClientFiltersOrReply(client *c, int index, clientFilter *filter) } filter->not_db_number = not_db_id; index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "capa") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "capa") && moreargs) { if (filter->capa) { sdsfree(filter->capa); filter->capa = NULL; } - filter->capa = sdsnew(c->argv[index + 1]->ptr); + filter->capa = sdsnew(objectGetVal(c->argv[index + 1])); if (validateClientCapaFilter(filter->capa) == C_ERR) { addReplyErrorFormat(c, "Unknown capa found in the provided filter: %s", filter->capa); return C_ERR; } index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "not-capa") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "not-capa") && moreargs) { if (filter->not_capa) { sdsfree(filter->not_capa); filter->not_capa = NULL; } - filter->not_capa = sdsnew(c->argv[index + 1]->ptr); + filter->not_capa = sdsnew(objectGetVal(c->argv[index + 1])); if (validateClientCapaFilter(filter->not_capa) == C_ERR) { addReplyErrorFormat(c, "Unknown capa found in the NOT-CAPA filter: %s", filter->not_capa); return C_ERR; } index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "ip") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "ip") && moreargs) { if (filter->ip) { sdsfree(filter->ip); filter->ip = NULL; } - filter->ip = sdsnew(c->argv[index + 1]->ptr); + filter->ip = sdsnew(objectGetVal(c->argv[index + 1])); index += 2; - } else if (!strcasecmp(c->argv[index]->ptr, "not-ip") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[index]), "not-ip") && moreargs) { if (filter->not_ip) { sdsfree(filter->not_ip); filter->not_ip = NULL; } - filter->not_ip = sdsnew(c->argv[index + 1]->ptr); + filter->not_ip = sdsnew(objectGetVal(c->argv[index + 1])); index += 2; } else { addReplyErrorObject(c, shared.syntaxerr); @@ -4809,7 +4809,7 @@ static int clientMatchesFilter(client *client, clientFilter *client_filter) { if (client_filter->idle != 0 && (long long)(commandTimeSnapshot() / 1000 - client->last_interaction) < client_filter->idle) return 0; if (client_filter->flags && clientMatchesFlagFilter(client, client_filter->flags) == 0) return 0; if (client_filter->name) { - if (!client->name || !client->name->ptr || strcmp(client->name->ptr, client_filter->name) != 0) { + if (!client->name || !objectGetVal(client->name) || strcmp(objectGetVal(client->name), client_filter->name) != 0) { return 0; } } @@ -4827,7 +4827,7 @@ static int clientMatchesFilter(client *client, clientFilter *client_filter) { if (client_filter->not_user && client->user == client_filter->not_user) return 0; if (client_filter->not_flags && clientMatchesFlagFilter(client, client_filter->not_flags) != 0) return 0; if (client_filter->not_name) { - if (client->name && client->name->ptr && strcmp(client->name->ptr, client_filter->not_name) == 0) { + if (client->name && objectGetVal(client->name) && strcmp(objectGetVal(client->name), client_filter->not_name) == 0) { return 0; } } @@ -5123,13 +5123,13 @@ void clientListCommand(client *c) { void clientReplyCommand(client *c) { /* CLIENT REPLY ON|OFF|SKIP */ - if (!strcasecmp(c->argv[2]->ptr, "on")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "on")) { c->flag.reply_skip = 0; c->flag.reply_off = 0; addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[2]->ptr, "off")) { + } else if (!strcasecmp(objectGetVal(c->argv[2]), "off")) { c->flag.reply_off = 1; - } else if (!strcasecmp(c->argv[2]->ptr, "skip")) { + } else if (!strcasecmp(objectGetVal(c->argv[2]), "skip")) { if (!c->flag.reply_off) c->flag.reply_skip_next = 1; } else { addReplyErrorObject(c, shared.syntaxerr); @@ -5139,11 +5139,11 @@ void clientReplyCommand(client *c) { void clientNoEvictCommand(client *c) { /* CLIENT NO-EVICT ON|OFF */ - if (!strcasecmp(c->argv[2]->ptr, "on")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "on")) { c->flag.no_evict = 1; removeClientFromMemUsageBucket(c, 0); addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[2]->ptr, "off")) { + } else if (!strcasecmp(objectGetVal(c->argv[2]), "off")) { c->flag.no_evict = 0; updateClientMemUsageAndBucket(c); addReply(c, shared.ok); @@ -5171,7 +5171,7 @@ void clientKillCommand(client *c) { if (c->argc == 3) { /* Old style syntax: CLIENT KILL */ - client_filter.addr = c->argv[2]->ptr; + client_filter.addr = objectGetVal(c->argv[2]); client_filter.skipme = 0; /* With the old form, you can kill yourself. */ } else if (c->argc > 3) { int i = 2; /* Next option index. */ @@ -5278,9 +5278,9 @@ void clientUnblockCommand(client *c) { int unblock_error = 0; if (c->argc == 4) { - if (!strcasecmp(c->argv[3]->ptr, "timeout")) { + if (!strcasecmp(objectGetVal(c->argv[3]), "timeout")) { unblock_error = 0; - } else if (!strcasecmp(c->argv[3]->ptr, "error")) { + } else if (!strcasecmp(objectGetVal(c->argv[3]), "error")) { unblock_error = 1; } else { addReplyError(c, "CLIENT UNBLOCK reason should be TIMEOUT or ERROR"); @@ -5331,9 +5331,9 @@ void clientPauseCommand(client *c) { mstime_t end; int isPauseClientAll = 1; if (c->argc == 4) { - if (!strcasecmp(c->argv[3]->ptr, "write")) { + if (!strcasecmp(objectGetVal(c->argv[3]), "write")) { isPauseClientAll = 0; - } else if (strcasecmp(c->argv[3]->ptr, "all")) { + } else if (strcasecmp(objectGetVal(c->argv[3]), "all")) { addReplyError(c, "CLIENT PAUSE mode must be WRITE or ALL"); return; } @@ -5357,7 +5357,7 @@ void clientTrackingCommand(client *c) { for (int j = 3; j < c->argc; j++) { int moreargs = (c->argc - 1) - j; - if (!strcasecmp(c->argv[j]->ptr, "redirect") && moreargs) { + if (!strcasecmp(objectGetVal(c->argv[j]), "redirect") && moreargs) { j++; if (redir != 0) { addReplyError(c, "A client can only redirect to a single " @@ -5379,15 +5379,15 @@ void clientTrackingCommand(client *c) { zfree(prefix); return; } - } else if (!strcasecmp(c->argv[j]->ptr, "bcast")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "bcast")) { options.tracking_bcast = 1; - } else if (!strcasecmp(c->argv[j]->ptr, "optin")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "optin")) { options.tracking_optin = 1; - } else if (!strcasecmp(c->argv[j]->ptr, "optout")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "optout")) { options.tracking_optout = 1; - } else if (!strcasecmp(c->argv[j]->ptr, "noloop")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "noloop")) { options.tracking_noloop = 1; - } else if (!strcasecmp(c->argv[j]->ptr, "prefix") && moreargs) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "prefix") && moreargs) { j++; prefix = zrealloc(prefix, sizeof(robj *) * (numprefix + 1)); prefix[numprefix++] = c->argv[j]; @@ -5399,7 +5399,7 @@ void clientTrackingCommand(client *c) { } /* Options are ok: enable or disable the tracking for this client. */ - if (!strcasecmp(c->argv[2]->ptr, "on")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "on")) { /* Before enabling tracking, make sure options are compatible * among each other and with the current state of the client. */ if (!(options.tracking_bcast) && numprefix) { @@ -5449,7 +5449,7 @@ void clientTrackingCommand(client *c) { } enableTracking(c, redir, options, prefix, numprefix); - } else if (!strcasecmp(c->argv[2]->ptr, "off")) { + } else if (!strcasecmp(objectGetVal(c->argv[2]), "off")) { disableTracking(c); } else { zfree(prefix); @@ -5468,7 +5468,7 @@ void clientCachingCommand(client *c) { return; } - char *opt = c->argv[2]->ptr; + char *opt = objectGetVal(c->argv[2]); if (!strcasecmp(opt, "yes")) { if (c->flag.tracking_optin) { c->flag.tracking_caching = 1; @@ -5566,10 +5566,10 @@ void clientTrackingInfoCommand(client *c) { void clientNoTouchCommand(client *c) { /* CLIENT NO-TOUCH ON|OFF */ - if (!strcasecmp(c->argv[2]->ptr, "on")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "on")) { c->flag.no_touch = 1; addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[2]->ptr, "off")) { + } else if (!strcasecmp(objectGetVal(c->argv[2]), "off")) { c->flag.no_touch = 0; addReply(c, shared.ok); } else { @@ -5579,7 +5579,7 @@ void clientNoTouchCommand(client *c) { void clientCapaCommand(client *c) { for (int i = 2; i < c->argc; i++) { - if (!strcasecmp(c->argv[i]->ptr, "redirect")) { + if (!strcasecmp(objectGetVal(c->argv[i]), "redirect")) { c->capa |= CLIENT_CAPA_REDIRECT; } } @@ -5588,14 +5588,14 @@ void clientCapaCommand(client *c) { void clientImportSourceCommand(client *c) { /* CLIENT IMPORT-SOURCE ON|OFF */ - if (!server.import_mode && strcasecmp(c->argv[2]->ptr, "off")) { + if (!server.import_mode && strcasecmp(objectGetVal(c->argv[2]), "off")) { addReplyError(c, "Server is not in import mode"); return; } - if (!strcasecmp(c->argv[2]->ptr, "on")) { + if (!strcasecmp(objectGetVal(c->argv[2]), "on")) { c->flag.import_source = 1; addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[2]->ptr, "off")) { + } else if (!strcasecmp(objectGetVal(c->argv[2]), "off")) { c->flag.import_source = 0; addReply(c, shared.ok); } else { @@ -5630,7 +5630,7 @@ void helloCommand(client *c) { robj *clientname = NULL; for (int j = next_arg; j < c->argc; j++) { int moreargs = (c->argc - 1) - j; - const char *opt = c->argv[j]->ptr; + const char *opt = objectGetVal(c->argv[j]); if (!strcasecmp(opt, "AUTH") && moreargs >= 2) { redactClientCommandArgument(c, j + 1); redactClientCommandArgument(c, j + 2); diff --git a/src/notify.c b/src/notify.c index bec0af284..d48c515b9 100644 --- a/src/notify.c +++ b/src/notify.c @@ -138,7 +138,7 @@ void notifyKeyspaceEvent(int type, char *event, robj *key, int dbid) { len = ll2string(buf, sizeof(buf), dbid); chan = sdscatlen(chan, buf, len); chan = sdscatlen(chan, "__:", 3); - chan = sdscatsds(chan, key->ptr); + chan = sdscatsds(chan, objectGetVal(key)); chanobj = createObject(OBJ_STRING, chan); pubsubPublishMessage(chanobj, eventobj, 0); decrRefCount(chanobj); @@ -150,7 +150,7 @@ void notifyKeyspaceEvent(int type, char *event, robj *key, int dbid) { if (len == -1) len = ll2string(buf, sizeof(buf), dbid); chan = sdscatlen(chan, buf, len); chan = sdscatlen(chan, "__:", 3); - chan = sdscatsds(chan, eventobj->ptr); + chan = sdscatsds(chan, objectGetVal(eventobj)); chanobj = createObject(OBJ_STRING, chan); pubsubPublishMessage(chanobj, key, 0); decrRefCount(chanobj); diff --git a/src/object.c b/src/object.c index 3e6c9abb5..63aaeb38d 100644 --- a/src/object.c +++ b/src/object.c @@ -51,11 +51,12 @@ /* ===================== Creation and parsing of objects ==================== */ /* Creates an object, optionally with embedded key and expire fields. The key - * and expire fields can be omitted by passing NULL and -1, respectively. */ -robj *createObjectWithKeyAndExpire(int type, void *ptr, const sds key, long long expire) { + * and expire fields can be omitted by passing NULL and EXPIRY_NONE, respectively. + * This function never embeds value. */ +static robj *createUnembeddedObjectWithKeyAndExpire(int type, void *val, const_sds key, long long expire) { /* Calculate sizes */ int has_embkey = key != NULL; - int has_expire = (expire != -1 || + int has_expire = (expire != EXPIRY_NONE || (has_embkey && sdslen(key) >= KEY_SIZE_TO_INCLUDE_EXPIRE_THRESHOLD)); size_t key_sds_len = has_embkey ? sdslen(key) : 0; char key_sds_type = has_embkey ? sdsReqType(key_sds_len) : 0; @@ -73,10 +74,11 @@ robj *createObjectWithKeyAndExpire(int type, void *ptr, const sds key, long long robj *o = zmalloc_usable(min_size, &bufsize); o->type = type; o->encoding = OBJ_ENCODING_RAW; - o->ptr = ptr; o->refcount = 1; o->lru = 0; o->hasembkey = has_embkey; + o->hasembval = 0; + o->val_ptr = val; /* If the allocation has enough space for an expire field, add it even if we * don't need it now. Then we don't need to realloc if it's needed later. */ @@ -104,8 +106,9 @@ robj *createObjectWithKeyAndExpire(int type, void *ptr, const sds key, long long return o; } -robj *createObject(int type, void *ptr) { - return createObjectWithKeyAndExpire(type, ptr, NULL, -1); +/* Creates an object of the specified type. The value is never embedded. */ +robj *createObject(int type, void *val) { + return createUnembeddedObjectWithKeyAndExpire(type, val, NULL, EXPIRY_NONE); } void initObjectLRUOrLFU(robj *o) { @@ -136,11 +139,18 @@ robj *createRawStringObject(const char *ptr, size_t len) { return createObject(OBJ_STRING, sdsnewlen(ptr, len)); } -/* Creates a new embedded string object and copies the content of key, val and - * expire to the new object. LRU is set to 0. */ +/* Get beginning of embedded data, which may contain expire, key, and/or value. Embedded data flags must be accurate when called. */ +static unsigned char *objectEmbeddedData(const robj *o) { + unsigned char *data = (void *)(o + 1); + if (o->hasembval) data -= sizeof(void *); + return data; +} + +/* Creates a new embedded string object and copies the content of key, val_ptr + * and expire to the new object. LRU is set to 0. */ static robj *createEmbeddedStringObjectWithKeyAndExpire(const char *val_ptr, size_t val_len, - const sds key, + const_sds key, long long expire) { /* Calculate sizes */ int has_embkey = (key != NULL); @@ -148,14 +158,20 @@ static robj *createEmbeddedStringObjectWithKeyAndExpire(const char *val_ptr, char key_sds_type = has_embkey ? sdsReqType(key_sds_len) : 0; size_t key_sds_size = has_embkey ? sdsReqSize(key_sds_len, key_sds_type) : 0; size_t val_sds_size = sdsReqSize(val_len, SDS_TYPE_8); - size_t min_size = sizeof(robj) + val_sds_size; - if (expire != -1) { + if (val_sds_size < sizeof(void *)) { + val_sds_size = sizeof(void *); /* Ensure it's possible to "unembed" value later */ + } + + /* We don't need 'val_ptr' when val is embedded, so we can overwrite `val_ptr` memory to reduce memory usage. */ + size_t min_size = sizeof(robj) - sizeof(void *); + if (expire != EXPIRY_NONE) { min_size += sizeof(long long); } if (has_embkey) { /* Size of embedded key, incl. 1 byte for prefixed sds hdr size. */ min_size += 1 + key_sds_size; } + min_size += val_sds_size; /* Allocate and set the declared fields. */ size_t bufsize = 0; @@ -164,8 +180,9 @@ static robj *createEmbeddedStringObjectWithKeyAndExpire(const char *val_ptr, o->encoding = OBJ_ENCODING_EMBSTR; o->refcount = 1; o->lru = 0; - o->hasexpire = (expire != -1); + o->hasexpire = (expire != EXPIRY_NONE); o->hasembkey = has_embkey; + o->hasembval = 1; /* If the allocation has enough space for an expire field, add it even if we * don't need it now. Then we don't need to realloc if it's needed later. */ @@ -175,7 +192,7 @@ static robj *createEmbeddedStringObjectWithKeyAndExpire(const char *val_ptr, } /* The memory after the struct where we embedded data. */ - char *data = (void *)(o + 1); + char *data = (char *)objectEmbeddedData(o); /* Set the expire field. */ if (o->hasexpire) { @@ -193,7 +210,10 @@ static robj *createEmbeddedStringObjectWithKeyAndExpire(const char *val_ptr, /* Copy embedded value (EMBSTR) always as SDS TYPE 8. Account for unused * memory in the SDS alloc field. */ size_t remaining_size = bufsize - (data - (char *)(void *)o); - o->ptr = sdswrite(data, remaining_size, SDS_TYPE_8, val_ptr, val_len); + + assert(val_len <= sdsTypeMaxSize(SDS_TYPE_8)); + assert(remaining_size <= sdsTypeMaxSize(SDS_TYPE_8)); + sdswrite(data, remaining_size, SDS_TYPE_8, val_ptr, val_len); return o; } @@ -201,54 +221,72 @@ static robj *createEmbeddedStringObjectWithKeyAndExpire(const char *val_ptr, /* Create a string object with encoding OBJ_ENCODING_EMBSTR, that is * an object where the sds string is actually an unmodifiable string * allocated in the same chunk as the object itself. */ -robj *createEmbeddedStringObject(const char *ptr, size_t len) { - return createEmbeddedStringObjectWithKeyAndExpire(ptr, len, NULL, -1); +static robj *createEmbeddedStringObject(const char *ptr, size_t len) { + return createEmbeddedStringObjectWithKeyAndExpire(ptr, len, NULL, EXPIRY_NONE); } -/* Create a string object with EMBSTR encoding if it is smaller than - * OBJ_ENCODING_EMBSTR_SIZE_LIMIT, otherwise the RAW encoding is - * used. - * - * The current limit of 44 is chosen so that the biggest string object - * we allocate as EMBSTR will still fit into the 64 byte arena of jemalloc. */ -#define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44 +static bool shouldEmbedStringObject(size_t val_len, const_sds key, long long expire) { + /* When to embed? Embed when the sum is up to 128 bytes. (2 cache lines on most systems) */ + if (val_len > sdsTypeMaxSize(SDS_TYPE_8)) return false; + + size_t size = sizeof(robj) - sizeof(void *); /* reusing 'ptr' memory when embedding */ + if (key) { + size_t key_len = sdslen(key); + size += sdsReqSize(key_len, sdsReqType(key_len)) + 1; /* 1 byte for prefixed sds hdr size */ + } + size += (expire != EXPIRY_NONE) * sizeof(long long); + size += sdsReqSize(val_len, SDS_TYPE_8); + return size <= 128; +} + +/* Create a string object with EMBSTR encoding if it is small, otherwise RAW encoding */ robj *createStringObject(const char *ptr, size_t len) { - if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT) + if (shouldEmbedStringObject(len, NULL, EXPIRY_NONE)) return createEmbeddedStringObject(ptr, len); else return createRawStringObject(ptr, len); } /* Similar to createStringObject() but takes an existing SDS as input. */ -robj *createStringObjectFromSds(const sds s) { +robj *createStringObjectFromSds(const_sds s) { return createStringObject(s, sdslen(s)); } -robj *createStringObjectWithKeyAndExpire(const char *ptr, size_t len, const sds key, long long expire) { - /* When to embed? Embed when the sum is up to 64 bytes. There may be better - * heuristics, e.g. we can look at the jemalloc sizes (16-byte intervals up - * to 128 bytes). */ - size_t size = sizeof(robj); - if (key) { - size_t key_len = sdslen(key); - size += sdsReqSize(key_len, sdsReqType(key_len)) + 1; /* 1 byte for prefixed sds hdr size */ - } - size += (expire != -1) * sizeof(long long); - size += sdsReqSize(len, SDS_TYPE_8); - if (size <= 64) { +static robj *createStringObjectWithKeyAndExpire(const char *ptr, size_t len, const_sds key, long long expire) { + if (shouldEmbedStringObject(len, key, expire)) { return createEmbeddedStringObjectWithKeyAndExpire(ptr, len, key, expire); } else { - return createObjectWithKeyAndExpire(OBJ_STRING, sdsnewlen(ptr, len), key, expire); + return createUnembeddedObjectWithKeyAndExpire(OBJ_STRING, sdsnewlen(ptr, len), key, expire); } } -sds objectGetKey(const robj *val) { - unsigned char *data = (void *)(val + 1); - if (val->hasexpire) { +void *objectGetVal(const robj *o) { + if (o->hasembval) { + unsigned char *data = objectEmbeddedData(o); + if (o->hasexpire) { + /* Skip expire field */ + data += sizeof(long long); + } + if (o->hasembkey) { + /* Skip embedded key */ + uint8_t hdr_size = *(uint8_t *)data; + data += 1 + hdr_size; /* +1 for header size byte */ + data += sdslen((const_sds)data) + 1; /* +1 for null terminator */ + } + assert(o->encoding == OBJ_ENCODING_EMBSTR); + return data + sdsHdrSize(SDS_TYPE_8); + } else { + return o->val_ptr; + } +} + +sds objectGetKey(const robj *o) { + const unsigned char *data = objectEmbeddedData((robj *)o); + if (o->hasexpire) { /* Skip expire field */ data += sizeof(long long); } - if (val->hasembkey) { + if (o->hasembkey) { uint8_t hdr_size = *(uint8_t *)data; data += 1 + hdr_size; return (sds)data; @@ -256,66 +294,94 @@ sds objectGetKey(const robj *val) { return NULL; } -/* Return the expire time of the specified robj, or -1 if no expire +/* Return the expire time of the specified robj, or EXPIRY_NONE if no expire * is associated with this robj (i.e. the robj is non volatile) */ -long long objectGetExpire(const robj *val) { - if (val->hasexpire) { - unsigned char *data = (void *)(val + 1); +long long objectGetExpire(const robj *o) { + if (o->hasexpire) { + const unsigned char *data = objectEmbeddedData((robj *)o); return *(long long *)data; } else { - return -1; + return EXPIRY_NONE; } } /* This functions may reallocate the value. The new allocation is returned and * the old object's reference counter is decremented and possibly freed. Use the - * returned object instead of 'val' after calling this function. */ -robj *objectSetExpire(robj *val, long long expire) { - if (val->hasexpire) { + * returned object instead of 'o' after calling this function. */ +robj *objectSetExpire(robj *o, long long expire) { + if (o->hasexpire) { /* Update existing expire field. */ - unsigned char *data = (void *)(val + 1); + unsigned char *data = objectEmbeddedData(o); *(long long *)data = expire; - return val; - } else if (expire == -1) { - return val; + return o; + } else if (expire == EXPIRY_NONE) { + return o; } else { - return objectSetKeyAndExpire(val, objectGetKey(val), expire); + return objectSetKeyAndExpire(o, objectGetKey(o), expire); } } +/* Caller is responsible for ensuring that robj does not have an embedded value */ +void objectSetVal(robj *o, void *val) { + assert(!o->hasembval); + o->val_ptr = val; +} + +/* Sometimes it's necessary to grow an object's value without reallocating it. + * The old embedded value memory becomes wasted for the remaining lifetime of this + * object. Consider using dbUnshareStringValue() or similar if at all possible */ +void objectUnembedVal(robj *o) { + assert(o->hasembval); + assert(o->encoding == OBJ_ENCODING_EMBSTR); + + const_sds embedded_sds = objectGetVal(o); + assert(sdsAllocSize(embedded_sds) >= sizeof(void *)); + + sds new_val = sdsnewlen(embedded_sds, sdslen(embedded_sds)); + + /* shift remaining embedded data out of val_ptr location */ + ptrdiff_t embedded_data_size = (unsigned char *)embedded_sds - objectEmbeddedData(o); + embedded_data_size -= sdsHdrSize(SDS_TYPE_8); + memmove(objectEmbeddedData(o) + sizeof(void *), objectEmbeddedData(o), embedded_data_size); + + o->hasembval = 0; + o->encoding = OBJ_ENCODING_RAW; + o->val_ptr = new_val; +} + /* This functions may reallocate the value. The new allocation is returned and * the old object's reference counter is decremented and possibly freed. Use the - * returned object instead of 'val' after calling this function. */ -robj *objectSetKeyAndExpire(robj *val, sds key, long long expire) { - if (val->type == OBJ_STRING && val->encoding == OBJ_ENCODING_EMBSTR) { - robj *new = createStringObjectWithKeyAndExpire(val->ptr, sdslen(val->ptr), key, expire); - new->lru = val->lru; - decrRefCount(val); + * returned object instead of 'o' after calling this function. */ +robj *objectSetKeyAndExpire(robj *o, const_sds key, long long expire) { + if (o->type == OBJ_STRING && o->encoding == OBJ_ENCODING_EMBSTR) { + robj *new = createStringObjectWithKeyAndExpire(objectGetVal(o), sdslen(objectGetVal(o)), key, expire); + new->lru = o->lru; + decrRefCount(o); return new; } /* Create a new object with embedded key. Reuse ptr if possible. */ void *ptr; - if (val->refcount == 1) { - /* Reuse the ptr. There are no other references to val. */ - ptr = val->ptr; - val->ptr = NULL; - } else if (val->type == OBJ_STRING && val->encoding == OBJ_ENCODING_INT) { + if (o->refcount == 1) { + /* Reuse the ptr. There are no other references to o. */ + ptr = o->val_ptr; + o->val_ptr = NULL; + } else if (o->type == OBJ_STRING && o->encoding == OBJ_ENCODING_INT) { /* The pointer is not allocated memory. We can just copy the pointer. */ - ptr = val->ptr; - } else if (val->type == OBJ_STRING && val->encoding == OBJ_ENCODING_RAW) { + ptr = o->val_ptr; + } else if (o->type == OBJ_STRING && o->encoding == OBJ_ENCODING_RAW) { /* Dup the string. */ - ptr = sdsdup(val->ptr); + ptr = sdsdup(o->val_ptr); } else { - serverAssert(val->type != OBJ_STRING); + serverAssert(o->type != OBJ_STRING); /* There are multiple references to this non-string object. Most types * can be duplicated, but for a module type is not always possible. */ serverPanic("Not implemented"); } - robj *new = createObjectWithKeyAndExpire(val->type, ptr, key, expire); - new->encoding = val->encoding; - new->lru = val->lru; - decrRefCount(val); + robj *new = createUnembeddedObjectWithKeyAndExpire(o->type, ptr, key, expire); + new->encoding = o->encoding; + new->lru = o->lru; + decrRefCount(o); return new; } @@ -328,7 +394,7 @@ robj *tryCreateRawStringObject(const char *ptr, size_t len) { /* Same as createStringObject, can return NULL if allocation fails */ robj *tryCreateStringObject(const char *ptr, size_t len) { - if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT) + if (shouldEmbedStringObject(len, NULL, EXPIRY_NONE)) return createEmbeddedStringObject(ptr, len); else return tryCreateRawStringObject(ptr, len); @@ -347,7 +413,7 @@ robj *createStringObjectFromLongLongWithOptions(long long value, int flag) { if ((value >= LONG_MIN && value <= LONG_MAX) && flag != LL2STROBJ_NO_INT_ENC) { o = createObject(OBJ_STRING, NULL); o->encoding = OBJ_ENCODING_INT; - o->ptr = (void *)((long)value); + o->val_ptr = (void *)((long)value); } else { char buf[LONG_STR_SIZE]; int len = ll2string(buf, sizeof(buf), value); @@ -401,12 +467,12 @@ robj *dupStringObject(const robj *o) { serverAssert(o->type == OBJ_STRING); switch (o->encoding) { - case OBJ_ENCODING_RAW: return createRawStringObject(o->ptr, sdslen(o->ptr)); - case OBJ_ENCODING_EMBSTR: return createEmbeddedStringObject(o->ptr, sdslen(o->ptr)); + case OBJ_ENCODING_RAW: return createRawStringObject(objectGetVal(o), sdslen(objectGetVal(o))); + case OBJ_ENCODING_EMBSTR: return createEmbeddedStringObject(objectGetVal(o), sdslen(objectGetVal(o))); case OBJ_ENCODING_INT: d = createObject(OBJ_STRING, NULL); d->encoding = OBJ_ENCODING_INT; - d->ptr = o->ptr; + d->val_ptr = o->val_ptr; return d; default: serverPanic("Wrong encoding."); break; } @@ -488,15 +554,15 @@ robj *createModuleObject(moduleType *mt, void *value) { void freeStringObject(robj *o) { if (o->encoding == OBJ_ENCODING_RAW) { - sdsfree(o->ptr); + sdsfree(objectGetVal(o)); } } void freeListObject(robj *o) { if (o->encoding == OBJ_ENCODING_QUICKLIST) { - quicklistRelease(o->ptr); + quicklistRelease(objectGetVal(o)); } else if (o->encoding == OBJ_ENCODING_LISTPACK) { - lpFree(o->ptr); + lpFree(objectGetVal(o)); } else { serverPanic("Unknown list encoding type"); } @@ -504,9 +570,9 @@ void freeListObject(robj *o) { void freeSetObject(robj *o) { switch (o->encoding) { - case OBJ_ENCODING_HASHTABLE: hashtableRelease((hashtable *)o->ptr); break; + case OBJ_ENCODING_HASHTABLE: hashtableRelease((hashtable *)objectGetVal(o)); break; case OBJ_ENCODING_INTSET: - case OBJ_ENCODING_LISTPACK: zfree(o->ptr); break; + case OBJ_ENCODING_LISTPACK: zfree(objectGetVal(o)); break; default: serverPanic("Unknown set encoding type"); } } @@ -515,12 +581,12 @@ void freeZsetObject(robj *o) { zset *zs; switch (o->encoding) { case OBJ_ENCODING_SKIPLIST: - zs = o->ptr; + zs = objectGetVal(o); hashtableRelease(zs->ht); zslFree(zs->zsl); zfree(zs); break; - case OBJ_ENCODING_LISTPACK: zfree(o->ptr); break; + case OBJ_ENCODING_LISTPACK: zfree(objectGetVal(o)); break; default: serverPanic("Unknown sorted set encoding"); } } @@ -529,21 +595,21 @@ void freeHashObject(robj *o) { switch (o->encoding) { case OBJ_ENCODING_HASHTABLE: hashTypeFreeVolatileSet(o); - hashtableRelease((hashtable *)o->ptr); + hashtableRelease((hashtable *)objectGetVal(o)); break; - case OBJ_ENCODING_LISTPACK: lpFree(o->ptr); break; + case OBJ_ENCODING_LISTPACK: lpFree(objectGetVal(o)); break; default: serverPanic("Unknown hash encoding type"); break; } } void freeModuleObject(robj *o) { - moduleValue *mv = o->ptr; + moduleValue *mv = objectGetVal(o); mv->type->free(mv->value); zfree(mv); } void freeStreamObject(robj *o) { - freeStream(o->ptr); + freeStream(objectGetVal(o)); } void incrRefCount(robj *o) { @@ -560,7 +626,7 @@ void incrRefCount(robj *o) { void decrRefCount(robj *o) { if (o->refcount == 1) { - if (o->ptr != NULL) { + if (objectGetVal(o) != NULL) { switch (o->type) { case OBJ_STRING: freeStringObject(o); break; case OBJ_LIST: freeListObject(o); break; @@ -592,14 +658,14 @@ void dismissSds(sds s) { /* See dismissObject() */ void dismissStringObject(robj *o) { if (o->encoding == OBJ_ENCODING_RAW) { - dismissSds(o->ptr); + dismissSds(objectGetVal(o)); } } /* See dismissObject() */ void dismissListObject(robj *o, size_t size_hint) { if (o->encoding == OBJ_ENCODING_QUICKLIST) { - quicklist *ql = o->ptr; + quicklist *ql = objectGetVal(o); serverAssert(ql->len != 0); /* We iterate all nodes only when average node size is bigger than a * page size, and there's a high chance we'll actually dismiss something. */ @@ -615,7 +681,7 @@ void dismissListObject(robj *o, size_t size_hint) { } } } else if (o->encoding == OBJ_ENCODING_LISTPACK) { - dismissMemory(o->ptr, lpBytes((unsigned char *)o->ptr)); + dismissMemory(objectGetVal(o), lpBytes((unsigned char *)objectGetVal(o))); } else { serverPanic("Unknown list encoding type"); } @@ -624,7 +690,7 @@ void dismissListObject(robj *o, size_t size_hint) { /* See dismissObject() */ void dismissSetObject(robj *o, size_t size_hint) { if (o->encoding == OBJ_ENCODING_HASHTABLE) { - hashtable *ht = o->ptr; + hashtable *ht = objectGetVal(o); serverAssert(hashtableSize(ht) != 0); /* We iterate all nodes only when average member size is bigger than a * page size, and there's a high chance we'll actually dismiss something. */ @@ -641,9 +707,9 @@ void dismissSetObject(robj *o, size_t size_hint) { dismissHashtable(ht); } else if (o->encoding == OBJ_ENCODING_INTSET) { - dismissMemory(o->ptr, intsetBlobLen((intset *)o->ptr)); + dismissMemory(objectGetVal(o), intsetBlobLen((intset *)objectGetVal(o))); } else if (o->encoding == OBJ_ENCODING_LISTPACK) { - dismissMemory(o->ptr, lpBytes((unsigned char *)o->ptr)); + dismissMemory(objectGetVal(o), lpBytes((unsigned char *)objectGetVal(o))); } else { serverPanic("Unknown set encoding type"); } @@ -652,7 +718,7 @@ void dismissSetObject(robj *o, size_t size_hint) { /* See dismissObject() */ void dismissZsetObject(robj *o, size_t size_hint) { if (o->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = o->ptr; + zset *zs = objectGetVal(o); zskiplist *zsl = zs->zsl; serverAssert(zsl->length != 0); /* We iterate all nodes only when average member size is bigger than a @@ -668,7 +734,7 @@ void dismissZsetObject(robj *o, size_t size_hint) { dismissHashtable(zs->ht); } else if (o->encoding == OBJ_ENCODING_LISTPACK) { - dismissMemory(o->ptr, lpBytes((unsigned char *)o->ptr)); + dismissMemory(objectGetVal(o), lpBytes((unsigned char *)objectGetVal(o))); } else { serverPanic("Unknown zset encoding type"); } @@ -677,7 +743,7 @@ void dismissZsetObject(robj *o, size_t size_hint) { /* See dismissObject() */ void dismissHashObject(robj *o, size_t size_hint) { if (o->encoding == OBJ_ENCODING_HASHTABLE) { - hashtable *ht = o->ptr; + hashtable *ht = objectGetVal(o); serverAssert(hashtableSize(ht) != 0); /* We iterate all fields only when average field/value size is bigger than * a page size, and there's a high chance we'll actually dismiss something. */ @@ -693,7 +759,7 @@ void dismissHashObject(robj *o, size_t size_hint) { dismissHashtable(ht); } else if (o->encoding == OBJ_ENCODING_LISTPACK) { - dismissMemory(o->ptr, lpBytes((unsigned char *)o->ptr)); + dismissMemory(objectGetVal(o), lpBytes((unsigned char *)objectGetVal(o))); } else { serverPanic("Unknown hash encoding type"); } @@ -701,7 +767,7 @@ void dismissHashObject(robj *o, size_t size_hint) { /* See dismissObject() */ void dismissStreamObject(robj *o, size_t size_hint) { - stream *s = o->ptr; + stream *s = objectGetVal(o); rax *rax = s->rax; if (raxSize(rax) == 0) return; @@ -771,10 +837,10 @@ int isSdsRepresentableAsLongLong(sds s, long long *llval) { int isObjectRepresentableAsLongLong(robj *o, long long *llval) { serverAssertWithInfo(NULL, o, o->type == OBJ_STRING); if (o->encoding == OBJ_ENCODING_INT) { - if (llval) *llval = (long)o->ptr; + if (llval) *llval = (long)objectGetVal(o); return C_OK; } else { - return isSdsRepresentableAsLongLong(o->ptr, llval); + return isSdsRepresentableAsLongLong(objectGetVal(o), llval); } } @@ -786,11 +852,11 @@ void trimStringObjectIfNeeded(robj *o, int trim_small_values) { * 1. When an arg len is greater than PROTO_MBULK_BIG_ARG the query buffer may be used directly as the SDS string. * 2. When utilizing the argument caching mechanism in Lua. * 3. When calling from RM_TrimStringAllocation (trim_small_values is true). */ - size_t len = sdslen(o->ptr); + size_t len = sdslen(o->val_ptr); if (len >= PROTO_MBULK_BIG_ARG || trim_small_values || (server.executing_client && server.executing_client->flag.script && len < LUA_CMD_OBJCACHE_MAX_LEN)) { - if (sdsavail(o->ptr) > len / 10) { - o->ptr = sdsRemoveFreeSpace(o->ptr, 0); + if (sdsavail(o->val_ptr) > len / 10) { + o->val_ptr = sdsRemoveFreeSpace(o->val_ptr, 0); } } } @@ -798,7 +864,7 @@ void trimStringObjectIfNeeded(robj *o, int trim_small_values) { /* Try to encode a string object in order to save space */ robj *tryObjectEncodingEx(robj *o, int try_trim) { long value; - sds s = o->ptr; + sds s = objectGetVal(o); size_t len; /* Make sure this is a string object, the only type we encode @@ -824,9 +890,9 @@ robj *tryObjectEncodingEx(robj *o, int try_trim) { if (len <= 20 && string2l(s, len, &value)) { /* This object is encodable as a long. */ if (o->encoding == OBJ_ENCODING_RAW) { - sdsfree(o->ptr); + sdsfree(objectGetVal(o)); o->encoding = OBJ_ENCODING_INT; - o->ptr = (void *)value; + o->val_ptr = (void *)value; return o; } else if (o->encoding == OBJ_ENCODING_EMBSTR) { decrRefCount(o); @@ -838,11 +904,9 @@ robj *tryObjectEncodingEx(robj *o, int try_trim) { * try the EMBSTR encoding which is more efficient. * In this representation the object and the SDS string are allocated * in the same chunk of memory to save space and cache misses. */ - if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT) { - robj *emb; - + if (shouldEmbedStringObject(len, NULL, EXPIRY_NONE)) { if (o->encoding == OBJ_ENCODING_EMBSTR) return o; - emb = createEmbeddedStringObject(s, sdslen(s)); + robj *emb = createEmbeddedStringObject(s, sdslen(s)); decrRefCount(o); return emb; } @@ -871,7 +935,7 @@ robj *getDecodedObject(robj *o) { if (o->type == OBJ_STRING && o->encoding == OBJ_ENCODING_INT) { char buf[32]; - ll2string(buf, 32, (long)o->ptr); + ll2string(buf, 32, (long)objectGetVal(o)); dec = createStringObject(buf, strlen(buf)); return dec; } else { @@ -897,17 +961,17 @@ int compareStringObjectsWithFlags(const robj *a, const robj *b, int flags) { if (a == b) return 0; if (sdsEncodedObject(a)) { - astr = a->ptr; + astr = objectGetVal(a); alen = sdslen(astr); } else { - alen = ll2string(bufa, sizeof(bufa), (long)a->ptr); + alen = ll2string(bufa, sizeof(bufa), (long)objectGetVal(a)); astr = bufa; } if (sdsEncodedObject(b)) { - bstr = b->ptr; + bstr = objectGetVal(b); blen = sdslen(bstr); } else { - blen = ll2string(bufb, sizeof(bufb), (long)b->ptr); + blen = ll2string(bufb, sizeof(bufb), (long)objectGetVal(b)); bstr = bufb; } if (flags & STRING_COMPARE_COLL) { @@ -940,10 +1004,10 @@ int equalStringObjects(robj *a, robj *b) { if (a->encoding == OBJ_ENCODING_INT && b->encoding == OBJ_ENCODING_INT) { /* If both strings are integer encoded just check if the stored * long is the same. */ - return a->ptr == b->ptr; + return objectGetVal(a) == objectGetVal(b); } else if (a->encoding != OBJ_ENCODING_INT && b->encoding != OBJ_ENCODING_INT && - sdslen(a->ptr) != sdslen(b->ptr)) { + sdslen(objectGetVal(a)) != sdslen(objectGetVal(b))) { return 0; } else { return compareStringObjects(a, b) == 0; @@ -953,9 +1017,9 @@ int equalStringObjects(robj *a, robj *b) { size_t stringObjectLen(robj *o) { serverAssertWithInfo(NULL, o, o->type == OBJ_STRING); if (sdsEncodedObject(o)) { - return sdslen(o->ptr); + return sdslen(objectGetVal(o)); } else { - return sdigits10((long)o->ptr); + return sdigits10((long)objectGetVal(o)); } } @@ -967,9 +1031,9 @@ int getDoubleFromObject(const robj *o, double *target) { } else { serverAssertWithInfo(NULL, o, o->type == OBJ_STRING); if (sdsEncodedObject(o)) { - if (!string2d(o->ptr, sdslen(o->ptr), &value)) return C_ERR; + if (!string2d(objectGetVal(o), sdslen(objectGetVal(o)), &value)) return C_ERR; } else if (o->encoding == OBJ_ENCODING_INT) { - value = (long)o->ptr; + value = (long)objectGetVal(o); } else { serverPanic("Unknown string encoding"); } @@ -1000,9 +1064,9 @@ int getLongDoubleFromObject(robj *o, long double *target) { } else { serverAssertWithInfo(NULL, o, o->type == OBJ_STRING); if (sdsEncodedObject(o)) { - if (!string2ld(o->ptr, sdslen(o->ptr), &value)) return C_ERR; + if (!string2ld(objectGetVal(o), sdslen(objectGetVal(o)), &value)) return C_ERR; } else if (o->encoding == OBJ_ENCODING_INT) { - value = (long)o->ptr; + value = (long)objectGetVal(o); } else { serverPanic("Unknown string encoding"); } @@ -1033,9 +1097,9 @@ int getLongLongFromObject(robj *o, long long *target) { } else { serverAssertWithInfo(NULL, o, o->type == OBJ_STRING); if (sdsEncodedObject(o)) { - if (string2ll(o->ptr, sdslen(o->ptr), &value) == 0) return C_ERR; + if (string2ll(objectGetVal(o), sdslen(objectGetVal(o)), &value) == 0) return C_ERR; } else if (o->encoding == OBJ_ENCODING_INT) { - value = (long)o->ptr; + value = (long)objectGetVal(o); } else { serverPanic("Unknown string encoding"); } @@ -1133,13 +1197,13 @@ size_t objectComputeSize(robj *key, robj *o, size_t sample_size, int dbid) { if (o->type == OBJ_STRING) { if (o->encoding == OBJ_ENCODING_RAW) { - asize += sdsAllocSize(o->ptr); + asize += sdsAllocSize(objectGetVal(o)); } else if (o->encoding != OBJ_ENCODING_INT && o->encoding != OBJ_ENCODING_EMBSTR) { serverPanic("Unknown string encoding"); } } else if (o->type == OBJ_LIST) { if (o->encoding == OBJ_ENCODING_QUICKLIST) { - quicklist *ql = o->ptr; + quicklist *ql = objectGetVal(o); quicklistNode *node = ql->head; asize += sizeof(quicklist); do { @@ -1148,13 +1212,13 @@ size_t objectComputeSize(robj *key, robj *o, size_t sample_size, int dbid) { } while ((node = node->next) && samples < sample_size); asize += (double)elesize / samples * ql->len; } else if (o->encoding == OBJ_ENCODING_LISTPACK) { - asize += zmalloc_size(o->ptr); + asize += zmalloc_size(objectGetVal(o)); } else { serverPanic("Unknown list encoding"); } } else if (o->type == OBJ_SET) { if (o->encoding == OBJ_ENCODING_HASHTABLE) { - hashtable *ht = o->ptr; + hashtable *ht = objectGetVal(o); asize += hashtableMemUsage(ht); hashtableIterator iter; @@ -1168,18 +1232,18 @@ size_t objectComputeSize(robj *key, robj *o, size_t sample_size, int dbid) { hashtableCleanupIterator(&iter); if (samples) asize += (double)elesize / samples * hashtableSize(ht); } else if (o->encoding == OBJ_ENCODING_INTSET) { - asize += zmalloc_size(o->ptr); + asize += zmalloc_size(objectGetVal(o)); } else if (o->encoding == OBJ_ENCODING_LISTPACK) { - asize += zmalloc_size(o->ptr); + asize += zmalloc_size(objectGetVal(o)); } else { serverPanic("Unknown set encoding"); } } else if (o->type == OBJ_ZSET) { if (o->encoding == OBJ_ENCODING_LISTPACK) { - asize += zmalloc_size(o->ptr); + asize += zmalloc_size(objectGetVal(o)); } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { - hashtable *ht = ((zset *)o->ptr)->ht; - zskiplist *zsl = ((zset *)o->ptr)->zsl; + hashtable *ht = ((zset *)objectGetVal(o))->ht; + zskiplist *zsl = ((zset *)objectGetVal(o))->zsl; zskiplistNode *znode = zsl->header->level[0].forward; asize += sizeof(zset) + sizeof(zskiplist) + hashtableMemUsage(ht) + zmalloc_size(zsl->header); @@ -1194,9 +1258,9 @@ size_t objectComputeSize(robj *key, robj *o, size_t sample_size, int dbid) { } } else if (o->type == OBJ_HASH) { if (o->encoding == OBJ_ENCODING_LISTPACK) { - asize += zmalloc_size(o->ptr); + asize += zmalloc_size(objectGetVal(o)); } else if (o->encoding == OBJ_ENCODING_HASHTABLE) { - hashtable *ht = o->ptr; + hashtable *ht = objectGetVal(o); hashtableIterator iter; vset *volatile_fields = hashtableMetadata(ht); hashtableInitIterator(&iter, ht, 0); @@ -1214,7 +1278,7 @@ size_t objectComputeSize(robj *key, robj *o, size_t sample_size, int dbid) { serverPanic("Unknown hash encoding"); } } else if (o->type == OBJ_STREAM) { - stream *s = o->ptr; + stream *s = objectGetVal(o); asize += sizeof(*s); asize += raxAllocSize(s->rax); @@ -1632,7 +1696,7 @@ robj *objectCommandLookupOrReply(client *c, robj *key, robj *reply) { void objectCommand(client *c) { robj *o; - if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "help")) { + if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "help")) { const char *help[] = {"ENCODING ", " Return the kind of internal representation used in order to store the value", " associated with a .", @@ -1647,13 +1711,13 @@ void objectCommand(client *c) { " .", NULL}; addReplyHelp(c, help); - } else if (!strcasecmp(c->argv[1]->ptr, "refcount") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "refcount") && c->argc == 3) { if ((o = objectCommandLookupOrReply(c, c->argv[2], shared.null[c->resp])) == NULL) return; addReplyLongLong(c, o->refcount); - } else if (!strcasecmp(c->argv[1]->ptr, "encoding") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "encoding") && c->argc == 3) { if ((o = objectCommandLookupOrReply(c, c->argv[2], shared.null[c->resp])) == NULL) return; addReplyBulkCString(c, strEncoding(o->encoding)); - } else if (!strcasecmp(c->argv[1]->ptr, "idletime") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "idletime") && c->argc == 3) { if ((o = objectCommandLookupOrReply(c, c->argv[2], shared.null[c->resp])) == NULL) return; if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) { addReplyError(c, "An LFU maxmemory policy is selected, idle time not tracked. Please note that when " @@ -1661,7 +1725,7 @@ void objectCommand(client *c) { return; } addReplyLongLong(c, lru_getIdleSecs(o->lru)); - } else if (!strcasecmp(c->argv[1]->ptr, "freq") && c->argc == 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "freq") && c->argc == 3) { if ((o = objectCommandLookupOrReply(c, c->argv[2], shared.null[c->resp])) == NULL) return; if (!(server.maxmemory_policy & MAXMEMORY_FLAG_LFU)) { addReplyError(c, @@ -1680,7 +1744,7 @@ void objectCommand(client *c) { * * Usage: MEMORY usage */ void memoryCommand(client *c) { - if (!strcasecmp(c->argv[1]->ptr, "help") && c->argc == 2) { + if (!strcasecmp(objectGetVal(c->argv[1]), "help") && c->argc == 2) { const char *help[] = { "DOCTOR", " Return memory problems reports.", @@ -1696,10 +1760,10 @@ void memoryCommand(client *c) { NULL, }; addReplyHelp(c, help); - } else if (!strcasecmp(c->argv[1]->ptr, "usage") && c->argc >= 3) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "usage") && c->argc >= 3) { long long samples = OBJ_COMPUTE_SIZE_DEF_SAMPLES; for (int j = 3; j < c->argc; j++) { - if (!strcasecmp(c->argv[j]->ptr, "samples") && j + 1 < c->argc) { + if (!strcasecmp(objectGetVal(c->argv[j]), "samples") && j + 1 < c->argc) { if (getLongLongFromObjectOrReply(c, c->argv[j + 1], &samples, NULL) == C_ERR) return; if (samples < 0) { addReplyErrorObject(c, shared.syntaxerr); @@ -1712,14 +1776,14 @@ void memoryCommand(client *c) { return; } } - robj *obj = dbFind(c->db, c->argv[2]->ptr); + robj *obj = dbFind(c->db, objectGetVal(c->argv[2])); if (obj == NULL) { addReplyNull(c); return; } size_t usage = objectComputeSize(c->argv[2], obj, samples, c->db->id); addReplyLongLong(c, usage); - } else if (!strcasecmp(c->argv[1]->ptr, "stats") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "stats") && c->argc == 2) { struct serverMemOverhead *mh = getMemoryOverheadData(); addReplyMapLen(c, 33 + mh->num_dbs); @@ -1837,7 +1901,7 @@ void memoryCommand(client *c) { addReplyLongLong(c, mh->total_frag_bytes); freeMemoryOverheadData(mh); - } else if (!strcasecmp(c->argv[1]->ptr, "malloc-stats") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "malloc-stats") && c->argc == 2) { #if defined(USE_JEMALLOC) sds info = sdsempty(); je_malloc_stats_print(inputCatSds, &info, NULL); @@ -1846,11 +1910,11 @@ void memoryCommand(client *c) { #else addReplyBulkCString(c, "Stats not supported for the current allocator"); #endif - } else if (!strcasecmp(c->argv[1]->ptr, "doctor") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "doctor") && c->argc == 2) { sds report = getMemoryDoctorReport(); addReplyVerbatim(c, report, sdslen(report), "txt"); sdsfree(report); - } else if (!strcasecmp(c->argv[1]->ptr, "purge") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "purge") && c->argc == 2) { if (jemalloc_purge() == 0) addReply(c, shared.ok); else diff --git a/src/pubsub.c b/src/pubsub.c index a6371dfc0..ca45855b3 100644 --- a/src/pubsub.c +++ b/src/pubsub.c @@ -301,7 +301,7 @@ int pubsubSubscribeChannel(client *c, robj *channel, pubsubtype type) { retval = 1; /* Add the client to the channel -> list of clients hash table */ if (server.cluster_enabled && type.shard) { - slot = getKeySlot(channel->ptr); + slot = getKeySlot(objectGetVal(channel)); } hashtablePosition pos; @@ -343,7 +343,7 @@ int pubsubUnsubscribeChannel(client *c, robj *channel, int notify, pubsubtype ty if (server.cluster_enabled && type.shard) { /* Using keyHashSlot directly because we can't rely on the current_client's slot via getKeySlot() here, * as it might differ from the channel's slot. */ - slot = keyHashSlot(channel->ptr, (int)sdslen(channel->ptr)); + slot = keyHashSlot(objectGetVal(channel), (int)sdslen(objectGetVal(channel))); } void *found = NULL; kvstoreHashtableFind(*type.serverPubSubChannels, slot, channel, &found); @@ -514,7 +514,7 @@ int pubsubPublishMessageInternal(robj *channel, robj *message, pubsubtype type) /* Send to clients listening for that channel */ if (server.cluster_enabled && type.shard) { - slot = keyHashSlot(channel->ptr, sdslen(channel->ptr)); + slot = keyHashSlot(objectGetVal(channel), sdslen(objectGetVal(channel))); } if (kvstoreHashtableFind(*type.serverPubSubChannels, (slot == -1) ? 0 : slot, channel, &element)) { hashtable *clients = element; @@ -542,8 +542,8 @@ int pubsubPublishMessageInternal(robj *channel, robj *message, pubsubtype type) while ((de = dictNext(di)) != NULL) { robj *pattern = dictGetKey(de); hashtable *clients = dictGetVal(de); - if (!stringmatchlen((char *)pattern->ptr, sdslen(pattern->ptr), - (char *)channel->ptr, sdslen(channel->ptr), 0)) + if (!stringmatchlen((char *)objectGetVal(pattern), sdslen(objectGetVal(pattern)), + (char *)objectGetVal(channel), sdslen(objectGetVal(channel)), 0)) continue; hashtableIterator iter; @@ -660,7 +660,7 @@ void publishCommand(client *c) { /* PUBSUB command for Pub/Sub introspection. */ void pubsubCommand(client *c) { - if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "help")) { + if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "help")) { const char *help[] = { "CHANNELS []", " Return the currently active channels matching a (default: '*').", @@ -675,11 +675,11 @@ void pubsubCommand(client *c) { " Return the number of subscribers for the specified shard level channel(s)", NULL}; addReplyHelp(c, help); - } else if (!strcasecmp(c->argv[1]->ptr, "channels") && (c->argc == 2 || c->argc == 3)) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "channels") && (c->argc == 2 || c->argc == 3)) { /* PUBSUB CHANNELS [] */ - sds pat = (c->argc == 2) ? NULL : c->argv[2]->ptr; + sds pat = (c->argc == 2) ? NULL : objectGetVal(c->argv[2]); channelList(c, pat, server.pubsub_channels); - } else if (!strcasecmp(c->argv[1]->ptr, "numsub") && c->argc >= 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "numsub") && c->argc >= 2) { /* PUBSUB NUMSUB [Channel_1 ... Channel_N] */ int j; @@ -691,19 +691,19 @@ void pubsubCommand(client *c) { addReplyBulk(c, c->argv[j]); addReplyLongLong(c, d ? dictSize(d) : 0); } - } else if (!strcasecmp(c->argv[1]->ptr, "numpat") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "numpat") && c->argc == 2) { /* PUBSUB NUMPAT */ addReplyLongLong(c, dictSize(server.pubsub_patterns)); - } else if (!strcasecmp(c->argv[1]->ptr, "shardchannels") && (c->argc == 2 || c->argc == 3)) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "shardchannels") && (c->argc == 2 || c->argc == 3)) { /* PUBSUB SHARDCHANNELS */ - sds pat = (c->argc == 2) ? NULL : c->argv[2]->ptr; + sds pat = (c->argc == 2) ? NULL : objectGetVal(c->argv[2]); channelList(c, pat, server.pubsubshard_channels); - } else if (!strcasecmp(c->argv[1]->ptr, "shardnumsub") && c->argc >= 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "shardnumsub") && c->argc >= 2) { /* PUBSUB SHARDNUMSUB [ShardChannel_1 ... ShardChannel_N] */ int j; addReplyArrayLen(c, (c->argc - 2) * 2); for (j = 2; j < c->argc; j++) { - sds key = c->argv[j]->ptr; + sds key = objectGetVal(c->argv[j]); unsigned int slot = server.cluster_enabled ? keyHashSlot(key, (int)sdslen(key)) : 0; void *found = NULL; kvstoreHashtableFind(server.pubsubshard_channels, slot, c->argv[j], &found); @@ -729,7 +729,7 @@ void channelList(client *c, sds pat, kvstore *pubsub_channels) { while (kvstoreHashtableIteratorNext(kvs_di, &next)) { hashtable *clients = next; robj *cobj = *(robj **)hashtableMetadata(clients); - sds channel = cobj->ptr; + sds channel = objectGetVal(cobj); if (!pat || stringmatchlen(pat, sdslen(pat), channel, sdslen(channel), 0)) { addReplyBulk(c, cobj); diff --git a/src/rdb.c b/src/rdb.c index a192c5305..5fa3c70b8 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -548,10 +548,10 @@ ssize_t rdbSaveStringObject(rio *rdb, robj *obj) { /* Avoid to decode the object, then encode it again, if the * object is already integer encoded. */ if (obj->encoding == OBJ_ENCODING_INT) { - return rdbSaveLongLongAsStringObject(rdb, (long)obj->ptr); + return rdbSaveLongLongAsStringObject(rdb, (long)objectGetVal(obj)); } else { serverAssertWithInfo(NULL, obj, sdsEncodedObject(obj)); - return rdbSaveRawString(rdb, obj->ptr, sdslen(obj->ptr)); + return rdbSaveRawString(rdb, objectGetVal(obj), sdslen(objectGetVal(obj))); } } @@ -610,7 +610,7 @@ void *rdbGenericLoadStringObject(rio *rdb, int flags, size_t *lenptr) { "rdbGenericLoadStringObject failed allocating %llu bytes", len); return NULL; } - if (len && rioRead(rdb, o->ptr, len) == 0) { + if (len && rioRead(rdb, objectGetVal(o), len) == 0) { decrRefCount(o); return NULL; } @@ -870,7 +870,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key, int dbid) { } else if (o->type == OBJ_LIST) { /* Save a list value */ if (o->encoding == OBJ_ENCODING_QUICKLIST) { - quicklist *ql = o->ptr; + quicklist *ql = objectGetVal(o); quicklistNode *node = ql->head; if ((n = rdbSaveLen(rdb, ql->len)) == -1) return -1; @@ -892,7 +892,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key, int dbid) { node = node->next; } } else if (o->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *lp = o->ptr; + unsigned char *lp = objectGetVal(o); /* Save list listpack as a fake quicklist that only has a single node. */ if ((n = rdbSaveLen(rdb, 1)) == -1) return -1; @@ -907,7 +907,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key, int dbid) { } else if (o->type == OBJ_SET) { /* Save a set value */ if (o->encoding == OBJ_ENCODING_HASHTABLE) { - hashtable *set = o->ptr; + hashtable *set = objectGetVal(o); if ((n = rdbSaveLen(rdb, hashtableSize(set))) == -1) { return -1; @@ -927,13 +927,13 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key, int dbid) { } hashtableCleanupIterator(&iterator); } else if (o->encoding == OBJ_ENCODING_INTSET) { - size_t l = intsetBlobLen((intset *)o->ptr); + size_t l = intsetBlobLen((intset *)objectGetVal(o)); - if ((n = rdbSaveRawString(rdb, o->ptr, l)) == -1) return -1; + if ((n = rdbSaveRawString(rdb, objectGetVal(o), l)) == -1) return -1; nwritten += n; } else if (o->encoding == OBJ_ENCODING_LISTPACK) { - size_t l = lpBytes((unsigned char *)o->ptr); - if ((n = rdbSaveRawString(rdb, o->ptr, l)) == -1) return -1; + size_t l = lpBytes((unsigned char *)objectGetVal(o)); + if ((n = rdbSaveRawString(rdb, objectGetVal(o), l)) == -1) return -1; nwritten += n; } else { serverPanic("Unknown set encoding"); @@ -941,12 +941,12 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key, int dbid) { } else if (o->type == OBJ_ZSET) { /* Save a sorted set value */ if (o->encoding == OBJ_ENCODING_LISTPACK) { - size_t l = lpBytes((unsigned char *)o->ptr); + size_t l = lpBytes((unsigned char *)objectGetVal(o)); - if ((n = rdbSaveRawString(rdb, o->ptr, l)) == -1) return -1; + if ((n = rdbSaveRawString(rdb, objectGetVal(o), l)) == -1) return -1; nwritten += n; } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = o->ptr; + zset *zs = objectGetVal(o); zskiplist *zsl = zs->zsl; if ((n = rdbSaveLen(rdb, zsl->length)) == -1) return -1; @@ -975,12 +975,12 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key, int dbid) { } else if (o->type == OBJ_HASH) { /* Save a hash value */ if (o->encoding == OBJ_ENCODING_LISTPACK) { - size_t l = lpBytes((unsigned char *)o->ptr); + size_t l = lpBytes((unsigned char *)objectGetVal(o)); - if ((n = rdbSaveRawString(rdb, o->ptr, l)) == -1) return -1; + if ((n = rdbSaveRawString(rdb, objectGetVal(o), l)) == -1) return -1; nwritten += n; } else if (o->encoding == OBJ_ENCODING_HASHTABLE) { - hashtable *ht = o->ptr; + hashtable *ht = objectGetVal(o); if ((n = rdbSaveLen(rdb, hashtableSize(ht))) == -1) { return -1; @@ -1021,7 +1021,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key, int dbid) { } } else if (o->type == OBJ_STREAM) { /* Store how many listpacks we have inside the radix tree. */ - stream *s = o->ptr; + stream *s = objectGetVal(o); rax *rax = s->rax; if ((n = rdbSaveLen(rdb, raxSize(rax))) == -1) return -1; nwritten += n; @@ -1132,7 +1132,7 @@ ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key, int dbid) { } else if (o->type == OBJ_MODULE) { /* Save a module-specific value. */ ValkeyModuleIO io; - moduleValue *mv = o->ptr; + moduleValue *mv = objectGetVal(o); moduleType *mt = mv->type; /* Write the "module" identifier as prefix, so that we'll be able @@ -1940,7 +1940,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { return NULL; } dec = getDecodedObject(ele); - quicklistPushTail(o->ptr, dec->ptr, sdslen(dec->ptr)); + quicklistPushTail(objectGetVal(o), objectGetVal(dec), sdslen(objectGetVal(dec))); decrRefCount(dec); decrRefCount(ele); } @@ -1958,7 +1958,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { o = createSetObject(); /* It's faster to expand the dict to the right size asap in order * to avoid rehashing */ - if (!hashtableTryExpand(o->ptr, len)) { + if (!hashtableTryExpand(objectGetVal(o), len)) { rdbReportCorruptRDB("OOM in hashtableTryExpand %llu", (unsigned long long)len); decrRefCount(o); return NULL; @@ -1985,7 +1985,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { /* Fetch integer value from element. */ if (isSdsRepresentableAsLongLong(sdsele, &llval) == C_OK) { uint8_t success; - o->ptr = intsetAdd(o->ptr, llval, &success); + objectSetVal(o, intsetAdd(objectGetVal(o), llval, &success)); if (!success) { rdbReportCorruptRDB("Duplicate set members detected"); decrRefCount(o); @@ -2010,15 +2010,15 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { * to a listpack encoded set. */ if (o->encoding == OBJ_ENCODING_LISTPACK) { if (setTypeSize(o) < server.set_max_listpack_entries && elelen <= server.set_max_listpack_value && - lpSafeToAdd(o->ptr, elelen)) { - unsigned char *p = lpFirst(o->ptr); - if (p && lpFind(o->ptr, p, (unsigned char *)sdsele, elelen, 0)) { + lpSafeToAdd(objectGetVal(o), elelen)) { + unsigned char *p = lpFirst(objectGetVal(o)); + if (p && lpFind(objectGetVal(o), p, (unsigned char *)sdsele, elelen, 0)) { rdbReportCorruptRDB("Duplicate set members detected"); decrRefCount(o); sdsfree(sdsele); return NULL; } - o->ptr = lpAppend(o->ptr, (unsigned char *)sdsele, elelen); + objectSetVal(o, lpAppend(objectGetVal(o), (unsigned char *)sdsele, elelen)); } else if (setTypeConvertAndExpand(o, OBJ_ENCODING_HASHTABLE, len, 0) != C_OK) { rdbReportCorruptRDB("OOM in hashtableTryExpand %llu", (unsigned long long)len); sdsfree(sdsele); @@ -2030,7 +2030,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { /* This will also be called when the set was just converted * to a regular hash table encoded set. */ if (o->encoding == OBJ_ENCODING_HASHTABLE) { - if (!hashtableAdd((hashtable *)o->ptr, sdsele)) { + if (!hashtableAdd((hashtable *)objectGetVal(o), sdsele)) { rdbReportCorruptRDB("Duplicate set members detected"); decrRefCount(o); sdsfree(sdsele); @@ -2050,7 +2050,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { if (zsetlen == 0) goto emptykey; o = createZsetObject(); - zs = o->ptr; + zs = objectGetVal(o); if (!hashtableTryExpand(zs->ht, zsetlen)) { rdbReportCorruptRDB("OOM in hashtableTryExpand %llu", (unsigned long long)zsetlen); @@ -2164,11 +2164,11 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { /* Convert to hash table if size threshold is exceeded */ if (o->encoding != OBJ_ENCODING_HASHTABLE && (sdslen(field) > server.hash_max_listpack_value || sdslen(value) > server.hash_max_listpack_value || - !lpSafeToAdd(o->ptr, sdslen(field) + sdslen(value)))) { + !lpSafeToAdd(objectGetVal(o), sdslen(field) + sdslen(value)))) { hashTypeConvert(o, OBJ_ENCODING_HASHTABLE); entry *entry = entryCreate(field, value, EXPIRY_NONE); sdsfree(field); - if (!hashtableAdd((hashtable *)o->ptr, entry)) { + if (!hashtableAdd((hashtable *)objectGetVal(o), entry)) { rdbReportCorruptRDB("Duplicate hash fields detected"); if (dupSearchHashtable) hashtableRelease(dupSearchHashtable); entryFree(entry); @@ -2180,8 +2180,8 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { /* Add pair to listpack */ - o->ptr = lpAppend(o->ptr, (unsigned char *)field, sdslen(field)); - o->ptr = lpAppend(o->ptr, (unsigned char *)value, sdslen(value)); + objectSetVal(o, lpAppend(objectGetVal(o), (unsigned char *)field, sdslen(field))); + objectSetVal(o, lpAppend(objectGetVal(o), (unsigned char *)value, sdslen(value))); sdsfree(field); sdsfree(value); @@ -2195,7 +2195,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { } if (o->encoding == OBJ_ENCODING_HASHTABLE) { - if (!hashtableTryExpand(o->ptr, len)) { + if (!hashtableTryExpand(objectGetVal(o), len)) { rdbReportCorruptRDB("OOM in hashtableTryExpand %llu", (unsigned long long)len); decrRefCount(o); return NULL; @@ -2231,7 +2231,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { /* Add pair to hash table */ entry *entry = entryCreate(field, value, itemexpiry); sdsfree(field); - if (!hashtableAdd((hashtable *)o->ptr, entry)) { + if (!hashtableAdd((hashtable *)objectGetVal(o), entry)) { rdbReportCorruptRDB("Duplicate hash fields detected"); entryFree(entry); decrRefCount(o); @@ -2276,7 +2276,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { } if (container == QUICKLIST_NODE_CONTAINER_PLAIN) { - quicklistAppendPlainNode(o->ptr, data, encoded_len); + quicklistAppendPlainNode(objectGetVal(o), data, encoded_len); continue; } @@ -2307,11 +2307,11 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { zfree(lp); continue; } else { - quicklistAppendListpack(o->ptr, lp); + quicklistAppendListpack(objectGetVal(o), lp); } } - if (quicklistCount(o->ptr) == 0) { + if (quicklistCount(objectGetVal(o)) == 0) { decrRefCount(o); goto emptykey; } @@ -2340,7 +2340,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { if (!zipmapValidateIntegrity(encoded, encoded_len, 1)) { rdbReportCorruptRDB("Zipmap integrity check failed."); zfree(encoded); - o->ptr = NULL; + objectSetVal(o, NULL); decrRefCount(o); return NULL; } @@ -2348,7 +2348,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { * when loading dumps created by Redis OSS 2.4 gets deprecated. */ { unsigned char *lp = lpNew(0); - unsigned char *zi = zipmapRewind(o->ptr); + unsigned char *zi = zipmapRewind(objectGetVal(o)); unsigned char *fstr, *vstr; unsigned int flen, vlen; unsigned int maxlen = 0; @@ -2366,7 +2366,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { hashtableRelease(dupSearchHashtable); sdsfree(field); zfree(encoded); - o->ptr = NULL; + objectSetVal(o, NULL); decrRefCount(o); return NULL; } @@ -2376,8 +2376,8 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { } hashtableRelease(dupSearchHashtable); - zfree(o->ptr); - o->ptr = lp; + zfree(objectGetVal(o)); + objectSetVal(o, lp); o->type = OBJ_HASH; o->encoding = OBJ_ENCODING_LISTPACK; @@ -2392,7 +2392,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { if (!ziplistValidateIntegrity(encoded, encoded_len, 1, _listZiplistEntryConvertAndValidate, ql)) { rdbReportCorruptRDB("List ziplist integrity check failed."); zfree(encoded); - o->ptr = NULL; + objectSetVal(o, NULL); decrRefCount(o); quicklistRelease(ql); return NULL; @@ -2400,7 +2400,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { if (ql->len == 0) { zfree(encoded); - o->ptr = NULL; + objectSetVal(o, NULL); decrRefCount(o); quicklistRelease(ql); goto emptykey; @@ -2408,7 +2408,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { zfree(encoded); o->type = OBJ_LIST; - o->ptr = ql; + objectSetVal(o, ql); o->encoding = OBJ_ENCODING_QUICKLIST; break; } @@ -2417,20 +2417,20 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { if (!intsetValidateIntegrity(encoded, encoded_len, deep_integrity_validation)) { rdbReportCorruptRDB("Intset integrity check failed."); zfree(encoded); - o->ptr = NULL; + objectSetVal(o, NULL); decrRefCount(o); return NULL; } o->type = OBJ_SET; o->encoding = OBJ_ENCODING_INTSET; - if (intsetLen(o->ptr) > server.set_max_intset_entries) setTypeConvert(o, OBJ_ENCODING_HASHTABLE); + if (intsetLen(objectGetVal(o)) > server.set_max_intset_entries) setTypeConvert(o, OBJ_ENCODING_HASHTABLE); break; case RDB_TYPE_SET_LISTPACK: if (deep_integrity_validation) server.stat_dump_payload_sanitizations++; if (!lpValidateIntegrityAndDups(encoded, encoded_len, deep_integrity_validation, 0)) { rdbReportCorruptRDB("Set listpack integrity check failed."); zfree(encoded); - o->ptr = NULL; + objectSetVal(o, NULL); decrRefCount(o); return NULL; } @@ -2439,7 +2439,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { if (setTypeSize(o) == 0) { zfree(encoded); - o->ptr = NULL; + objectSetVal(o, NULL); decrRefCount(o); goto emptykey; } @@ -2451,14 +2451,14 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { rdbReportCorruptRDB("Zset ziplist integrity check failed."); zfree(lp); zfree(encoded); - o->ptr = NULL; + objectSetVal(o, NULL); decrRefCount(o); return NULL; } - zfree(o->ptr); + zfree(objectGetVal(o)); o->type = OBJ_ZSET; - o->ptr = lp; + objectSetVal(o, lp); o->encoding = OBJ_ENCODING_LISTPACK; if (zsetLength(o) == 0) { decrRefCount(o); @@ -2468,7 +2468,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { if (zsetLength(o) > server.zset_max_listpack_entries) zsetConvert(o, OBJ_ENCODING_SKIPLIST); else - o->ptr = lpShrinkToFit(o->ptr); + objectSetVal(o, lpShrinkToFit(objectGetVal(o))); break; } case RDB_TYPE_ZSET_LISTPACK: @@ -2476,7 +2476,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { if (!lpValidateIntegrityAndDups(encoded, encoded_len, deep_integrity_validation, 1)) { rdbReportCorruptRDB("Zset listpack integrity check failed."); zfree(encoded); - o->ptr = NULL; + objectSetVal(o, NULL); decrRefCount(o); return NULL; } @@ -2495,13 +2495,13 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { rdbReportCorruptRDB("Hash ziplist integrity check failed."); zfree(lp); zfree(encoded); - o->ptr = NULL; + objectSetVal(o, NULL); decrRefCount(o); return NULL; } - zfree(o->ptr); - o->ptr = lp; + zfree(objectGetVal(o)); + objectSetVal(o, lp); o->type = OBJ_HASH; o->encoding = OBJ_ENCODING_LISTPACK; if (hashTypeLength(o) == 0) { @@ -2512,7 +2512,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { if (hashTypeLength(o) > server.hash_max_listpack_entries) hashTypeConvert(o, OBJ_ENCODING_HASHTABLE); else - o->ptr = lpShrinkToFit(o->ptr); + objectSetVal(o, lpShrinkToFit(objectGetVal(o))); break; } case RDB_TYPE_HASH_LISTPACK: @@ -2520,7 +2520,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { if (!lpValidateIntegrityAndDups(encoded, encoded_len, deep_integrity_validation, 1)) { rdbReportCorruptRDB("Hash listpack integrity check failed."); zfree(encoded); - o->ptr = NULL; + objectSetVal(o, NULL); decrRefCount(o); return NULL; } @@ -2541,7 +2541,7 @@ robj *rdbLoadObject(int rdbtype, rio *rdb, sds key, int dbid, int *error) { } else if (rdbtype == RDB_TYPE_STREAM_LISTPACKS || rdbtype == RDB_TYPE_STREAM_LISTPACKS_2 || rdbtype == RDB_TYPE_STREAM_LISTPACKS_3) { o = createStreamObject(); - stream *s = o->ptr; + stream *s = objectGetVal(o); uint64_t listpacks = rdbLoadLen(rdb, NULL); if (listpacks == RDB_LENERR) { rdbReportReadError("Stream listpacks len loading failed."); @@ -3230,43 +3230,43 @@ int rdbLoadRioWithLoadingCtx(rio *rdb, int rdbflags, rdbSaveInfo *rsi, rdbLoadin goto eoferr; } - if (((char *)auxkey->ptr)[0] == '%') { + if (((char *)objectGetVal(auxkey))[0] == '%') { /* All the fields with a name staring with '%' are considered * information fields and are logged at startup with a log * level of NOTICE. */ - serverLog(LL_NOTICE, "RDB '%s': %s", (char *)auxkey->ptr, (char *)auxval->ptr); - } else if (!strcasecmp(auxkey->ptr, "repl-stream-db")) { - if (rsi) rsi->repl_stream_db = atoi(auxval->ptr); - } else if (!strcasecmp(auxkey->ptr, "repl-id")) { - if (rsi && sdslen(auxval->ptr) == CONFIG_RUN_ID_SIZE) { - memcpy(rsi->repl_id, auxval->ptr, CONFIG_RUN_ID_SIZE + 1); + serverLog(LL_NOTICE, "RDB '%s': %s", (char *)objectGetVal(auxkey), (char *)objectGetVal(auxval)); + } else if (!strcasecmp(objectGetVal(auxkey), "repl-stream-db")) { + if (rsi) rsi->repl_stream_db = atoi(objectGetVal(auxval)); + } else if (!strcasecmp(objectGetVal(auxkey), "repl-id")) { + if (rsi && sdslen(objectGetVal(auxval)) == CONFIG_RUN_ID_SIZE) { + memcpy(rsi->repl_id, objectGetVal(auxval), CONFIG_RUN_ID_SIZE + 1); rsi->repl_id_is_set = 1; } - } else if (!strcasecmp(auxkey->ptr, "repl-offset")) { - if (rsi) rsi->repl_offset = strtoll(auxval->ptr, NULL, 10); - } else if (!strcasecmp(auxkey->ptr, "lua")) { + } else if (!strcasecmp(objectGetVal(auxkey), "repl-offset")) { + if (rsi) rsi->repl_offset = strtoll(objectGetVal(auxval), NULL, 10); + } else if (!strcasecmp(objectGetVal(auxkey), "lua")) { /* Won't load the script back in memory anymore. */ - } else if (!strcasecmp(auxkey->ptr, "redis-ver")) { - serverLog(LL_NOTICE, "Loading RDB produced by Redis version %s", (char *)auxval->ptr); - } else if (!strcasecmp(auxkey->ptr, "valkey-ver")) { - serverLog(LL_NOTICE, "Loading RDB produced by Valkey version %s", (char *)auxval->ptr); - } else if (!strcasecmp(auxkey->ptr, "ctime")) { - time_t age = time(NULL) - strtol(auxval->ptr, NULL, 10); + } else if (!strcasecmp(objectGetVal(auxkey), "redis-ver")) { + serverLog(LL_NOTICE, "Loading RDB produced by Redis version %s", (char *)objectGetVal(auxval)); + } else if (!strcasecmp(objectGetVal(auxkey), "valkey-ver")) { + serverLog(LL_NOTICE, "Loading RDB produced by Valkey version %s", (char *)objectGetVal(auxval)); + } else if (!strcasecmp(objectGetVal(auxkey), "ctime")) { + time_t age = time(NULL) - strtol(objectGetVal(auxval), NULL, 10); if (age < 0) age = 0; serverLog(LL_NOTICE, "RDB age %ld seconds", (unsigned long)age); - } else if (!strcasecmp(auxkey->ptr, "used-mem")) { - long long usedmem = strtoll(auxval->ptr, NULL, 10); + } else if (!strcasecmp(objectGetVal(auxkey), "used-mem")) { + long long usedmem = strtoll(objectGetVal(auxval), NULL, 10); serverLog(LL_NOTICE, "RDB memory usage when created %.2f Mb", (double)usedmem / (1024 * 1024)); server.loading_rdb_used_mem = usedmem; - } else if (!strcasecmp(auxkey->ptr, "aof-preamble")) { - long long haspreamble = strtoll(auxval->ptr, NULL, 10); + } else if (!strcasecmp(objectGetVal(auxkey), "aof-preamble")) { + long long haspreamble = strtoll(objectGetVal(auxval), NULL, 10); if (haspreamble) serverLog(LL_NOTICE, "RDB has an AOF tail"); - } else if (!strcasecmp(auxkey->ptr, "aof-base")) { - long long isbase = strtoll(auxval->ptr, NULL, 10); + } else if (!strcasecmp(objectGetVal(auxkey), "aof-base")) { + long long isbase = strtoll(objectGetVal(auxval), NULL, 10); if (isbase) serverLog(LL_NOTICE, "RDB is base AOF"); - } else if (!strcasecmp(auxkey->ptr, "redis-bits")) { + } else if (!strcasecmp(objectGetVal(auxkey), "redis-bits")) { /* Just ignored. */ - } else if (!strcasecmp(auxkey->ptr, "slot-info")) { + } else if (!strcasecmp(objectGetVal(auxkey), "slot-info")) { int slot_id; unsigned long slot_size = 0, expires_slot_size = 0, keys_with_volatile_items_slot_size = 0; /* Try to parse the slot information. In case the number of parsed arguments is smaller than expected @@ -3277,7 +3277,7 @@ int rdbLoadRioWithLoadingCtx(rio *rdb, int rdbflags, rdbSaveInfo *rsi, rdbLoadin * In case of relaxed rdb downgrade, trailing unknown data will simply be ignored. * The verification only verifies we read the fields known to exist when we first introduced the slot-info AUX field, * which are the slot number, number of keys in slot and the number of volatile keys. */ - if (sscanf(auxval->ptr, "%i,%lu,%lu,%lu", + if (sscanf(objectGetVal(auxval), "%i,%lu,%lu,%lu", &slot_id, &slot_size, &expires_slot_size, &keys_with_volatile_items_slot_size) < 3) { decrRefCount(auxkey); @@ -3301,11 +3301,11 @@ int rdbLoadRioWithLoadingCtx(rio *rdb, int rdbflags, rdbSaveInfo *rsi, rdbLoadin /* Check if this is a dynamic aux field */ int handled = 0; if (rdbAuxFields != NULL) { - dictEntry *de = dictFind(rdbAuxFields, auxkey->ptr); + dictEntry *de = dictFind(rdbAuxFields, objectGetVal(auxkey)); if (de != NULL) { handled = 1; rdbAuxFieldCodec *codec = (rdbAuxFieldCodec *)dictGetVal(de); - if (codec->decoder(rdbflags, auxval->ptr) == C_ERR) { + if (codec->decoder(rdbflags, objectGetVal(auxval)) == C_ERR) { decrRefCount(auxkey); decrRefCount(auxval); goto eoferr; @@ -3316,7 +3316,7 @@ int rdbLoadRioWithLoadingCtx(rio *rdb, int rdbflags, rdbSaveInfo *rsi, rdbLoadin if (!handled) { /* We ignore fields we don't understand, as by AUX field * contract. */ - serverLog(LL_DEBUG, "Unrecognized RDB AUX field: '%s'", (char *)auxkey->ptr); + serverLog(LL_DEBUG, "Unrecognized RDB AUX field: '%s'", (char *)objectGetVal(auxkey)); } } @@ -3870,9 +3870,9 @@ void bgsaveCommand(client *c) { /* The SCHEDULE option changes the behavior of BGSAVE when an AOF rewrite * is in progress. Instead of returning an error a BGSAVE gets scheduled. */ if (c->argc > 1) { - if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "schedule")) { + if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "schedule")) { schedule = 1; - } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "cancel")) { + } else if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "cancel")) { /* Terminates an in progress BGSAVE */ if (server.child_type == CHILD_TYPE_RDB) { /* There is an ongoing bgsave */ diff --git a/src/replication.c b/src/replication.c index 403662522..475fac9dd 100644 --- a/src/replication.c +++ b/src/replication.c @@ -332,11 +332,11 @@ void feedReplicationBufferWithObject(robj *o) { size_t len; if (o->encoding == OBJ_ENCODING_INT) { - len = ll2string(llstr, sizeof(llstr), (long)o->ptr); + len = ll2string(llstr, sizeof(llstr), (long)objectGetVal(o)); p = llstr; } else { - len = sdslen(o->ptr); - p = o->ptr; + len = sdslen(objectGetVal(o)); + p = objectGetVal(o); } feedReplicationBuffer(p, len); } @@ -571,7 +571,7 @@ void replicationFeedReplicas(int dictid, robj **argv, int argc) { /* Although the SELECT command is not associated with any slot, * its per-slot network-bytes-out accumulation is made by the above function call. * To cancel-out this accumulation, below adjustment is made. */ - clusterSlotStatsDecrNetworkBytesOutForReplication(sdslen(selectcmd->ptr)); + clusterSlotStatsDecrNetworkBytesOutForReplication(sdslen(objectGetVal(selectcmd))); decrRefCount(selectcmd); @@ -688,9 +688,9 @@ void replicationFeedMonitors(client *c, list *monitors, int dictid, robj **argv, for (j = 0; j < argc; j++) { if (argv[j]->encoding == OBJ_ENCODING_INT) { - cmdrepr = sdscatprintf(cmdrepr, "\"%ld\"", (long)argv[j]->ptr); + cmdrepr = sdscatprintf(cmdrepr, "\"%ld\"", (long)objectGetVal(argv[j])); } else { - cmdrepr = sdscatrepr(cmdrepr, (char *)argv[j]->ptr, sdslen(argv[j]->ptr)); + cmdrepr = sdscatrepr(cmdrepr, (char *)objectGetVal(argv[j]), sdslen(objectGetVal(argv[j]))); } if (j != argc - 1) cmdrepr = sdscatlen(cmdrepr, " ", 1); } @@ -826,7 +826,7 @@ int replicationSetupReplicaForFullResync(client *replica, long long offset) { * with the usual full resync. */ int primaryTryPartialResynchronization(client *c, long long psync_offset) { long long psync_len; - char *primary_replid = c->argv[1]->ptr; + char *primary_replid = objectGetVal(c->argv[1]); char buf[128]; int buflen; @@ -1047,14 +1047,14 @@ void syncCommand(client *c) { /* Check if this is a failover request to a replica with the same replid and * become a primary if so. */ - if (c->argc > 3 && !strcasecmp(c->argv[0]->ptr, "psync") && !strcasecmp(c->argv[3]->ptr, "failover")) { - serverLog(LL_NOTICE, "Failover request received for replid %s.", (unsigned char *)c->argv[1]->ptr); + if (c->argc > 3 && !strcasecmp(objectGetVal(c->argv[0]), "psync") && !strcasecmp(objectGetVal(c->argv[3]), "failover")) { + serverLog(LL_NOTICE, "Failover request received for replid %s.", (unsigned char *)objectGetVal(c->argv[1])); if (!server.primary_host) { addReplyError(c, "PSYNC FAILOVER can't be sent to a master."); return; } - if (!strcasecmp(c->argv[1]->ptr, server.replid)) { + if (!strcasecmp(objectGetVal(c->argv[1]), server.replid)) { if (server.cluster_enabled) { clusterPromoteSelfToPrimary(); } else { @@ -1110,7 +1110,7 @@ void syncCommand(client *c) { * * So the replica knows the new replid and offset to try a PSYNC later * if the connection with the primary is lost. */ - if (!strcasecmp(c->argv[0]->ptr, "psync")) { + if (!strcasecmp(objectGetVal(c->argv[0]), "psync")) { long long psync_offset; if (getLongLongFromObjectOrReply(c, c->argv[2], &psync_offset, NULL) != C_OK) { serverLog(LL_WARNING, "Replica %s asks for synchronization but with a wrong offset", @@ -1122,7 +1122,7 @@ void syncCommand(client *c) { server.stat_sync_partial_ok++; return; /* No full resync needed, return. */ } else { - char *primary_replid = c->argv[1]->ptr; + char *primary_replid = objectGetVal(c->argv[1]); /* Increment stats for failed PSYNCs, but only if the * replid is not "?", as this is used by replicas to force a full @@ -1371,13 +1371,13 @@ void replconfCommand(client *c) { /* Process every option-value pair. */ for (j = 1; j < c->argc; j += 2) { - if (!strcasecmp(c->argv[j]->ptr, "listening-port")) { + if (!strcasecmp(objectGetVal(c->argv[j]), "listening-port")) { long port; if ((getLongFromObjectOrReply(c, c->argv[j + 1], &port, NULL) != C_OK)) return; c->repl_data->replica_listening_port = port; - } else if (!strcasecmp(c->argv[j]->ptr, "ip-address")) { - sds addr = c->argv[j + 1]->ptr; + } else if (!strcasecmp(objectGetVal(c->argv[j]), "ip-address")) { + sds addr = objectGetVal(c->argv[j + 1]); if (sdslen(addr) < NET_HOST_STR_LEN) { if (c->repl_data->replica_addr) sdsfree(c->repl_data->replica_addr); c->repl_data->replica_addr = sdsdup(addr); @@ -1388,20 +1388,20 @@ void replconfCommand(client *c) { sdslen(addr)); return; } - } else if (!strcasecmp(c->argv[j]->ptr, "capa")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "capa")) { /* Ignore capabilities not understood by this primary. */ - if (!strcasecmp(c->argv[j + 1]->ptr, "eof")) + if (!strcasecmp(objectGetVal(c->argv[j + 1]), "eof")) c->repl_data->replica_capa |= REPLICA_CAPA_EOF; - else if (!strcasecmp(c->argv[j + 1]->ptr, "psync2")) + else if (!strcasecmp(objectGetVal(c->argv[j + 1]), "psync2")) c->repl_data->replica_capa |= REPLICA_CAPA_PSYNC2; - else if (!strcasecmp(c->argv[j + 1]->ptr, "dual-channel") && server.dual_channel_replication && + else if (!strcasecmp(objectGetVal(c->argv[j + 1]), "dual-channel") && server.dual_channel_replication && server.repl_diskless_sync) { /* If dual-channel is disable on this primary, treat this command as unrecognized * replconf option. */ c->repl_data->replica_capa |= REPLICA_CAPA_DUAL_CHANNEL; - } else if (!strcasecmp(c->argv[j + 1]->ptr, REPLICA_CAPA_SKIP_RDB_CHECKSUM_STR)) + } else if (!strcasecmp(objectGetVal(c->argv[j + 1]), REPLICA_CAPA_SKIP_RDB_CHECKSUM_STR)) c->repl_data->replica_capa |= REPLICA_CAPA_SKIP_RDB_CHECKSUM; - } else if (!strcasecmp(c->argv[j]->ptr, "ack")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "ack")) { /* REPLCONF ACK is used by replica to inform the primary the amount * of replication stream that it processed so far. It is an * internal only command that normal clients should never use. */ @@ -1410,7 +1410,7 @@ void replconfCommand(client *c) { if (!c->flag.replica) return; if ((getLongLongFromObject(c->argv[j + 1], &offset) != C_OK)) return; if (offset > c->repl_data->repl_ack_off) c->repl_data->repl_ack_off = offset; - if (c->argc > j + 3 && !strcasecmp(c->argv[j + 2]->ptr, "fack")) { + if (c->argc > j + 3 && !strcasecmp(objectGetVal(c->argv[j + 2]), "fack")) { if ((getLongLongFromObject(c->argv[j + 3], &offset) != C_OK)) return; if (offset > c->repl_data->repl_aof_off) c->repl_data->repl_aof_off = offset; } @@ -1431,12 +1431,12 @@ void replconfCommand(client *c) { } /* Note: this command does not reply anything! */ return; - } else if (!strcasecmp(c->argv[j]->ptr, "getack")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "getack")) { /* REPLCONF GETACK is used in order to request an ACK ASAP * to the replica. */ if (server.primary_host && server.primary) replicationSendAck(); return; - } else if (!strcasecmp(c->argv[j]->ptr, "rdb-only")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "rdb-only")) { /* REPLCONF RDB-ONLY is used to identify the client only wants * RDB snapshot without replication buffer. */ long rdb_only = 0; @@ -1445,7 +1445,7 @@ void replconfCommand(client *c) { c->flag.repl_rdbonly = 1; else c->flag.repl_rdbonly = 0; - } else if (!strcasecmp(c->argv[j]->ptr, "rdb-filter-only")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "rdb-filter-only")) { /* REPLCONFG RDB-FILTER-ONLY is used to define "include" filters * for the RDB snapshot. Currently we only support a single * include filter: "functions". In the future we may want to add @@ -1455,7 +1455,7 @@ void replconfCommand(client *c) { * filter out certain data. */ int filter_count, i; sds *filters; - if (!(filters = sdssplitargs(c->argv[j + 1]->ptr, &filter_count))) { + if (!(filters = sdssplitargs(objectGetVal(c->argv[j + 1]), &filter_count))) { addReplyError(c, "Missing rdb-filter-only values"); return; } @@ -1472,16 +1472,16 @@ void replconfCommand(client *c) { } } sdsfreesplitres(filters, filter_count); - } else if (!strcasecmp(c->argv[j]->ptr, "version")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "version")) { /* REPLCONF VERSION x.y.z */ - int version = version2num(c->argv[j + 1]->ptr); + int version = version2num(objectGetVal(c->argv[j + 1])); if (version >= 0) { c->repl_data->replica_version = version; } else { - addReplyErrorFormat(c, "Unrecognized version format: %s", (char *)c->argv[j + 1]->ptr); + addReplyErrorFormat(c, "Unrecognized version format: %s", (char *)objectGetVal(c->argv[j + 1])); return; } - } else if (!strcasecmp(c->argv[j]->ptr, "rdb-channel")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "rdb-channel")) { long start_with_offset = 0; if (getRangeLongFromObjectOrReply(c, c->argv[j + 1], 0, 1, &start_with_offset, NULL) != C_OK) { return; @@ -1493,7 +1493,7 @@ void replconfCommand(client *c) { c->flag.repl_rdb_channel = 0; c->repl_data->replica_req &= ~REPLICA_REQ_RDB_CHANNEL; } - } else if (!strcasecmp(c->argv[j]->ptr, "set-rdb-client-id")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "set-rdb-client-id")) { /* REPLCONF identify is used to identify the current replica main channel with existing * rdb-connection with the given id. */ long long client_id = 0; @@ -1505,23 +1505,23 @@ void replconfCommand(client *c) { return; } c->repl_data->associated_rdb_client_id = (uint64_t)client_id; - } else if (!strcasecmp(c->argv[j]->ptr, "set-cluster-node-id")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "set-cluster-node-id")) { /* REPLCONF SET-CLUSTER-NODE-ID */ if (!server.cluster_enabled) { addReplyError(c, "This instance has cluster support disabled"); return; } - clusterNode *n = clusterLookupNode(c->argv[j + 1]->ptr, sdslen(c->argv[j + 1]->ptr)); + clusterNode *n = clusterLookupNode(objectGetVal(c->argv[j + 1]), sdslen(objectGetVal(c->argv[j + 1]))); if (!n) { - addReplyErrorFormat(c, "Unknown node %s", (char *)c->argv[j + 1]->ptr); + addReplyErrorFormat(c, "Unknown node %s", (char *)objectGetVal(c->argv[j + 1])); return; } if (c->repl_data->replica_nodeid) sdsfree(c->repl_data->replica_nodeid); - c->repl_data->replica_nodeid = sdsdup(c->argv[j + 1]->ptr); + c->repl_data->replica_nodeid = sdsdup(objectGetVal(c->argv[j + 1])); } else { - addReplyErrorFormat(c, "Unrecognized REPLCONF option: %s", (char *)c->argv[j]->ptr); + addReplyErrorFormat(c, "Unrecognized REPLCONF option: %s", (char *)objectGetVal(c->argv[j])); return; } } @@ -4489,7 +4489,7 @@ void replicaofCommand(client *c) { /* The special host/port combination "NO" "ONE" turns the instance * into a primary. Otherwise the new primary address is set. */ - if (!strcasecmp(c->argv[1]->ptr, "no") && !strcasecmp(c->argv[2]->ptr, "one")) { + if (!strcasecmp(objectGetVal(c->argv[1]), "no") && !strcasecmp(objectGetVal(c->argv[2]), "one")) { if (server.primary_host) { replicationUnsetPrimary(); sds client = catClientInfoShortString(sdsempty(), c, server.hide_user_data_from_log); @@ -4510,7 +4510,7 @@ void replicaofCommand(client *c) { if (getRangeLongFromObjectOrReply(c, c->argv[2], 0, 65535, &port, "Invalid master port") != C_OK) return; /* Check if we are already attached to the specified primary */ - if (server.primary_host && !strcasecmp(server.primary_host, c->argv[1]->ptr) && server.primary_port == port) { + if (server.primary_host && !strcasecmp(server.primary_host, objectGetVal(c->argv[1])) && server.primary_port == port) { serverLog(LL_NOTICE, "REPLICAOF would result into synchronization " "with the primary we are already connected " "with. No operation performed."); @@ -4520,7 +4520,7 @@ void replicaofCommand(client *c) { } /* There was no previous primary or the user specified a different one, * we can continue. */ - replicationSetPrimary(c->argv[1]->ptr, port, 0, true); + replicationSetPrimary(objectGetVal(c->argv[1]), port, 0, true); sds client = catClientInfoShortString(sdsempty(), c, server.hide_user_data_from_log); serverLog(LL_NOTICE, "REPLICAOF %s:%d enabled (user request from '%s')", server.primary_host, server.primary_port, client); @@ -5479,7 +5479,7 @@ void failoverCommand(client *c) { } /* Handle special case for abort */ - if ((c->argc == 2) && !strcasecmp(c->argv[1]->ptr, "abort")) { + if ((c->argc == 2) && !strcasecmp(objectGetVal(c->argv[1]), "abort")) { if (server.failover_state == NO_FAILOVER) { addReplyError(c, "No failover in progress."); return; @@ -5497,18 +5497,18 @@ void failoverCommand(client *c) { /* Parse the command for syntax and arguments. */ for (int j = 1; j < c->argc; j++) { - if (!strcasecmp(c->argv[j]->ptr, "timeout") && (j + 1 < c->argc) && timeout_in_ms == 0) { + if (!strcasecmp(objectGetVal(c->argv[j]), "timeout") && (j + 1 < c->argc) && timeout_in_ms == 0) { if (getLongFromObjectOrReply(c, c->argv[j + 1], &timeout_in_ms, NULL) != C_OK) return; if (timeout_in_ms <= 0) { addReplyError(c, "FAILOVER timeout must be greater than 0"); return; } j++; - } else if (!strcasecmp(c->argv[j]->ptr, "to") && (j + 2 < c->argc) && !host) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "to") && (j + 2 < c->argc) && !host) { if (getLongFromObjectOrReply(c, c->argv[j + 2], &port, NULL) != C_OK) return; - host = c->argv[j + 1]->ptr; + host = objectGetVal(c->argv[j + 1]); j += 2; - } else if (!strcasecmp(c->argv[j]->ptr, "force") && !force_flag) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "force") && !force_flag) { force_flag = 1; } else { addReplyErrorObject(c, shared.syntaxerr); diff --git a/src/script.c b/src/script.c index 23bf51445..0a84d7c0f 100644 --- a/src/script.c +++ b/src/script.c @@ -346,7 +346,7 @@ static int scriptVerifyACL(client *c, sds *err) { int acl_retval = ACLCheckAllPerm(c, &acl_errpos); if (acl_retval != ACL_OK) { addACLLogEntry(c, acl_retval, ACL_LOG_CTX_LUA, acl_errpos, NULL, NULL); - sds msg = getAclErrorMessage(acl_retval, c->user, c->cmd, c->argv[acl_errpos]->ptr, 0); + sds msg = getAclErrorMessage(acl_retval, c->user, c->cmd, objectGetVal(c->argv[acl_errpos]), 0); *err = sdscatsds(sdsnew("ACL failure in script: "), msg); sdsfree(msg); return C_ERR; @@ -378,7 +378,7 @@ static int scriptVerifyWriteCommandAllow(scriptRunCtx *run_ctx, char **err) { int deny_write_type = writeCommandsDeniedByDiskError(); if (server.primary_host && server.repl_replica_ro && !mustObeyClient(run_ctx->original_client)) { - *err = sdsdup(shared.roreplicaerr->ptr); + *err = sdsdup(objectGetVal(shared.roreplicaerr)); return C_ERR; } @@ -392,7 +392,7 @@ static int scriptVerifyWriteCommandAllow(scriptRunCtx *run_ctx, char **err) { * for Eval scripts that didn't declare flags, see the other check in * scriptPrepareForRun */ if (!checkGoodReplicasStatus()) { - *err = sdsdup(shared.noreplicaserr->ptr); + *err = sdsdup(objectGetVal(shared.noreplicaserr)); return C_ERR; } @@ -415,7 +415,7 @@ static int scriptVerifyOOM(scriptRunCtx *run_ctx, char **err) { !(run_ctx->flags & SCRIPT_WRITE_DIRTY) && /* Script had no side effects so far. */ server.pre_command_oom_state && /* Detected OOM when script start. */ (run_ctx->c->cmd->flags & CMD_DENYOOM)) { - *err = sdsdup(shared.oomerr->ptr); + *err = sdsdup(objectGetVal(shared.oomerr)); return C_ERR; } diff --git a/src/scripting_engine.c b/src/scripting_engine.c index aa16e9699..309518336 100644 --- a/src/scripting_engine.c +++ b/src/scripting_engine.c @@ -571,9 +571,9 @@ void scriptingEngineDebuggerLog(robj *entry) { void scriptingEngineDebuggerLogWithMaxLen(robj *entry) { int trimmed = 0; - if (ds.maxlen && sdslen(entry->ptr) > ds.maxlen) { - sdsrange(entry->ptr, 0, ds.maxlen - 1); - entry->ptr = sdscatlen(entry->ptr, " ...", 4); + if (ds.maxlen && sdslen(objectGetVal(entry)) > ds.maxlen) { + sdsrange(objectGetVal(entry), 0, ds.maxlen - 1); + objectSetVal(entry, sdscatlen(objectGetVal(entry), " ...", 4)); trimmed = 1; } scriptingEngineDebuggerLog(entry); @@ -603,8 +603,8 @@ void scriptingEngineDebuggerFlushLogs(void) { listNode *ln = listFirst(ds.logs); robj *msg = ln->value; proto = sdscatlen(proto, "+", 1); - sdsmapchars(msg->ptr, "\r\n", " ", 2); - proto = sdscatsds(proto, msg->ptr); + sdsmapchars(objectGetVal(msg), "\r\n", " ", 2); + proto = sdscatsds(proto, objectGetVal(msg)); proto = sdscatlen(proto, "\r\n", 2); listDelNode(ds.logs, ln); } @@ -893,7 +893,7 @@ static int maxlenCommandHandler(robj **argv, size_t argc, void *context) { scriptingEngineDebuggerLog(createObject(OBJ_STRING, msg)); } else if (argc == 2) { long long new_maxlen; - if (string2ll(argv[1]->ptr, sdslen(argv[1]->ptr), &new_maxlen) && new_maxlen >= 0) { + if (string2ll(objectGetVal(argv[1]), sdslen(objectGetVal(argv[1])), &new_maxlen) && new_maxlen >= 0) { scriptingEngineDebuggerSetMaxlen((size_t)new_maxlen); if (new_maxlen == 0) { sds msg = sdscatfmt(sdsempty(), " replies are not truncated."); @@ -996,9 +996,9 @@ static const debuggerCommand *findCommand(robj **argv, size_t argc) { // Check built-in commands first. for (size_t i = 0; i < builtins_len; i++) { const debuggerCommand *cmd = &builtins[i]; - if ((sdslen(argv[0]->ptr) == cmd->prefix_len && - strncasecmp(cmd->name, argv[0]->ptr, cmd->prefix_len) == 0) || - strcasecmp(cmd->name, argv[0]->ptr) == 0) { + if ((sdslen(objectGetVal(argv[0])) == cmd->prefix_len && + strncasecmp(cmd->name, objectGetVal(argv[0]), cmd->prefix_len) == 0) || + strcasecmp(cmd->name, objectGetVal(argv[0])) == 0) { if (checkCommandParameters(cmd, argc)) { return cmd; } @@ -1008,9 +1008,9 @@ static const debuggerCommand *findCommand(robj **argv, size_t argc) { // Then check the commands exported by the scripting engine. for (size_t i = 0; i < ds.commands_len; i++) { const debuggerCommand *cmd = &ds.commands[i]; - if ((sdslen(argv[0]->ptr) == cmd->prefix_len && - strncasecmp(cmd->name, argv[0]->ptr, cmd->prefix_len) == 0) || - strcasecmp(cmd->name, argv[0]->ptr) == 0) { + if ((sdslen(objectGetVal(argv[0])) == cmd->prefix_len && + strncasecmp(cmd->name, objectGetVal(argv[0]), cmd->prefix_len) == 0) || + strcasecmp(cmd->name, objectGetVal(argv[0])) == 0) { if (checkCommandParameters(cmd, argc)) { return cmd; } diff --git a/src/sds.c b/src/sds.c index 0ebfbdd0f..faa773f7a 100644 --- a/src/sds.c +++ b/src/sds.c @@ -33,7 +33,6 @@ #include #include #include -#include #include "serverassert.h" #include "sds.h" #include "sdsalloc.h" @@ -65,17 +64,6 @@ char sdsReqType(size_t string_size) { #endif } -/* The maximum length of a string that can be stored with the given SDS type. */ -static inline size_t sdsTypeMaxSize(char type) { - if (type == SDS_TYPE_5) return (1 << 5) - 1; - if (type == SDS_TYPE_8) return (1 << 8) - 1; - if (type == SDS_TYPE_16) return (1 << 16) - 1; -#if (LONG_MAX == LLONG_MAX) - if (type == SDS_TYPE_32) return (1ll << 32) - 1; -#endif - return -1; /* this is equivalent to the max SDS_TYPE_64 or SDS_TYPE_32 */ -} - static inline int adjustTypeIfNeeded(char *type, int *hdrlen, size_t bufsize) { size_t usable = bufsize - *hdrlen - 1; if (*type != SDS_TYPE_5 && usable > sdsTypeMaxSize(*type)) { diff --git a/src/sds.h b/src/sds.h index 739f67aef..222b23d17 100644 --- a/src/sds.h +++ b/src/sds.h @@ -38,6 +38,7 @@ extern const char *SDS_NOINIT; #include #include #include +#include /* Constness: * @@ -117,6 +118,17 @@ static inline void sdsSetAuxBit(sds s, int bit, int value) { s[-1] = (char)flags; } +/* The maximum length of a string that can be stored with the given SDS type. */ +static inline size_t sdsTypeMaxSize(char type) { + if (type == SDS_TYPE_5) return (1 << 5) - 1; + if (type == SDS_TYPE_8) return (1 << 8) - 1; + if (type == SDS_TYPE_16) return (1 << 16) - 1; +#if (LONG_MAX == LLONG_MAX) + if (type == SDS_TYPE_32) return (1ll << 32) - 1; +#endif + return -1; /* this is equivalent to the max SDS_TYPE_64 or SDS_TYPE_32 */ +} + static inline size_t sdslen(const_sds s) { switch (sdsType(s)) { case SDS_TYPE_5: return SDS_TYPE_5_LEN(s[-1]); diff --git a/src/sentinel.c b/src/sentinel.c index bd579982e..f7b051dad 100644 --- a/src/sentinel.c +++ b/src/sentinel.c @@ -3107,7 +3107,7 @@ void sentinelConfigSetCommand(client *c) { /* Validate arguments are valid */ for (int i = 3; i < c->argc; i++) { - option = c->argv[i]->ptr; + option = objectGetVal(c->argv[i]); /* Validate option is valid */ if (dictFind(options_dict, option) == NULL) { @@ -3131,15 +3131,15 @@ void sentinelConfigSetCommand(client *c) { val = c->argv[++i]; if (!strcasecmp(option, "resolve-hostnames")) { - if ((yesnotoi(val->ptr)) == -1) goto badfmt; + if ((yesnotoi(objectGetVal(val))) == -1) goto badfmt; } else if (!strcasecmp(option, "announce-hostnames")) { - if ((yesnotoi(val->ptr)) == -1) goto badfmt; + if ((yesnotoi(objectGetVal(val))) == -1) goto badfmt; } else if (!strcasecmp(option, "announce-port")) { if (getLongLongFromObject(val, &numval) == C_ERR || numval < 0 || numval > 65535) goto badfmt; } else if (!strcasecmp(option, "loglevel")) { - if (!(!strcasecmp(val->ptr, "debug") || !strcasecmp(val->ptr, "verbose") || - !strcasecmp(val->ptr, "notice") || !strcasecmp(val->ptr, "warning") || - !strcasecmp(val->ptr, "nothing"))) + if (!(!strcasecmp(objectGetVal(val), "debug") || !strcasecmp(objectGetVal(val), "verbose") || + !strcasecmp(objectGetVal(val), "notice") || !strcasecmp(objectGetVal(val), "warning") || + !strcasecmp(objectGetVal(val), "nothing"))) goto badfmt; } } @@ -3147,31 +3147,31 @@ void sentinelConfigSetCommand(client *c) { /* Apply changes */ for (int i = 3; i < c->argc; i++) { int moreargs = (c->argc - 1) - i; - option = c->argv[i]->ptr; + option = objectGetVal(c->argv[i]); if (!strcasecmp(option, "loglevel") && moreargs > 0) { val = c->argv[++i]; - if (!strcasecmp(val->ptr, "debug")) + if (!strcasecmp(objectGetVal(val), "debug")) server.verbosity = LL_DEBUG; - else if (!strcasecmp(val->ptr, "verbose")) + else if (!strcasecmp(objectGetVal(val), "verbose")) server.verbosity = LL_VERBOSE; - else if (!strcasecmp(val->ptr, "notice")) + else if (!strcasecmp(objectGetVal(val), "notice")) server.verbosity = LL_NOTICE; - else if (!strcasecmp(val->ptr, "warning")) + else if (!strcasecmp(objectGetVal(val), "warning")) server.verbosity = LL_WARNING; - else if (!strcasecmp(val->ptr, "nothing")) + else if (!strcasecmp(objectGetVal(val), "nothing")) server.verbosity = LL_NOTHING; } else if (!strcasecmp(option, "resolve-hostnames") && moreargs > 0) { val = c->argv[++i]; - numval = yesnotoi(val->ptr); + numval = yesnotoi(objectGetVal(val)); sentinel.resolve_hostnames = numval; } else if (!strcasecmp(option, "announce-hostnames") && moreargs > 0) { val = c->argv[++i]; - numval = yesnotoi(val->ptr); + numval = yesnotoi(objectGetVal(val)); sentinel.announce_hostnames = numval; } else if (!strcasecmp(option, "announce-ip") && moreargs > 0) { val = c->argv[++i]; if (sentinel.announce_ip) sdsfree(sentinel.announce_ip); - sentinel.announce_ip = sdsnew(val->ptr); + sentinel.announce_ip = sdsnew(objectGetVal(val)); } else if (!strcasecmp(option, "announce-port") && moreargs > 0) { val = c->argv[++i]; getLongLongFromObject(val, &numval); @@ -3179,12 +3179,12 @@ void sentinelConfigSetCommand(client *c) { } else if (!strcasecmp(option, "sentinel-user") && moreargs > 0) { val = c->argv[++i]; sdsfree(sentinel.sentinel_auth_user); - sentinel.sentinel_auth_user = sdslen(val->ptr) == 0 ? NULL : sdsdup(val->ptr); + sentinel.sentinel_auth_user = sdslen(objectGetVal(val)) == 0 ? NULL : sdsdup(objectGetVal(val)); drop_conns = 1; } else if (!strcasecmp(option, "sentinel-pass") && moreargs > 0) { val = c->argv[++i]; sdsfree(sentinel.sentinel_auth_pass); - sentinel.sentinel_auth_pass = sdslen(val->ptr) == 0 ? NULL : sdsdup(val->ptr); + sentinel.sentinel_auth_pass = sdslen(objectGetVal(val)) == 0 ? NULL : sdsdup(objectGetVal(val)); drop_conns = 1; } else { /* Should never reach here */ @@ -3202,7 +3202,7 @@ exit: return; badfmt: - addReplyErrorFormat(c, "Invalid value '%s' to SENTINEL CONFIG SET '%s'", (char *)val->ptr, option); + addReplyErrorFormat(c, "Invalid value '%s' to SENTINEL CONFIG SET '%s'", (char *)objectGetVal(val), option); dictRelease(set_configs); } @@ -3214,7 +3214,7 @@ void sentinelConfigGetCommand(client *c) { /* Create a dictionary to store the input configs,to avoid adding duplicate twice */ dict *d = dictCreate(&externalStringType); for (int i = 3; i < c->argc; i++) { - pattern = c->argv[i]->ptr; + pattern = objectGetVal(c->argv[i]); /* If the string doesn't contain glob patterns and available in dictionary, don't look further, just continue. */ if (!strpbrk(pattern, "[*?") && dictFind(d, pattern)) continue; /* we want to print all the matched patterns and avoid printing duplicates twice */ @@ -3478,7 +3478,7 @@ void sentinelSetDebugConfigParameters(client *c) { /* Process option - value pairs. */ for (j = 2; j < c->argc; j++) { int moreargs = (c->argc - 1) - j; - option = c->argv[j]->ptr; + option = objectGetVal(c->argv[j]); long long ll; if (!strcasecmp(option, "info-period") && moreargs > 0) { @@ -3611,7 +3611,7 @@ void sentinelSetDebugConfigParameters(client *c) { return; badfmt: /* Bad format errors */ - addReplyErrorFormat(c, "Invalid argument '%s' for SENTINEL DEBUG '%s'", (char *)c->argv[badarg]->ptr, option); + addReplyErrorFormat(c, "Invalid argument '%s' for SENTINEL DEBUG '%s'", (char *)objectGetVal(c->argv[badarg]), option); return; } @@ -3704,7 +3704,7 @@ void addReplyDictOfValkeyInstances(client *c, dict *instances) { sentinelValkeyInstance *sentinelGetPrimaryByNameOrReplyError(client *c, robj *name) { sentinelValkeyInstance *ri; - ri = dictFetchValue(sentinel.primaries, name->ptr); + ri = dictFetchValue(sentinel.primaries, objectGetVal(name)); if (!ri) { addReplyError(c, "No such master with that name"); return NULL; @@ -3738,7 +3738,7 @@ int sentinelIsQuorumReachable(sentinelValkeyInstance *primary, int *usableptr) { } void sentinelCommand(client *c) { - if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr, "help")) { + if (c->argc == 2 && !strcasecmp(objectGetVal(c->argv[1]), "help")) { const char *help[] = { "CKQUORUM ", " Check if the current Sentinel configuration is able to reach the quorum", @@ -3789,36 +3789,36 @@ void sentinelCommand(client *c) { NULL, }; addReplyHelp(c, help); - } else if (!strcasecmp(c->argv[1]->ptr, "primaries") || !strcasecmp(c->argv[1]->ptr, "masters")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "primaries") || !strcasecmp(objectGetVal(c->argv[1]), "masters")) { /* SENTINEL PRIMARIES */ if (c->argc != 2) goto numargserr; addReplyDictOfValkeyInstances(c, sentinel.primaries); - } else if (!strcasecmp(c->argv[1]->ptr, "primary") || !strcasecmp(c->argv[1]->ptr, "master")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "primary") || !strcasecmp(objectGetVal(c->argv[1]), "master")) { /* SENTINEL PRIMARY */ sentinelValkeyInstance *ri; if (c->argc != 3) goto numargserr; if ((ri = sentinelGetPrimaryByNameOrReplyError(c, c->argv[2])) == NULL) return; addReplySentinelValkeyInstance(c, ri); - } else if (!strcasecmp(c->argv[1]->ptr, "slaves") || !strcasecmp(c->argv[1]->ptr, "replicas")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "slaves") || !strcasecmp(objectGetVal(c->argv[1]), "replicas")) { /* SENTINEL REPLICAS */ sentinelValkeyInstance *ri; if (c->argc != 3) goto numargserr; if ((ri = sentinelGetPrimaryByNameOrReplyError(c, c->argv[2])) == NULL) return; addReplyDictOfValkeyInstances(c, ri->replicas); - } else if (!strcasecmp(c->argv[1]->ptr, "sentinels")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "sentinels")) { /* SENTINEL SENTINELS */ sentinelValkeyInstance *ri; if (c->argc != 3) goto numargserr; if ((ri = sentinelGetPrimaryByNameOrReplyError(c, c->argv[2])) == NULL) return; addReplyDictOfValkeyInstances(c, ri->sentinels); - } else if (!strcasecmp(c->argv[1]->ptr, "myid") && c->argc == 2) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "myid") && c->argc == 2) { /* SENTINEL MYID */ addReplyBulkCBuffer(c, sentinel.myid, CONFIG_RUN_ID_SIZE); - } else if (!strcasecmp(c->argv[1]->ptr, "is-primary-down-by-addr") || - !strcasecmp(c->argv[1]->ptr, "is-master-down-by-addr")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "is-primary-down-by-addr") || + !strcasecmp(objectGetVal(c->argv[1]), "is-master-down-by-addr")) { /* SENTINEL IS-PRIMARY-DOWN-BY-ADDR * * Arguments: @@ -3847,7 +3847,7 @@ void sentinelCommand(client *c) { if (getLongFromObjectOrReply(c, c->argv[3], &port, NULL) != C_OK || getLongLongFromObjectOrReply(c, c->argv[4], &req_epoch, NULL) != C_OK) return; - ri = getSentinelValkeyInstanceByAddrAndRunID(sentinel.primaries, c->argv[2]->ptr, port, NULL); + ri = getSentinelValkeyInstanceByAddrAndRunID(sentinel.primaries, objectGetVal(c->argv[2]), port, NULL); /* It exists? Is actually a primary? Is subjectively down? It's down. * Note: if we are in tilt mode we always reply with "0". */ @@ -3855,8 +3855,8 @@ void sentinelCommand(client *c) { /* Vote for the primary (or fetch the previous vote) if the request * includes a runid, otherwise the sender is not seeking for a vote. */ - if (ri && ri->flags & SRI_PRIMARY && strcasecmp(c->argv[5]->ptr, "*")) { - leader = sentinelVoteLeader(ri, (uint64_t)req_epoch, c->argv[5]->ptr, &leader_epoch); + if (ri && ri->flags & SRI_PRIMARY && strcasecmp(objectGetVal(c->argv[5]), "*")) { + leader = sentinelVoteLeader(ri, (uint64_t)req_epoch, objectGetVal(c->argv[5]), &leader_epoch); } /* Reply with a three-elements multi-bulk reply: @@ -3866,17 +3866,17 @@ void sentinelCommand(client *c) { addReplyBulkCString(c, leader ? leader : "*"); addReplyLongLong(c, (long long)leader_epoch); if (leader) sdsfree(leader); - } else if (!strcasecmp(c->argv[1]->ptr, "reset")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "reset")) { /* SENTINEL RESET */ if (c->argc != 3) goto numargserr; - addReplyLongLong(c, sentinelResetPrimariesByPattern(c->argv[2]->ptr, SENTINEL_GENERATE_EVENT)); - } else if (!strcasecmp(c->argv[1]->ptr, "get-primary-addr-by-name") || - !strcasecmp(c->argv[1]->ptr, "get-master-addr-by-name")) { + addReplyLongLong(c, sentinelResetPrimariesByPattern(objectGetVal(c->argv[2]), SENTINEL_GENERATE_EVENT)); + } else if (!strcasecmp(objectGetVal(c->argv[1]), "get-primary-addr-by-name") || + !strcasecmp(objectGetVal(c->argv[1]), "get-master-addr-by-name")) { /* SENTINEL GET-PRIMARY-ADDR-BY-NAME */ sentinelValkeyInstance *ri; if (c->argc != 3) goto numargserr; - ri = sentinelGetPrimaryByName(c->argv[2]->ptr); + ri = sentinelGetPrimaryByName(objectGetVal(c->argv[2])); if (ri == NULL) { addReplyNullArray(c); } else { @@ -3886,7 +3886,7 @@ void sentinelCommand(client *c) { addReplyBulkCString(c, announceSentinelAddr(addr)); addReplyBulkLongLong(c, addr->port); } - } else if (!strcasecmp(c->argv[1]->ptr, "failover")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "failover")) { /* SENTINEL FAILOVER */ sentinelValkeyInstance *ri; int coordinated = 0; @@ -3895,7 +3895,7 @@ void sentinelCommand(client *c) { if ((ri = sentinelGetPrimaryByNameOrReplyError(c, c->argv[2])) == NULL) return; if (c->argc == 4) { - if (!strcasecmp(c->argv[3]->ptr, "coordinated")) { + if (!strcasecmp(objectGetVal(c->argv[3]), "coordinated")) { coordinated = 1; if (ri->monitored_instance_failover_state == SENTINEL_MONITORED_INSTANCE_FAILOVER_NS) { addReplyError(c, "-NOGOODPRIMARY Primary does not support FAILOVER command"); @@ -3929,12 +3929,12 @@ void sentinelCommand(client *c) { ri->flags |= SRI_FORCE_FAILOVER; } addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "pending-scripts")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "pending-scripts")) { /* SENTINEL PENDING-SCRIPTS */ if (c->argc != 2) goto numargserr; sentinelPendingScriptsCommand(c); - } else if (!strcasecmp(c->argv[1]->ptr, "monitor")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "monitor")) { /* SENTINEL MONITOR */ sentinelValkeyInstance *ri; long quorum, port; @@ -3952,34 +3952,34 @@ void sentinelCommand(client *c) { /* If resolve-hostnames is used, actual DNS resolution may take place. * Otherwise just validate address. */ - if (anetResolve(NULL, c->argv[3]->ptr, ip, sizeof(ip), sentinel.resolve_hostnames ? ANET_NONE : ANET_IP_ONLY) == + if (anetResolve(NULL, objectGetVal(c->argv[3]), ip, sizeof(ip), sentinel.resolve_hostnames ? ANET_NONE : ANET_IP_ONLY) == ANET_ERR) { addReplyError(c, "Invalid IP address or hostname specified"); return; } /* Parameters are valid. Try to create the primary instance. */ - ri = createSentinelValkeyInstance(c->argv[2]->ptr, SRI_PRIMARY, c->argv[3]->ptr, port, quorum, NULL); + ri = createSentinelValkeyInstance(objectGetVal(c->argv[2]), SRI_PRIMARY, objectGetVal(c->argv[3]), port, quorum, NULL); if (ri == NULL) { addReplyError(c, sentinelCheckCreateInstanceErrors(SRI_PRIMARY)); } else { sentinelFlushConfigAndReply(c); sentinelEvent(LL_WARNING, "+monitor", ri, "%@ quorum %d", ri->quorum); } - } else if (!strcasecmp(c->argv[1]->ptr, "flushconfig")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "flushconfig")) { if (c->argc != 2) goto numargserr; sentinelFlushConfigAndReply(c); return; - } else if (!strcasecmp(c->argv[1]->ptr, "remove")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "remove")) { /* SENTINEL REMOVE */ sentinelValkeyInstance *ri; if (c->argc != 3) goto numargserr; if ((ri = sentinelGetPrimaryByNameOrReplyError(c, c->argv[2])) == NULL) return; sentinelEvent(LL_WARNING, "-monitor", ri, "%@"); - dictDelete(sentinel.primaries, c->argv[2]->ptr); + dictDelete(sentinel.primaries, objectGetVal(c->argv[2])); sentinelFlushConfigAndReply(c); - } else if (!strcasecmp(c->argv[1]->ptr, "ckquorum")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "ckquorum")) { /* SENTINEL CKQUORUM */ sentinelValkeyInstance *ri; int usable; @@ -4004,18 +4004,18 @@ void sentinelCommand(client *c) { } addReplyErrorSds(c, e); } - } else if (!strcasecmp(c->argv[1]->ptr, "set")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "set")) { sentinelSetCommand(c); - } else if (!strcasecmp(c->argv[1]->ptr, "config")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "config")) { if (c->argc < 4) goto numargserr; - if (!strcasecmp(c->argv[2]->ptr, "set") && c->argc >= 5) + if (!strcasecmp(objectGetVal(c->argv[2]), "set") && c->argc >= 5) sentinelConfigSetCommand(c); - else if (!strcasecmp(c->argv[2]->ptr, "get") && c->argc >= 4) + else if (!strcasecmp(objectGetVal(c->argv[2]), "get") && c->argc >= 4) sentinelConfigGetCommand(c); else addReplyError(c, "Only SENTINEL CONFIG GET [ ...] / SET [ " " ...] are supported."); - } else if (!strcasecmp(c->argv[1]->ptr, "info-cache")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "info-cache")) { /* SENTINEL INFO-CACHE */ if (c->argc < 2) goto numargserr; mstime_t now = mstime(); @@ -4031,7 +4031,7 @@ void sentinelCommand(client *c) { for (int i = 2; i < c->argc; i++) { sentinelValkeyInstance *ri; - ri = sentinelGetPrimaryByName(c->argv[i]->ptr); + ri = sentinelGetPrimaryByName(objectGetVal(c->argv[i])); if (!ri) continue; /* ignore non-existing names */ dictAdd(primaries_local, ri->name, ri); } @@ -4080,22 +4080,22 @@ void sentinelCommand(client *c) { } dictReleaseIterator(di); if (primaries_local != sentinel.primaries) dictRelease(primaries_local); - } else if (!strcasecmp(c->argv[1]->ptr, "simulate-failure")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "simulate-failure")) { /* SENTINEL SIMULATE-FAILURE [CRASH-AFTER-ELECTION] [CRASH-AFTER-PROMOTION] [HELP] */ int j; sentinel.simfailure_flags = SENTINEL_SIMFAILURE_NONE; for (j = 2; j < c->argc; j++) { - if (!strcasecmp(c->argv[j]->ptr, "crash-after-election")) { + if (!strcasecmp(objectGetVal(c->argv[j]), "crash-after-election")) { sentinel.simfailure_flags |= SENTINEL_SIMFAILURE_CRASH_AFTER_ELECTION; serverLog(LL_WARNING, "Failure simulation: this Sentinel " "will crash after being successfully elected as failover " "leader"); - } else if (!strcasecmp(c->argv[j]->ptr, "crash-after-promotion")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "crash-after-promotion")) { sentinel.simfailure_flags |= SENTINEL_SIMFAILURE_CRASH_AFTER_PROMOTION; serverLog(LL_WARNING, "Failure simulation: this Sentinel " "will crash after promoting the selected replica to master"); - } else if (!strcasecmp(c->argv[j]->ptr, "help")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "help")) { addReplyArrayLen(c, 2); addReplyBulkCString(c, "crash-after-election"); addReplyBulkCString(c, "crash-after-promotion"); @@ -4106,7 +4106,7 @@ void sentinelCommand(client *c) { } } addReply(c, shared.ok); - } else if (!strcasecmp(c->argv[1]->ptr, "debug")) { + } else if (!strcasecmp(objectGetVal(c->argv[1]), "debug")) { if (c->argc == 2) addReplySentinelDebugInfo(c); else @@ -4229,7 +4229,7 @@ void sentinelSetCommand(client *c) { /* Process option - value pairs. */ for (j = 3; j < c->argc; j++) { int moreargs = (c->argc - 1) - j; - option = c->argv[j]->ptr; + option = objectGetVal(c->argv[j]); long long ll; int old_j = j; /* Used to know what to log as an event. */ redacted = 0; @@ -4264,7 +4264,7 @@ void sentinelSetCommand(client *c) { changes++; } else if (!strcasecmp(option, "notification-script") && moreargs > 0) { /* notification-script */ - sds value = c->argv[++j]->ptr; + sds value = objectGetVal(c->argv[++j]); if (sentinel.deny_scripts_reconfig) { addReplyError(c, "Reconfiguration of scripts path is denied for " "security reasons. Check the deny-scripts-reconfig " @@ -4281,7 +4281,7 @@ void sentinelSetCommand(client *c) { changes++; } else if (!strcasecmp(option, "client-reconfig-script") && moreargs > 0) { /* client-reconfig-script */ - sds value = c->argv[++j]->ptr; + sds value = objectGetVal(c->argv[++j]); if (sentinel.deny_scripts_reconfig) { addReplyError(c, "Reconfiguration of scripts path is denied for " "security reasons. Check the deny-scripts-reconfig " @@ -4299,7 +4299,7 @@ void sentinelSetCommand(client *c) { changes++; } else if (!strcasecmp(option, "auth-pass") && moreargs > 0) { /* auth-pass */ - sds value = c->argv[++j]->ptr; + sds value = objectGetVal(c->argv[++j]); sdsfree(ri->auth_pass); ri->auth_pass = sdslen(value) ? sdsdup(value) : NULL; dropInstanceConnections(ri); @@ -4307,7 +4307,7 @@ void sentinelSetCommand(client *c) { redacted = 1; } else if (!strcasecmp(option, "auth-user") && moreargs > 0) { /* auth-user */ - sds value = c->argv[++j]->ptr; + sds value = objectGetVal(c->argv[++j]); sdsfree(ri->auth_user); ri->auth_user = sdslen(value) ? sdsdup(value) : NULL; dropInstanceConnections(ri); @@ -4323,8 +4323,8 @@ void sentinelSetCommand(client *c) { changes++; } else if (!strcasecmp(option, "rename-command") && moreargs > 1) { /* rename-command */ - sds oldname = c->argv[++j]->ptr; - sds newname = c->argv[++j]->ptr; + sds oldname = objectGetVal(c->argv[++j]); + sds newname = objectGetVal(c->argv[++j]); if ((sdslen(oldname) == 0) || (sdslen(newname) == 0)) { badarg = sdslen(newname) ? j - 1 : j; @@ -4365,21 +4365,21 @@ void sentinelSetCommand(client *c) { int numargs = j - old_j + 1; switch (numargs) { case 2: - sentinelEvent(LL_WARNING, "+set", ri, "%@ %s %s", (char *)c->argv[old_j]->ptr, - redacted ? "******" : (char *)c->argv[old_j + 1]->ptr); + sentinelEvent(LL_WARNING, "+set", ri, "%@ %s %s", (char *)objectGetVal(c->argv[old_j]), + redacted ? "******" : (char *)objectGetVal(c->argv[old_j + 1])); break; case 3: - sentinelEvent(LL_WARNING, "+set", ri, "%@ %s %s %s", (char *)c->argv[old_j]->ptr, - (char *)c->argv[old_j + 1]->ptr, (char *)c->argv[old_j + 2]->ptr); + sentinelEvent(LL_WARNING, "+set", ri, "%@ %s %s %s", (char *)objectGetVal(c->argv[old_j]), + (char *)objectGetVal(c->argv[old_j + 1]), (char *)objectGetVal(c->argv[old_j + 2])); break; - default: sentinelEvent(LL_WARNING, "+set", ri, "%@ %s", (char *)c->argv[old_j]->ptr); break; + default: sentinelEvent(LL_WARNING, "+set", ri, "%@ %s", (char *)objectGetVal(c->argv[old_j])); break; } } if (changes) sentinelFlushConfigAndReply(c); return; badfmt: /* Bad format errors */ - addReplyErrorFormat(c, "Invalid argument '%s' for SENTINEL SET '%s'", (char *)c->argv[badarg]->ptr, option); + addReplyErrorFormat(c, "Invalid argument '%s' for SENTINEL SET '%s'", (char *)objectGetVal(c->argv[badarg]), option); seterr: /* TODO: Handle the case of both bad input and save error, possibly handling * SENTINEL SET atomically. */ @@ -4393,11 +4393,11 @@ seterr: * Because we have a Sentinel PUBLISH, the code to send hello messages is the same * for all the three kind of instances: primaries, replicas, sentinels. */ void sentinelPublishCommand(client *c) { - if (strcmp(c->argv[1]->ptr, SENTINEL_HELLO_CHANNEL)) { + if (strcmp(objectGetVal(c->argv[1]), SENTINEL_HELLO_CHANNEL)) { addReplyError(c, "Only HELLO messages are accepted by Sentinel instances."); return; } - sentinelProcessHelloMessage(c->argv[2]->ptr, sdslen(c->argv[2]->ptr)); + sentinelProcessHelloMessage(objectGetVal(c->argv[2]), sdslen(objectGetVal(c->argv[2]))); addReplyLongLong(c, 1); } diff --git a/src/server.c b/src/server.c index 6dfe153f0..ce2bfe639 100644 --- a/src/server.c +++ b/src/server.c @@ -407,12 +407,12 @@ void *dictSdsDup(const void *key) { int dictObjKeyCompare(const void *key1, const void *key2) { const robj *o1 = key1, *o2 = key2; - return dictSdsKeyCompare(o1->ptr, o2->ptr); + return dictSdsKeyCompare(objectGetVal(o1), objectGetVal(o2)); } uint64_t dictObjHash(const void *key) { const robj *o = key; - return dictGenHashFunction(o->ptr, sdslen((sds)o->ptr)); + return dictGenHashFunction(objectGetVal(o), sdslen((sds)objectGetVal(o))); } uint64_t dictSdsHash(const void *key) { @@ -461,7 +461,7 @@ int dictEncObjKeyCompare(const void *key1, const void *key2) { robj *o1 = (robj *)key1, *o2 = (robj *)key2; int cmp; - if (o1->encoding == OBJ_ENCODING_INT && o2->encoding == OBJ_ENCODING_INT) return o1->ptr == o2->ptr; + if (o1->encoding == OBJ_ENCODING_INT && o2->encoding == OBJ_ENCODING_INT) return objectGetVal(o1) == objectGetVal(o2); /* Due to OBJ_STATIC_REFCOUNT, we avoid calling getDecodedObject() without * good reasons, because it would incrRefCount() the object, which @@ -469,7 +469,7 @@ int dictEncObjKeyCompare(const void *key1, const void *key2) { * objects as well. */ if (o1->refcount != OBJ_STATIC_REFCOUNT) o1 = getDecodedObject(o1); if (o2->refcount != OBJ_STATIC_REFCOUNT) o2 = getDecodedObject(o2); - cmp = dictSdsKeyCompare(o1->ptr, o2->ptr); + cmp = dictSdsKeyCompare(objectGetVal(o1), objectGetVal(o2)); if (o1->refcount != OBJ_STATIC_REFCOUNT) decrRefCount(o1); if (o2->refcount != OBJ_STATIC_REFCOUNT) decrRefCount(o2); return cmp; @@ -484,12 +484,12 @@ uint64_t dictEncObjHash(const void *key) { robj *o = (robj *)key; if (sdsEncodedObject(o)) { - return dictGenHashFunction(o->ptr, sdslen((sds)o->ptr)); + return dictGenHashFunction(objectGetVal(o), sdslen((sds)objectGetVal(o))); } else if (o->encoding == OBJ_ENCODING_INT) { char buf[32]; int len; - len = ll2string(buf, 32, (long)o->ptr); + len = ll2string(buf, 32, (long)objectGetVal(o)); return dictGenHashFunction((unsigned char *)buf, len); } else { serverPanic("Unknown string encoding"); @@ -584,13 +584,13 @@ void hashtableObjectPrefetchValue(const void *entry) { const robj *obj = entry; if (obj->encoding != OBJ_ENCODING_EMBSTR && obj->encoding != OBJ_ENCODING_INT) { - valkey_prefetch(obj->ptr); + valkey_prefetch(objectGetVal(obj)); } } int hashtableObjKeyCompare(const void *key1, const void *key2) { const robj *o1 = key1, *o2 = key2; - return hashtableSdsKeyCompare(o1->ptr, o2->ptr); + return hashtableSdsKeyCompare(objectGetVal(o1), objectGetVal(o2)); } void hashtableObjectDestructor(void *val) { @@ -3382,7 +3382,7 @@ struct serverCommand *lookupSubcommand(struct serverCommand *container, sds sub_ */ struct serverCommand *lookupCommandLogic(hashtable *commands, robj **argv, int argc, int strict) { void *entry = NULL; - bool found_command = hashtableFind(commands, argv[0]->ptr, &entry); + bool found_command = hashtableFind(commands, objectGetVal(argv[0]), &entry); struct serverCommand *base_cmd = entry; bool has_subcommands = found_command && base_cmd->subcommands_ht; if (argc == 1 || !has_subcommands) { @@ -3392,7 +3392,7 @@ struct serverCommand *lookupCommandLogic(hashtable *commands, robj **argv, int a } else { /* argc > 1 && has_subcommands */ if (strict && argc != 2) return NULL; /* Note: Currently we support just one level of subcommands */ - return lookupSubcommand(base_cmd, argv[1]->ptr); + return lookupSubcommand(base_cmd, objectGetVal(argv[1])); } } @@ -3974,7 +3974,7 @@ void rejectCommand(client *c, robj *reply) { c->duration = 0; if (c->cmd) c->cmd->rejected_calls++; if (c->cmd && c->cmd->proc == execCommand) { - execCommandAbort(c, reply->ptr); + execCommandAbort(c, objectGetVal(reply)); } else { /* using addReplyError* rather than addReply so that the error can be logged. */ addReplyErrorObject(c, reply); @@ -4027,22 +4027,22 @@ void afterCommand(client *c) { int commandCheckExistence(client *c, sds *err) { if (c->cmd) return 1; if (!err) return 0; - if (isContainerCommandBySds(c->argv[0]->ptr) && c->argc >= 2) { + if (isContainerCommandBySds(objectGetVal(c->argv[0])) && c->argc >= 2) { /* If we can't find the command but argv[0] by itself is a command * it means we're dealing with an invalid subcommand. Print Help. */ - sds cmd = sdsnew((char *)c->argv[0]->ptr); + sds cmd = sdsnew((char *)objectGetVal(c->argv[0])); sdstoupper(cmd); *err = sdsnew(NULL); - *err = sdscatprintf(*err, "unknown subcommand '%.128s'. Try %s HELP.", (char *)c->argv[1]->ptr, cmd); + *err = sdscatprintf(*err, "unknown subcommand '%.128s'. Try %s HELP.", (char *)objectGetVal(c->argv[1]), cmd); sdsfree(cmd); } else { sds args = sdsempty(); int i; for (i = 1; i < c->argc && sdslen(args) < 128; i++) - args = sdscatprintf(args, "'%.*s' ", 128 - (int)sdslen(args), (char *)c->argv[i]->ptr); + args = sdscatprintf(args, "'%.*s' ", 128 - (int)sdslen(args), (char *)objectGetVal(c->argv[i])); *err = sdsnew(NULL); *err = - sdscatprintf(*err, "unknown command '%.128s', with args beginning with: %s", (char *)c->argv[0]->ptr, args); + sdscatprintf(*err, "unknown command '%.128s', with args beginning with: %s", (char *)objectGetVal(c->argv[0]), args); sdsfree(args); } /* Make sure there are no newlines in the string, otherwise invalid protocol @@ -4173,7 +4173,7 @@ int processCommand(client *c) { struct serverCommand *cmd = c->parsed_cmd; if (!cmd) { /* Handle possible security attacks. */ - if (!strcasecmp(c->argv[0]->ptr, "host:") || !strcasecmp(c->argv[0]->ptr, "post")) { + if (!strcasecmp(objectGetVal(c->argv[0]), "host:") || !strcasecmp(objectGetVal(c->argv[0]), "post")) { securityWarningCommand(c); return C_ERR; } @@ -4251,7 +4251,7 @@ int processCommand(client *c) { if (acl_retval != ACL_OK) { addACLLogEntry(c, acl_retval, (c->flag.multi) ? ACL_LOG_CTX_MULTI : ACL_LOG_CTX_TOPLEVEL, acl_errpos, NULL, NULL); - sds msg = getAclErrorMessage(acl_retval, c->user, c->cmd, c->argv[acl_errpos]->ptr, 0); + sds msg = getAclErrorMessage(acl_retval, c->user, c->cmd, objectGetVal(c->argv[acl_errpos]), 0); rejectCommandFormat(c, "-NOPERM %s", msg); sdsfree(msg); return C_OK; @@ -4829,7 +4829,7 @@ int writeCommandsDeniedByDiskError(void) { sds writeCommandsGetDiskErrorMessage(int error_code) { sds ret = NULL; if (error_code == DISK_ERROR_TYPE_RDB) { - ret = sdsdup(shared.bgsaveerr->ptr); + ret = sdsdup(objectGetVal(shared.bgsaveerr)); } else { ret = sdscatfmt(sdsempty(), "-MISCONF Errors writing to the AOF file: %s\r\n", strerror(server.aof_last_write_errno)); @@ -5439,9 +5439,9 @@ void commandListCommand(client *c) { commandListFilter filter = {0}; for (; i < c->argc; i++) { int moreargs = (c->argc - 1) - i; /* Number of additional arguments. */ - char *opt = c->argv[i]->ptr; + char *opt = objectGetVal(c->argv[i]); if (!strcasecmp(opt, "filterby") && moreargs == 2) { - char *filtertype = c->argv[i + 1]->ptr; + char *filtertype = objectGetVal(c->argv[i + 1]); if (!strcasecmp(filtertype, "module")) { filter.type = COMMAND_LIST_FILTER_MODULE; } else if (!strcasecmp(filtertype, "aclcat")) { @@ -5453,7 +5453,7 @@ void commandListCommand(client *c) { return; } got_filter = 1; - filter.arg = c->argv[i + 2]->ptr; + filter.arg = objectGetVal(c->argv[i + 2]); i += 2; } else { addReplyErrorObject(c, shared.syntaxerr); @@ -5490,7 +5490,7 @@ void commandInfoCommand(client *c) { } else { addReplyArrayLen(c, c->argc - 2); for (i = 2; i < c->argc; i++) { - addReplyCommandInfo(c, lookupCommandBySds(c->argv[i]->ptr)); + addReplyCommandInfo(c, lookupCommandBySds(objectGetVal(c->argv[i]))); } } } @@ -5515,7 +5515,7 @@ void commandDocsCommand(client *c) { int numcmds = 0; void *replylen = addReplyDeferredLen(c); for (i = 2; i < c->argc; i++) { - struct serverCommand *cmd = lookupCommandBySds(c->argv[i]->ptr); + struct serverCommand *cmd = lookupCommandBySds(objectGetVal(c->argv[i])); if (!cmd) continue; addReplyBulkCBuffer(c, cmd->fullname, sdslen(cmd->fullname)); addReplyCommandDocs(c, cmd); @@ -5797,15 +5797,15 @@ dict *genInfoSectionDict(robj **argv, int argc, char **defaults, int *out_all, i dict *section_dict = dictCreate(&stringSetDictType); dictExpand(section_dict, min(argc, 16)); for (int i = 0; i < argc; i++) { - if (!strcasecmp(argv[i]->ptr, "default")) { + if (!strcasecmp(objectGetVal(argv[i]), "default")) { addInfoSectionsToDict(section_dict, defaults); - } else if (!strcasecmp(argv[i]->ptr, "all")) { + } else if (!strcasecmp(objectGetVal(argv[i]), "all")) { if (out_all) *out_all = 1; - } else if (!strcasecmp(argv[i]->ptr, "everything")) { + } else if (!strcasecmp(objectGetVal(argv[i]), "everything")) { if (out_everything) *out_everything = 1; if (out_all) *out_all = 1; } else { - sds section = sdsnew(argv[i]->ptr); + sds section = sdsnew(objectGetVal(argv[i])); if (dictAdd(section_dict, section, NULL) != DICT_OK) sdsfree(section); } } @@ -7491,7 +7491,7 @@ __attribute__((weak)) int main(int argc, char **argv) { int parseExtendedCommandArgumentsOrReply(client *c, int *flags, int *unit, robj **expire, robj **compare_val, int command_type, int max_args) { int j = command_type == COMMAND_SET ? 3 : 2; for (; j < max_args; j++) { - char *opt = c->argv[j]->ptr; + char *opt = objectGetVal(c->argv[j]); robj *next = (j == max_args - 1) ? NULL : c->argv[j + 1]; /* clang-format off */ diff --git a/src/server.h b/src/server.h index aba34428d..66a619ffd 100644 --- a/src/server.h +++ b/src/server.h @@ -785,7 +785,7 @@ typedef struct ValkeyModuleType moduleType; #define OBJ_ENCODING_STREAM 10 /* Encoded as a radix tree of listpacks */ #define OBJ_ENCODING_LISTPACK 11 /* Encoded as a listpack */ -#define OBJ_REFCOUNT_BITS 30 +#define OBJ_REFCOUNT_BITS 29 #define OBJ_SHARED_REFCOUNT ((1 << OBJ_REFCOUNT_BITS) - 1) /* Global object never destroyed. */ #define OBJ_STATIC_REFCOUNT ((1 << OBJ_REFCOUNT_BITS) - 2) /* Object allocated in the stack. */ #define OBJ_FIRST_SPECIAL_REFCOUNT OBJ_STATIC_REFCOUNT @@ -795,9 +795,12 @@ struct serverObject { unsigned lru : LRULFU_BITS; unsigned hasexpire : 1; unsigned hasembkey : 1; + unsigned hasembval : 1; unsigned refcount : OBJ_REFCOUNT_BITS; - void *ptr; + void *val_ptr; /* Not always present. Use objectGetVal(obj) and + * objectSetVal(obj, val) instead. */ }; +static_assert(sizeof(struct serverObject) <= 8 + sizeof(void *), "unexpected size - verify struct is packed correctly"); /* The string name for an object's type as listed above * Native types are checked against the OBJ_STRING, OBJ_LIST, OBJ_* defines, @@ -815,7 +818,8 @@ char *getObjectTypeName(robj *); _var.encoding = OBJ_ENCODING_RAW; \ _var.hasexpire = 0; \ _var.hasembkey = 0; \ - _var.ptr = _ptr; \ + _var.hasembval = 0; \ + _var.val_ptr = _ptr; \ } while (0) struct evictionPoolEntry; /* Defined in evict.c */ @@ -3011,7 +3015,7 @@ void dismissObject(robj *o, size_t dump_size); robj *createObject(int type, void *ptr); void initObjectLRUOrLFU(robj *o); robj *createStringObject(const char *ptr, size_t len); -robj *createStringObjectFromSds(const sds s); +robj *createStringObjectFromSds(const_sds s); robj *createRawStringObject(const char *ptr, size_t len); robj *tryCreateRawStringObject(const char *ptr, size_t len); robj *tryCreateStringObject(const char *ptr, size_t len); @@ -3054,12 +3058,14 @@ int equalStringObjects(robj *a, robj *b); void trimStringObjectIfNeeded(robj *o, int trim_small_values); #define sdsEncodedObject(objptr) (objptr->encoding == OBJ_ENCODING_RAW || objptr->encoding == OBJ_ENCODING_EMBSTR) -/* Objects with key attached, AKA valkey (val+key) objects */ -robj *createObjectWithKeyAndExpire(int type, void *ptr, const sds key, long long expire); -robj *objectSetKeyAndExpire(robj *val, sds key, long long expire); -robj *objectSetExpire(robj *val, long long expire); -sds objectGetKey(const robj *val); -long long objectGetExpire(const robj *val); +/* Objects with val and/or key embedded */ +robj *objectSetKeyAndExpire(robj *o, const_sds key, long long expire); +robj *objectSetExpire(robj *o, long long expire); +void objectSetVal(robj *o, void *val); +void objectUnembedVal(robj *o); +void *objectGetVal(const robj *o); +sds objectGetKey(const robj *o); +long long objectGetExpire(const robj *o); uint8_t objectGetLFUFrequency(robj *o); uint32_t objectGetLRUIdleSecs(robj *o); uint32_t objectGetIdleness(robj *o); diff --git a/src/sort.c b/src/sort.c index 5b2b93415..1794c6e0f 100644 --- a/src/sort.c +++ b/src/sort.c @@ -74,7 +74,7 @@ robj *lookupKeyByPattern(serverDb *db, robj *pattern, robj *subst) { /* If the pattern is "#" return the substitution object itself in order * to implement the "SORT ... GET #" feature. */ - spat = pattern->ptr; + spat = objectGetVal(pattern); if (isReturnSubstPattern(spat)) { incrRefCount(subst); return subst; @@ -84,7 +84,7 @@ robj *lookupKeyByPattern(serverDb *db, robj *pattern, robj *subst) { * a decoded object on the fly. Otherwise getDecodedObject will just * increment the ref count, that we'll decrement later. */ subst = getDecodedObject(subst); - ssub = subst->ptr; + ssub = objectGetVal(subst); /* If we can't find '*' in the pattern we return NULL as to GET a * fixed key does not make sense. */ @@ -107,7 +107,7 @@ robj *lookupKeyByPattern(serverDb *db, robj *pattern, robj *subst) { sublen = sdslen(ssub); postfixlen = sdslen(spat) - (prefixlen + 1) - (fieldlen ? fieldlen + 2 : 0); keyobj = createStringObject(NULL, prefixlen + sublen + postfixlen); - k = keyobj->ptr; + k = objectGetVal(keyobj); memcpy(k, spat, prefixlen); memcpy(k + prefixlen, ssub, sublen); memcpy(k + prefixlen + sublen, p + 1, postfixlen); @@ -122,7 +122,7 @@ robj *lookupKeyByPattern(serverDb *db, robj *pattern, robj *subst) { /* Retrieve value from hash by the field name. The returned object * is a new object with refcount already incremented. */ - o = hashTypeGetValueObject(o, fieldobj->ptr); + o = hashTypeGetValueObject(o, objectGetVal(fieldobj)); } else { if (o->type != OBJ_STRING) goto noobj; @@ -177,7 +177,7 @@ int sortCompare(const void *s1, const void *s2) { } else { /* Here we can use strcoll() directly as we are sure that * the objects are decoded string objects. */ - cmp = strcoll(so1->u.cmpobj->ptr, so2->u.cmpobj->ptr); + cmp = strcoll(objectGetVal(so1->u.cmpobj), objectGetVal(so2->u.cmpobj)); } } } else { @@ -218,34 +218,34 @@ void sortCommandGeneric(client *c, int readonly) { /* The SORT command has an SQL-alike syntax, parse it */ while (j < c->argc) { int leftargs = c->argc - j - 1; - if (!strcasecmp(c->argv[j]->ptr, "asc")) { + if (!strcasecmp(objectGetVal(c->argv[j]), "asc")) { desc = 0; - } else if (!strcasecmp(c->argv[j]->ptr, "desc")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "desc")) { desc = 1; - } else if (!strcasecmp(c->argv[j]->ptr, "alpha")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "alpha")) { alpha = 1; - } else if (!strcasecmp(c->argv[j]->ptr, "limit") && leftargs >= 2) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "limit") && leftargs >= 2) { if ((getLongFromObjectOrReply(c, c->argv[j + 1], &limit_start, NULL) != C_OK) || (getLongFromObjectOrReply(c, c->argv[j + 2], &limit_count, NULL) != C_OK)) { syntax_error++; break; } j += 2; - } else if (readonly == 0 && !strcasecmp(c->argv[j]->ptr, "store") && leftargs >= 1) { + } else if (readonly == 0 && !strcasecmp(objectGetVal(c->argv[j]), "store") && leftargs >= 1) { storekey = c->argv[j + 1]; j++; - } else if (!strcasecmp(c->argv[j]->ptr, "by") && leftargs >= 1) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "by") && leftargs >= 1) { sortby = c->argv[j + 1]; /* If the BY pattern does not contain '*', i.e. it is constant, * we don't need to sort nor to lookup the weight keys. */ - if (strchr(c->argv[j + 1]->ptr, '*') == NULL) { + if (strchr(objectGetVal(c->argv[j + 1]), '*') == NULL) { dontsort = 1; } else { /* If BY is specified with a real pattern, we can't accept it in cluster mode, * unless we can make sure the keys formed by the pattern are in the same slot * as the key to sort. */ if (server.cluster_enabled && - patternHashSlot(sortby->ptr, sdslen(sortby->ptr)) != getKeySlot(c->argv[1]->ptr)) { + patternHashSlot(objectGetVal(sortby), sdslen(objectGetVal(sortby))) != getKeySlot(objectGetVal(c->argv[1]))) { addReplyError(c, "BY option of SORT denied in Cluster mode when " "keys formed by the pattern may be in different slots."); syntax_error++; @@ -260,13 +260,13 @@ void sortCommandGeneric(client *c, int readonly) { } } j++; - } else if (!strcasecmp(c->argv[j]->ptr, "get") && leftargs >= 1) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "get") && leftargs >= 1) { /* If GET is specified with a real pattern, we can't accept it in cluster mode, * unless we can make sure the keys formed by the pattern are in the same slot * as the key to sort. */ if (server.cluster_enabled && - !isReturnSubstPattern(c->argv[j + 1]->ptr) && - patternHashSlot(c->argv[j + 1]->ptr, sdslen(c->argv[j + 1]->ptr)) != getKeySlot(c->argv[1]->ptr)) { + !isReturnSubstPattern(objectGetVal(c->argv[j + 1])) && + patternHashSlot(objectGetVal(c->argv[j + 1]), sdslen(objectGetVal(c->argv[j + 1]))) != getKeySlot(objectGetVal(c->argv[1]))) { addReplyError(c, "GET option of SORT denied in Cluster mode when " "keys formed by the pattern may be in different slots."); syntax_error++; @@ -330,7 +330,7 @@ void sortCommandGeneric(client *c, int readonly) { switch (sortval->type) { case OBJ_LIST: vectorlen = listTypeLength(sortval); break; case OBJ_SET: vectorlen = setTypeSize(sortval); break; - case OBJ_ZSET: vectorlen = hashtableSize(((zset *)sortval->ptr)->ht); break; + case OBJ_ZSET: vectorlen = hashtableSize(((zset *)objectGetVal(sortval))->ht); break; default: vectorlen = 0; serverPanic("Bad SORT type"); /* Avoid GCC warning */ } @@ -415,7 +415,7 @@ void sortCommandGeneric(client *c, int readonly) { * Note that in this case we also handle LIMIT here in a direct * way, just getting the required range, as an optimization. */ - zset *zs = sortval->ptr; + zset *zs = objectGetVal(sortval); zskiplist *zsl = zs->zsl; zskiplistNode *ln; sds sdsele; @@ -423,7 +423,7 @@ void sortCommandGeneric(client *c, int readonly) { /* Check if starting point is trivial, before doing log(N) lookup. */ if (desc) { - long zsetlen = hashtableSize(((zset *)sortval->ptr)->ht); + long zsetlen = hashtableSize(((zset *)objectGetVal(sortval))->ht); ln = zsl->tail; if (start > 0) ln = zslGetElementByRank(zsl, zsetlen - start); @@ -445,7 +445,7 @@ void sortCommandGeneric(client *c, int readonly) { end -= start; start = 0; } else if (sortval->type == OBJ_ZSET) { - hashtable *ht = ((zset *)sortval->ptr)->ht; + hashtable *ht = ((zset *)objectGetVal(sortval))->ht; hashtableIterator iter; hashtableInitIterator(&iter, ht, 0); void *next; @@ -482,7 +482,7 @@ void sortCommandGeneric(client *c, int readonly) { if (sdsEncodedObject(byval)) { char *eptr; errno = 0; - vector[j].u.score = valkey_strtod(byval->ptr, &eptr); + vector[j].u.score = valkey_strtod(objectGetVal(byval), &eptr); if (eptr[0] != '\0' || errno == ERANGE || errno == EINVAL || isnan(vector[j].u.score)) { int_conversion_error = 1; } @@ -490,7 +490,7 @@ void sortCommandGeneric(client *c, int readonly) { /* Don't need to decode the object if it's * integer-encoded (the only encoding supported) so * far. We can just cast it */ - vector[j].u.score = (long)byval->ptr; + vector[j].u.score = (long)objectGetVal(byval); } else { serverAssertWithInfo(c, sortval, 1 != 1); } diff --git a/src/t_hash.c b/src/t_hash.c index 0e4d29417..d9aadf3dd 100644 --- a/src/t_hash.c +++ b/src/t_hash.c @@ -63,7 +63,7 @@ static long long entryGetExpiryVsetFunc(const void *e) { static vset *hashTypeGetVolatileSet(robj *o) { serverAssert(o->encoding == OBJ_ENCODING_HASHTABLE); - vset *set = (vset *)hashtableMetadata(o->ptr); + vset *set = (vset *)hashtableMetadata(objectGetVal(o)); return vsetIsValid(set) ? set : NULL; } @@ -86,13 +86,13 @@ static inline void hashTypeIgnoreTTL(robj *o, bool ignore) { if (!ignore && hashTypeGetVolatileSet(o) == NULL) { ignore = true; } - hashtableSetType(o->ptr, ignore ? &hashHashtableType : &hashWithVolatileItemsHashtableType); + hashtableSetType(objectGetVal(o), ignore ? &hashHashtableType : &hashWithVolatileItemsHashtableType); } } static vset *hashTypeGetOrcreateVolatileSet(robj *o) { serverAssert(o->encoding == OBJ_ENCODING_HASHTABLE); - vset *set = (vset *)hashtableMetadata(o->ptr); + vset *set = (vset *)hashtableMetadata(objectGetVal(o)); if (!vsetIsValid(set)) { vsetInit(set); /* serves mainly for optimization. Use type which supports access function only when needed. */ @@ -102,7 +102,7 @@ static vset *hashTypeGetOrcreateVolatileSet(robj *o) { } void hashTypeFreeVolatileSet(robj *o) { - vset *set = (vset *)hashtableMetadata(o->ptr); + vset *set = (vset *)hashtableMetadata(objectGetVal(o)); if (vsetIsValid(set)) vsetRelease(set); /* serves mainly for optimization. by changing the hashtable type we can avoid extra function call in hashtable access */ hashTypeIgnoreTTL(o, true); @@ -177,20 +177,20 @@ void hashTypeTryConversion(robj *o, robj **argv, int start, int end) { size_t new_fields = (end - start + 1) / 2; if (new_fields > server.hash_max_listpack_entries) { hashTypeConvert(o, OBJ_ENCODING_HASHTABLE); - hashtableExpand(o->ptr, new_fields); + hashtableExpand(objectGetVal(o), new_fields); return; } for (i = start; i <= end; i++) { if (!sdsEncodedObject(argv[i])) continue; - size_t len = sdslen(argv[i]->ptr); + size_t len = sdslen(objectGetVal(argv[i])); if (len > server.hash_max_listpack_value) { hashTypeConvert(o, OBJ_ENCODING_HASHTABLE); return; } sum += len; } - if (!lpSafeToAdd(o->ptr, sum)) hashTypeConvert(o, OBJ_ENCODING_HASHTABLE); + if (!lpSafeToAdd(objectGetVal(o), sum)) hashTypeConvert(o, OBJ_ENCODING_HASHTABLE); } /* Get the value from a listpack encoded hash, identified by field. @@ -200,7 +200,7 @@ int hashTypeGetFromListpack(robj *o, sds field, unsigned char **vstr, unsigned i serverAssert(o->encoding == OBJ_ENCODING_LISTPACK); - zl = o->ptr; + zl = objectGetVal(o); fptr = lpFirst(zl); if (fptr != NULL) { fptr = lpFind(zl, fptr, (unsigned char *)field, sdslen(field), 1); @@ -240,7 +240,7 @@ int hashTypeGetValue(robj *o, sds field, unsigned char **vstr, unsigned int *vle } } else if (o->encoding == OBJ_ENCODING_HASHTABLE) { void *entry = NULL; - hashtableFind(o->ptr, field, &entry); + hashtableFind(objectGetVal(o), field, &entry); if (entry) { sds value = entryGetValue(entry); serverAssert(value != NULL); @@ -267,7 +267,7 @@ int hashTypeGetExpiry(robj *o, sds field, long long *expiry) { } } else if (o->encoding == OBJ_ENCODING_HASHTABLE) { void *found_element = NULL; - if (hashtableFind(o->ptr, field, &found_element)) { + if (hashtableFind(objectGetVal(o), field, &found_element)) { if (expiry) *expiry = entryGetExpiry(found_element); return C_OK; } @@ -349,7 +349,7 @@ int hashTypeSet(robj *o, sds field, sds value, long long expiry, int flags) { if (o->encoding == OBJ_ENCODING_LISTPACK) { unsigned char *zl, *fptr, *vptr; - zl = o->ptr; + zl = objectGetVal(o); fptr = lpFirst(zl); if (fptr != NULL) { fptr = lpFind(zl, fptr, (unsigned char *)field, sdslen(field), 1); @@ -369,12 +369,12 @@ int hashTypeSet(robj *o, sds field, sds value, long long expiry, int flags) { zl = lpAppend(zl, (unsigned char *)field, sdslen(field)); zl = lpAppend(zl, (unsigned char *)value, sdslen(value)); } - o->ptr = zl; + objectSetVal(o, zl); /* Check if the listpack needs to be converted to a hash table */ if (hashTypeLength(o) > server.hash_max_listpack_entries) hashTypeConvert(o, OBJ_ENCODING_HASHTABLE); } else if (o->encoding == OBJ_ENCODING_HASHTABLE) { - hashtable *ht = o->ptr; + hashtable *ht = objectGetVal(o); sds v; if (flags & HASH_SET_TAKE_VALUE) { @@ -462,7 +462,7 @@ static expiryModificationResult hashTypeSetExpire(robj *o, sds field, long long /* we must be hashtable encoded */ serverAssert(o->encoding == OBJ_ENCODING_HASHTABLE); - hashtable *ht = o->ptr; + hashtable *ht = objectGetVal(o); void **entry_ref = NULL; if ((entry_ref = hashtableFindRef(ht, field))) { entry *current_entry = *entry_ref; @@ -520,7 +520,7 @@ static expiryModificationResult hashTypePersist(robj *o, sds field) { return EXPIRATION_MODIFICATION_NOT_EXIST; // Did not find any element return -2 } - hashtable *ht = o->ptr; + hashtable *ht = objectGetVal(o); void **entry_ref = NULL; if ((entry_ref = hashtableFindRef(ht, field))) { entry *current_entry = *entry_ref; @@ -543,19 +543,19 @@ bool hashTypeDelete(robj *o, sds field) { if (o->encoding == OBJ_ENCODING_LISTPACK) { unsigned char *zl, *fptr; - zl = o->ptr; + zl = objectGetVal(o); fptr = lpFirst(zl); if (fptr != NULL) { fptr = lpFind(zl, fptr, (unsigned char *)field, sdslen(field), 1); if (fptr != NULL) { /* Delete both field and value. */ zl = lpDeleteRangeWithEntry(zl, &fptr, 2); - o->ptr = zl; + objectSetVal(o, zl); deleted = true; } } } else if (o->encoding == OBJ_ENCODING_HASHTABLE) { - hashtable *ht = o->ptr; + hashtable *ht = objectGetVal(o); void *entry = NULL; deleted = hashtablePop(ht, field, &entry); if (deleted) { @@ -572,9 +572,9 @@ bool hashTypeDelete(robj *o, sds field) { unsigned long hashTypeLength(const robj *o) { switch (o->encoding) { case OBJ_ENCODING_LISTPACK: - return lpLength(o->ptr) / 2; + return lpLength(objectGetVal(o)) / 2; case OBJ_ENCODING_HASHTABLE: - return hashtableSize((const hashtable *)o->ptr); + return hashtableSize((const hashtable *)objectGetVal(o)); default: serverPanic("Unknown hash encoding"); return ULONG_MAX; @@ -590,7 +590,7 @@ void hashTypeInitIterator(robj *subject, hashTypeIterator *hi) { hi->fptr = NULL; hi->vptr = NULL; } else if (hi->encoding == OBJ_ENCODING_HASHTABLE) { - hashtableInitIterator(&hi->iter, subject->ptr, 0); + hashtableInitIterator(&hi->iter, objectGetVal(subject), 0); } else { serverPanic("Unknown hash encoding"); } @@ -629,7 +629,7 @@ int hashTypeNext(hashTypeIterator *hi) { /* listpack encoding does not have volatile items, so return as iteration end */ if (hi->volatile_items_iter) return C_ERR; - zl = hi->subject->ptr; + zl = objectGetVal(hi->subject); fptr = hi->fptr; vptr = hi->vptr; @@ -762,14 +762,14 @@ void hashTypeConvertListpack(robj *o, int enc) { if (!hashtableAdd(ht, entry)) { entryFree(entry); hashTypeResetIterator(&hi); /* Needed for gcc ASAN */ - serverLogHexDump(LL_WARNING, "listpack with dup elements dump", o->ptr, lpBytes(o->ptr)); + serverLogHexDump(LL_WARNING, "listpack with dup elements dump", objectGetVal(o), lpBytes(objectGetVal(o))); serverPanic("Listpack corruption detected"); } } hashTypeResetIterator(&hi); - zfree(o->ptr); + zfree(objectGetVal(o)); o->encoding = OBJ_ENCODING_HASHTABLE; - o->ptr = ht; + objectSetVal(o, ht); } else { serverPanic("Unknown hash encoding"); } @@ -797,7 +797,7 @@ robj *hashTypeDup(robj *o) { serverAssert(o->type == OBJ_HASH); if (o->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = o->ptr; + unsigned char *zl = objectGetVal(o); size_t sz = lpBytes(zl); unsigned char *new_zl = zmalloc(sz); memcpy(new_zl, zl, sz); @@ -805,7 +805,7 @@ robj *hashTypeDup(robj *o) { hobj->encoding = OBJ_ENCODING_LISTPACK; } else if (o->encoding == OBJ_ENCODING_HASHTABLE) { hashtable *ht = hashtableCreate(&hashHashtableType); - hashtableExpand(ht, hashtableSize((const hashtable *)o->ptr)); + hashtableExpand(ht, hashtableSize((const hashtable *)objectGetVal(o))); hobj = createObject(OBJ_HASH, ht); hobj->encoding = OBJ_ENCODING_HASHTABLE; @@ -851,7 +851,7 @@ static void hashTypeRandomElement(robj *hashobj, unsigned long hashsize, listpac int maxtries = 100; hashTypeIgnoreTTL(hashobj, true); while (!e) { - hashtableFairRandomEntry(hashobj->ptr, &e); + hashtableFairRandomEntry(objectGetVal(hashobj), &e); if (entryIsExpired(e) && --maxtries) { e = NULL; continue; @@ -875,7 +875,7 @@ static void hashTypeRandomElement(robj *hashobj, unsigned long hashsize, listpac } hashTypeIgnoreTTL(hashobj, false); } else if (hashobj->encoding == OBJ_ENCODING_LISTPACK) { - lpRandomPair(hashobj->ptr, hashsize, field, val); + lpRandomPair(objectGetVal(hashobj), hashsize, field, val); } else { serverPanic("Unknown hash encoding"); } @@ -895,7 +895,7 @@ void hincrbyCommand(client *c) { long long expiry = EXPIRY_NONE; if (getLongLongFromObjectOrReply(c, c->argv[3], &incr, NULL) != C_OK) return; if ((o = hashTypeLookupWriteOrCreate(c, c->argv[1])) == NULL) return; - if (hashTypeGetValue(o, c->argv[2]->ptr, &vstr, &vlen, &value, &expiry) == C_OK) { + if (hashTypeGetValue(o, objectGetVal(c->argv[2]), &vstr, &vlen, &value, &expiry) == C_OK) { if (vstr) { if (string2ll((char *)vstr, vlen, &value) == 0) { addReplyError(c, "hash value is not an integer"); @@ -914,7 +914,7 @@ void hincrbyCommand(client *c) { } value += incr; new = sdsfromlonglong(value); - hashTypeSet(o, c->argv[2]->ptr, new, expiry, HASH_SET_TAKE_VALUE); + hashTypeSet(o, objectGetVal(c->argv[2]), new, expiry, HASH_SET_TAKE_VALUE); signalModifiedKey(c, c->db, c->argv[1]); notifyKeyspaceEvent(NOTIFY_HASH, "hincrby", c->argv[1], c->db->id); server.dirty++; @@ -937,7 +937,7 @@ void hincrbyfloatCommand(client *c) { } if ((o = hashTypeLookupWriteOrCreate(c, c->argv[1])) == NULL) return; - if (hashTypeGetValue(o, c->argv[2]->ptr, &vstr, &vlen, &ll, &expiry) == C_OK) { + if (hashTypeGetValue(o, objectGetVal(c->argv[2]), &vstr, &vlen, &ll, &expiry) == C_OK) { if (vstr) { if (string2ld((char *)vstr, vlen, &value) == 0) { addReplyError(c, "hash value is not a float"); @@ -959,7 +959,7 @@ void hincrbyfloatCommand(client *c) { char buf[MAX_LONG_DOUBLE_CHARS]; int len = ld2string(buf, sizeof(buf), value, LD_STR_HUMAN); new = sdsnewlen(buf, len); - hashTypeSet(o, c->argv[2]->ptr, new, expiry, HASH_SET_TAKE_VALUE); + hashTypeSet(o, objectGetVal(c->argv[2]), new, expiry, HASH_SET_TAKE_VALUE); signalModifiedKey(c, c->db, c->argv[1]); notifyKeyspaceEvent(NOTIFY_HASH, "hincrbyfloat", c->argv[1], c->db->id); server.dirty++; @@ -1000,7 +1000,7 @@ void hgetCommand(client *c) { robj *o; if ((o = lookupKeyReadOrReply(c, c->argv[1], shared.null[c->resp])) == NULL || checkType(c, o, OBJ_HASH)) return; - addHashFieldToReply(c, o, c->argv[2]->ptr); + addHashFieldToReply(c, o, objectGetVal(c->argv[2])); } void hmgetCommand(client *c) { @@ -1015,7 +1015,7 @@ void hmgetCommand(client *c) { addReplyArrayLen(c, c->argc - 2); for (i = 2; i < c->argc; i++) { - addHashFieldToReply(c, o, c->argv[i]->ptr); + addHashFieldToReply(c, o, objectGetVal(c->argv[i])); } if (o && hashTypeLength(o) == 0) { dbDelete(c->db, c->argv[1]); @@ -1031,7 +1031,7 @@ void hdelCommand(client *c) { bool hash_volatile_items = hashTypeHasVolatileFields(o); for (j = 2; j < c->argc; j++) { - if (hashTypeDelete(o, c->argv[j]->ptr)) { + if (hashTypeDelete(o, objectGetVal(c->argv[j]))) { deleted++; if (hashTypeLength(o) == 0) { if (hash_volatile_items) dbUntrackKeyWithVolatileItems(c->db, o); @@ -1078,11 +1078,11 @@ void hgetdelCommand(client *c) { /* Reply with array of values and delete at the same time */ addReplyArrayLen(c, num_fields); for (i = fields_index; i < c->argc; i++) { - addHashFieldToReply(c, o, c->argv[i]->ptr); + addHashFieldToReply(c, o, objectGetVal(c->argv[i])); /* If hash doesn't exist, continue as already replied with NULL */ if (o == NULL) continue; - if (hashTypeDelete(o, c->argv[i]->ptr)) { + if (hashTypeDelete(o, objectGetVal(c->argv[i]))) { deleted++; if (hashTypeLength(o) == 0) { if (hash_volatile_items) dbUntrackKeyWithVolatileItems(c->db, o); @@ -1116,7 +1116,7 @@ void hstrlenCommand(client *c) { robj *o; if ((o = lookupKeyReadOrReply(c, c->argv[1], shared.czero)) == NULL || checkType(c, o, OBJ_HASH)) return; - addReplyLongLong(c, hashTypeGetValueLength(o, c->argv[2]->ptr)); + addReplyLongLong(c, hashTypeGetValueLength(o, objectGetVal(c->argv[2]))); } static void addHashIteratorCursorToReply(writePreparedClient *wpc, hashTypeIterator *hi, int what) { @@ -1141,12 +1141,12 @@ static void addHashIteratorCursorToReply(writePreparedClient *wpc, hashTypeItera void hsetnxCommand(client *c) { robj *o; if ((o = hashTypeLookupWriteOrCreate(c, c->argv[1])) == NULL) return; - if (hashTypeExists(o, c->argv[2]->ptr)) { + if (hashTypeExists(o, objectGetVal(c->argv[2]))) { addReply(c, shared.czero); } else { hashTypeTryConversion(o, c->argv, 2, 3); bool has_volatile_fields = hashTypeHasVolatileFields(o); - hashTypeSet(o, c->argv[2]->ptr, c->argv[3]->ptr, EXPIRY_NONE, HASH_SET_COPY | HASH_SET_KEEP_EXPIRY); + hashTypeSet(o, objectGetVal(c->argv[2]), objectGetVal(c->argv[3]), EXPIRY_NONE, HASH_SET_COPY | HASH_SET_KEEP_EXPIRY); if (has_volatile_fields != hashTypeHasVolatileFields(o)) { dbUpdateObjectWithVolatileItemsTracking(c->db, o); } @@ -1170,7 +1170,7 @@ void hsetCommand(client *c) { hashTypeTryConversion(o, c->argv, 2, c->argc - 1); bool has_volatile_fields = hashTypeHasVolatileFields(o); for (i = 2; i < c->argc; i += 2) { - created += !hashTypeSet(o, c->argv[i]->ptr, c->argv[i + 1]->ptr, EXPIRY_NONE, HASH_SET_COPY); + created += !hashTypeSet(o, objectGetVal(c->argv[i]), objectGetVal(c->argv[i + 1]), EXPIRY_NONE, HASH_SET_COPY); } if (has_volatile_fields != hashTypeHasVolatileFields(o)) { dbUpdateObjectWithVolatileItemsTracking(c->db, o); @@ -1180,7 +1180,7 @@ void hsetCommand(client *c) { server.dirty += (c->argc - 2) / 2; /* HMSET (deprecated) and HSET return value is different. */ - char *cmdname = c->argv[0]->ptr; + char *cmdname = objectGetVal(c->argv[0]); if (cmdname[1] == 's' || cmdname[1] == 'S') { /* HSET */ addReplyLongLong(c, created); @@ -1251,7 +1251,7 @@ void hsetexCommand(client *c) { int need_rewrite_argv = 0; for (; fields_index < c->argc - 1; fields_index++) { - if (!strcasecmp(c->argv[fields_index]->ptr, "fields")) { + if (!strcasecmp(objectGetVal(c->argv[fields_index]), "fields")) { /* checking optional flags */ if (parseExtendedCommandArgumentsOrReply(c, &flags, &unit, &expire, &comparison, COMMAND_HSET, fields_index++) != C_OK) return; if (getLongLongFromObjectOrReply(c, c->argv[fields_index++], &num_fields, NULL) != C_OK) return; @@ -1298,8 +1298,8 @@ void hsetexCommand(client *c) { if (o) { /* Key exists: check fields normally */ for (i = fields_index; i < c->argc; i += 2) { - if (((flags & ARGS_SET_FNX) && hashTypeExists(o, c->argv[i]->ptr)) || - ((flags & ARGS_SET_FXX) && !hashTypeExists(o, c->argv[i]->ptr))) { + if (((flags & ARGS_SET_FNX) && hashTypeExists(o, objectGetVal(c->argv[i]))) || + ((flags & ARGS_SET_FXX) && !hashTypeExists(o, objectGetVal(c->argv[i])))) { addReply(c, shared.czero); return; } @@ -1336,10 +1336,10 @@ void hsetexCommand(client *c) { new_argv = zmalloc(sizeof(robj *) * c->argc); // Copy optional args (skip NX/XX/FNX/FXX) for (int i = 0; i < fields_index; i++) { - if (strcmp(c->argv[i]->ptr, "NX") && - strcmp(c->argv[i]->ptr, "XX") && - strcmp(c->argv[i]->ptr, "FNX") && - strcmp(c->argv[i]->ptr, "FXX")) { + if (strcmp(objectGetVal(c->argv[i]), "NX") && + strcmp(objectGetVal(c->argv[i]), "XX") && + strcmp(objectGetVal(c->argv[i]), "FNX") && + strcmp(objectGetVal(c->argv[i]), "FXX")) { /* Propagate as HSETEX Key Value PXAT millisecond-timestamp if there is * EX/PX/EXAT flag. */ if (expire && !(flags & ARGS_PXAT) && c->argv[i + 1] == expire) { @@ -1357,7 +1357,7 @@ void hsetexCommand(client *c) { for (i = fields_index; i < c->argc; i += 2) { if (set_expired) { - if (hashTypeDelete(o, c->argv[i]->ptr)) { + if (hashTypeDelete(o, objectGetVal(c->argv[i]))) { new_argv[new_argc++] = c->argv[i]; incrRefCount(c->argv[i]); /* we treat this case exactly as active expiration. */ @@ -1365,7 +1365,7 @@ void hsetexCommand(client *c) { changes++; } } else { - hashTypeSet(o, c->argv[i]->ptr, c->argv[i + 1]->ptr, when, set_flags); + hashTypeSet(o, objectGetVal(c->argv[i]), objectGetVal(c->argv[i + 1]), when, set_flags); changes++; if (need_rewrite_argv) { new_argv[new_argc++] = c->argv[i]; @@ -1464,7 +1464,7 @@ void hgetexCommand(client *c) { int milliseconds_index = -1, numitems_index = -1; for (; fields_index < c->argc - 1; fields_index++) { - if (!strcasecmp(c->argv[fields_index]->ptr, "fields")) { + if (!strcasecmp(objectGetVal(c->argv[fields_index]), "fields")) { /* checking optional flags */ if (parseExtendedCommandArgumentsOrReply(c, &flags, &unit, &expire, &comparison, COMMAND_HGET, fields_index++) != C_OK) return; if (getLongLongFromObjectOrReply(c, c->argv[fields_index++], &num_fields, NULL) != C_OK) return; @@ -1533,15 +1533,15 @@ void hgetexCommand(client *c) { } for (i = fields_index; i < c->argc; i++) { bool changed = false; - addHashFieldToReply(c, o, c->argv[i]->ptr); + addHashFieldToReply(c, o, objectGetVal(c->argv[i])); if (o && set_expired) { - changed = hashTypeDelete(o, c->argv[i]->ptr); + changed = hashTypeDelete(o, objectGetVal(c->argv[i])); /* we treat this case exactly as active expiration. */ if (changed) server.stat_expiredfields++; } else if (set_expiry) { - changed = hashTypeSetExpire(o, c->argv[i]->ptr, when, 0) == EXPIRATION_MODIFICATION_SUCCESSFUL; + changed = hashTypeSetExpire(o, objectGetVal(c->argv[i]), when, 0) == EXPIRATION_MODIFICATION_SUCCESSFUL; } else if (persist) { - changed = hashTypePersist(o, c->argv[i]->ptr) == EXPIRATION_MODIFICATION_SUCCESSFUL; + changed = hashTypePersist(o, objectGetVal(c->argv[i])) == EXPIRATION_MODIFICATION_SUCCESSFUL; } if (changed) { changes++; @@ -1644,14 +1644,14 @@ void hgetallCommand(client *c) { void hexistsCommand(client *c) { robj *o; if ((o = lookupKeyReadOrReply(c, c->argv[1], shared.czero)) == NULL || checkType(c, o, OBJ_HASH)) return; - addReply(c, hashTypeExists(o, c->argv[2]->ptr) ? shared.cone : shared.czero); + addReply(c, hashTypeExists(o, objectGetVal(c->argv[2])) ? shared.cone : shared.czero); } void hscanCommand(client *c) { robj *o; unsigned long long cursor; - if (parseScanCursorOrReply(c, c->argv[2]->ptr, &cursor) == C_ERR) return; + if (parseScanCursorOrReply(c, objectGetVal(c->argv[2]), &cursor) == C_ERR) return; if ((o = lookupKeyReadOrReply(c, c->argv[1], shared.emptyscan)) == NULL || checkType(c, o, OBJ_HASH)) return; scanGenericCommand(c, o, cursor); } @@ -1721,7 +1721,7 @@ void hexpireGenericCommand(client *c, long long basetime, int unit) { int new_argc = 0; for (; fields_index < c->argc - 1; fields_index++) { - if (!strcasecmp(c->argv[fields_index]->ptr, "fields")) { + if (!strcasecmp(objectGetVal(c->argv[fields_index]), "fields")) { /* checking optional flags */ if (parseExtendedExpireArgumentsOrReply(c, &flag, fields_index++) != C_OK) return; if (getLongLongFromObjectOrReply(c, c->argv[fields_index++], &num_fields, NULL) != C_OK) return; @@ -1765,7 +1765,7 @@ void hexpireGenericCommand(client *c, long long basetime, int unit) { for (i = 0; i < num_fields; i++) { expiryModificationResult result = EXPIRATION_MODIFICATION_NOT_EXIST; if (set_expired) { - if (obj && hashTypeDelete(obj, c->argv[fields_index + i]->ptr)) { + if (obj && hashTypeDelete(obj, objectGetVal(c->argv[fields_index + i]))) { /* In case we deleted the field, add it to the new hdel command vector. */ new_argv[new_argc++] = c->argv[fields_index + i]; incrRefCount(c->argv[fields_index + i]); @@ -1775,7 +1775,7 @@ void hexpireGenericCommand(client *c, long long basetime, int unit) { expired++; } } else { - result = hashTypeSetExpire(obj, c->argv[fields_index + i]->ptr, when, flag); + result = hashTypeSetExpire(obj, objectGetVal(c->argv[fields_index + i]), when, flag); if (result == EXPIRATION_MODIFICATION_SUCCESSFUL) updated++; } addReplyLongLong(c, result); @@ -1869,7 +1869,7 @@ void hpersistCommand(client *c) { bool has_volatile_fields = hashTypeHasVolatileFields(hash); for (int i = 0; i < num_fields; i++, fields_index++) { - result = hashTypePersist(hash, c->argv[fields_index]->ptr); + result = hashTypePersist(hash, objectGetVal(c->argv[fields_index])); if (result == EXPIRATION_MODIFICATION_SUCCESSFUL) { server.dirty++; changes++; @@ -1933,7 +1933,7 @@ void httlGenericCommand(client *c, long long basetime, int unit) { addReplyArrayLen(c, num_fields); for (int i = 0; i < num_fields; i++) { - if (!hash || hashTypeGetExpiry(hash, c->argv[fields_index + i]->ptr, &result) == C_ERR) { + if (!hash || hashTypeGetExpiry(hash, objectGetVal(c->argv[fields_index + i]), &result) == C_ERR) { addReplyLongLong(c, -2); } else if (result == EXPIRY_NONE) { addReplyLongLong(c, -1); @@ -2030,7 +2030,7 @@ void hrandfieldWithCountCommand(client *c, long l, int withvalues) { sample_count = count > limit ? limit : count; count -= sample_count; reply_size += sample_count; - lpRandomPairs(hash->ptr, sample_count, fields, vals); + lpRandomPairs(objectGetVal(hash), sample_count, fields, vals); hrandfieldReplyWithListpack(wpc, sample_count, fields, vals); if (c->flag.close_asap) break; } @@ -2071,7 +2071,7 @@ void hrandfieldWithCountCommand(client *c, long l, int withvalues) { listpackEntry *fields, *vals = NULL; fields = zmalloc(sizeof(listpackEntry) * count); if (withvalues) vals = zmalloc(sizeof(listpackEntry) * count); - serverAssert(lpRandomPairsUnique(hash->ptr, count, fields, vals) == count); + serverAssert(lpRandomPairsUnique(objectGetVal(hash), count, fields, vals) == count); hrandfieldReplyWithListpack(wpc, count, fields, vals); zfree(fields); zfree(vals); @@ -2092,7 +2092,7 @@ void hrandfieldWithCountCommand(client *c, long l, int withvalues) { hashtable *ht = hashtableCreate(&sdsReplyHashtableType); hashtableExpand(ht, size); hashtableIterator iter; - hashtableInitIterator(&iter, hash->ptr, 0); + hashtableInitIterator(&iter, objectGetVal(hash), 0); void *entry; /* Add all the elements into the temporary hashtable. */ @@ -2182,7 +2182,7 @@ void hrandfieldCommand(client *c) { if (c->argc >= 3) { if (getRangeLongFromObjectOrReply(c, c->argv[2], -LONG_MAX, LONG_MAX, &l, NULL) != C_OK) return; - if (c->argc > 4 || (c->argc == 4 && strcasecmp(c->argv[3]->ptr, "withvalues"))) { + if (c->argc > 4 || (c->argc == 4 && strcasecmp(objectGetVal(c->argv[3]), "withvalues"))) { addReplyErrorObject(c, shared.syntaxerr); return; } else if (c->argc == 4) { @@ -2218,8 +2218,8 @@ typedef struct { static int hashTypeExpireEntry(void *entry, void *c) { expiryContext *ctx = c; robj *o = ctx->key; - serverAssert(o->encoding == OBJ_ENCODING_HASHTABLE && hashtableSize(o->ptr) > 0); - hashtable *ht = o->ptr; + serverAssert(o->encoding == OBJ_ENCODING_HASHTABLE && hashtableSize(objectGetVal(o)) > 0); + hashtable *ht = objectGetVal(o); void *entry_ptr = NULL; bool deleted = hashtablePop(ht, entry, &entry_ptr); if (deleted) { @@ -2276,7 +2276,7 @@ static void defragHashTypeEntry(void *privdata, void *element_ref) { size_t hashTypeScanDefrag(robj *ob, size_t cursor, void *(*defragAllocfn)(void *)) { if (ob->encoding == OBJ_ENCODING_LISTPACK) { unsigned char *newzl; - if ((newzl = activeDefragAlloc(ob->ptr))) ob->ptr = newzl; + if ((newzl = activeDefragAlloc(objectGetVal(ob)))) objectSetVal(ob, newzl); return 0; } serverAssert(ob->encoding == OBJ_ENCODING_HASHTABLE); @@ -2290,17 +2290,17 @@ size_t hashTypeScanDefrag(robj *ob, size_t cursor, void *(*defragAllocfn)(void * if (!vset_cursor) { /* New object scan */ - hashtable *ht = ob->ptr; + hashtable *ht = objectGetVal(ob); /* defrag the hashtable struct and tables */ hashtable *new_hashtable = hashtableDefragTables(ht, defragAllocfn); - if (new_hashtable) ob->ptr = new_hashtable; + if (new_hashtable) objectSetVal(ob, new_hashtable); vset_cursor = &volaSetIter; vset_cursor->cursor = 0; vset_cursor->is_vsetDefrag = false; } if (!vset_cursor->is_vsetDefrag) { - hashtable *ht = ob->ptr; + hashtable *ht = objectGetVal(ob); vset_cursor->cursor = hashtableScanDefrag(ht, vset_cursor->cursor, defragHashTypeEntry, ob, defragAllocfn, HASHTABLE_SCAN_EMIT_REF); diff --git a/src/t_list.c b/src/t_list.c index f072d6f7e..6c19036c7 100644 --- a/src/t_list.c +++ b/src/t_list.c @@ -48,24 +48,24 @@ static void listTypeTryConvertListpack(robj *o, robj **argv, int start, int end, if (argv) { for (int i = start; i <= end; i++) { if (!sdsEncodedObject(argv[i])) continue; - add_bytes += sdslen(argv[i]->ptr); + add_bytes += sdslen(objectGetVal(argv[i])); } add_length = end - start + 1; } - if (quicklistNodeExceedsLimit(server.list_max_listpack_size, lpBytes(o->ptr) + add_bytes, - lpLength(o->ptr) + add_length)) { + if (quicklistNodeExceedsLimit(server.list_max_listpack_size, lpBytes(objectGetVal(o)) + add_bytes, + lpLength(objectGetVal(o)) + add_length)) { /* Invoke callback before conversion. */ if (fn) fn(data); quicklist *ql = quicklistNew(server.list_max_listpack_size, server.list_compress_depth); /* Append listpack to quicklist if it's not empty, otherwise release it. */ - if (lpLength(o->ptr)) - quicklistAppendListpack(ql, o->ptr); + if (lpLength(objectGetVal(o))) + quicklistAppendListpack(ql, objectGetVal(o)); else - lpFree(o->ptr); - o->ptr = ql; + lpFree(objectGetVal(o)); + objectSetVal(o, ql); o->encoding = OBJ_ENCODING_QUICKLIST; } } @@ -84,7 +84,7 @@ static void listTypeTryConvertQuicklist(robj *o, int shrinking, beforeConvertCB size_t sz_limit; unsigned int count_limit; - quicklist *ql = o->ptr; + quicklist *ql = objectGetVal(o); /* A quicklist can be converted to listpack only if it has only one packed node. */ if (ql->len != 1 || ql->head->container != QUICKLIST_NODE_CONTAINER_PACKED) return; @@ -102,7 +102,7 @@ static void listTypeTryConvertQuicklist(robj *o, int shrinking, beforeConvertCB /* Extract the listpack from the unique quicklist node, * then reset it and release the quicklist. */ - o->ptr = ql->head->entry; + objectSetVal(o, ql->head->entry); ql->head->entry = NULL; quicklistRelease(ql); o->encoding = OBJ_ENCODING_LISTPACK; @@ -158,19 +158,21 @@ void listTypePush(robj *subject, robj *value, int where) { int pos = (where == LIST_HEAD) ? QUICKLIST_HEAD : QUICKLIST_TAIL; if (value->encoding == OBJ_ENCODING_INT) { char buf[32]; - ll2string(buf, 32, (long)value->ptr); - quicklistPush(subject->ptr, buf, strlen(buf), pos); + ll2string(buf, 32, (long)objectGetVal(value)); + quicklistPush(objectGetVal(subject), buf, strlen(buf), pos); } else { - quicklistPush(subject->ptr, value->ptr, sdslen(value->ptr), pos); + quicklistPush(objectGetVal(subject), objectGetVal(value), sdslen(objectGetVal(value)), pos); } } else if (subject->encoding == OBJ_ENCODING_LISTPACK) { + unsigned char *new_val = NULL; if (value->encoding == OBJ_ENCODING_INT) { - subject->ptr = (where == LIST_HEAD) ? lpPrependInteger(subject->ptr, (long)value->ptr) - : lpAppendInteger(subject->ptr, (long)value->ptr); + new_val = (where == LIST_HEAD) ? lpPrependInteger(objectGetVal(subject), (long)objectGetVal(value)) + : lpAppendInteger(objectGetVal(subject), (long)objectGetVal(value)); } else { - subject->ptr = (where == LIST_HEAD) ? lpPrepend(subject->ptr, value->ptr, sdslen(value->ptr)) - : lpAppend(subject->ptr, value->ptr, sdslen(value->ptr)); + new_val = (where == LIST_HEAD) ? lpPrepend(objectGetVal(subject), objectGetVal(value), sdslen(objectGetVal(value))) + : lpAppend(objectGetVal(subject), objectGetVal(value), sdslen(objectGetVal(value))); } + objectSetVal(subject, new_val); } else { serverPanic("Unknown list encoding"); } @@ -186,7 +188,7 @@ robj *listTypePop(robj *subject, int where) { if (subject->encoding == OBJ_ENCODING_QUICKLIST) { long long vlong; int ql_where = where == LIST_HEAD ? QUICKLIST_HEAD : QUICKLIST_TAIL; - if (quicklistPopCustom(subject->ptr, ql_where, (unsigned char **)&value, NULL, &vlong, listPopSaver)) { + if (quicklistPopCustom(objectGetVal(subject), ql_where, (unsigned char **)&value, NULL, &vlong, listPopSaver)) { if (!value) value = createStringObjectFromLongLong(vlong); } } else if (subject->encoding == OBJ_ENCODING_LISTPACK) { @@ -195,11 +197,11 @@ robj *listTypePop(robj *subject, int where) { int64_t vlen; unsigned char intbuf[LP_INTBUF_SIZE]; - p = (where == LIST_HEAD) ? lpFirst(subject->ptr) : lpLast(subject->ptr); + p = (where == LIST_HEAD) ? lpFirst(objectGetVal(subject)) : lpLast(objectGetVal(subject)); if (p) { vstr = lpGet(p, &vlen, intbuf); value = createStringObject((char *)vstr, vlen); - subject->ptr = lpDelete(subject->ptr, p, NULL); + objectSetVal(subject, lpDelete(objectGetVal(subject), p, NULL)); } } else { serverPanic("Unknown list encoding"); @@ -209,9 +211,9 @@ robj *listTypePop(robj *subject, int where) { unsigned long listTypeLength(const robj *subject) { if (subject->encoding == OBJ_ENCODING_QUICKLIST) { - return quicklistCount(subject->ptr); + return quicklistCount(objectGetVal(subject)); } else if (subject->encoding == OBJ_ENCODING_LISTPACK) { - return lpLength(subject->ptr); + return lpLength(objectGetVal(subject)); } else { serverPanic("Unknown list encoding"); } @@ -228,9 +230,9 @@ listTypeIterator *listTypeInitIterator(robj *subject, long index, unsigned char * LIST_TAIL means start at HEAD and move *towards* tail. */ if (li->encoding == OBJ_ENCODING_QUICKLIST) { int iter_direction = direction == LIST_HEAD ? AL_START_TAIL : AL_START_HEAD; - li->iter = quicklistGetIteratorAtIdx(li->subject->ptr, iter_direction, index); + li->iter = quicklistGetIteratorAtIdx(objectGetVal(li->subject), iter_direction, index); } else if (li->encoding == OBJ_ENCODING_LISTPACK) { - li->lpi = lpSeek(subject->ptr, index); + li->lpi = lpSeek(objectGetVal(subject), index); } else { serverPanic("Unknown list encoding"); } @@ -246,7 +248,7 @@ void listTypeSetIteratorDirection(listTypeIterator *li, listTypeEntry *entry, un int dir = direction == LIST_HEAD ? AL_START_TAIL : AL_START_HEAD; quicklistSetDirection(li->iter, dir); } else if (li->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *lp = li->subject->ptr; + unsigned char *lp = objectGetVal(li->subject); /* Note that the iterator for listpack always points to the next of the current entry, * so we need to update position of the iterator depending on the direction. */ li->lpi = (direction == LIST_TAIL) ? lpNext(lp, entry->lpe) : lpPrev(lp, entry->lpe); @@ -275,7 +277,7 @@ int listTypeNext(listTypeIterator *li, listTypeEntry *entry) { entry->lpe = li->lpi; if (entry->lpe != NULL) { li->lpi = - (li->direction == LIST_TAIL) ? lpNext(li->subject->ptr, li->lpi) : lpPrev(li->subject->ptr, li->lpi); + (li->direction == LIST_TAIL) ? lpNext(objectGetVal(li->subject), li->lpi) : lpPrev(objectGetVal(li->subject), li->lpi); return 1; } } else { @@ -323,7 +325,7 @@ robj *listTypeGet(listTypeEntry *entry) { void listTypeInsert(listTypeEntry *entry, robj *value, int where) { robj *subject = entry->li->subject; value = getDecodedObject(value); - sds str = value->ptr; + sds str = objectGetVal(value); size_t len = sdslen(str); if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) { @@ -334,7 +336,7 @@ void listTypeInsert(listTypeEntry *entry, robj *value, int where) { } } else if (entry->li->encoding == OBJ_ENCODING_LISTPACK) { int lpw = (where == LIST_TAIL) ? LP_AFTER : LP_BEFORE; - subject->ptr = lpInsertString(subject->ptr, (unsigned char *)str, len, entry->lpe, lpw, &entry->lpe); + objectSetVal(subject, lpInsertString(objectGetVal(subject), (unsigned char *)str, len, entry->lpe, lpw, &entry->lpe)); } else { serverPanic("Unknown list encoding"); } @@ -345,13 +347,13 @@ void listTypeInsert(listTypeEntry *entry, robj *value, int where) { void listTypeReplace(listTypeEntry *entry, robj *value) { robj *subject = entry->li->subject; value = getDecodedObject(value); - sds str = value->ptr; + sds str = objectGetVal(value); size_t len = sdslen(str); if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) { quicklistReplaceEntry(entry->li->iter, &entry->entry, str, len); } else if (entry->li->encoding == OBJ_ENCODING_LISTPACK) { - subject->ptr = lpReplace(subject->ptr, &entry->lpe, (unsigned char *)str, len); + objectSetVal(subject, lpReplace(objectGetVal(subject), &entry->lpe, (unsigned char *)str, len)); } else { serverPanic("Unknown list encoding"); } @@ -365,17 +367,17 @@ void listTypeReplace(listTypeEntry *entry, robj *value) { * Returns 0 if replace failed and no changes happened. */ int listTypeReplaceAtIndex(robj *o, int index, robj *value) { value = getDecodedObject(value); - sds vstr = value->ptr; + sds vstr = objectGetVal(value); size_t vlen = sdslen(vstr); int replaced = 0; if (o->encoding == OBJ_ENCODING_QUICKLIST) { - quicklist *ql = o->ptr; + quicklist *ql = objectGetVal(o); replaced = quicklistReplaceAtIndex(ql, index, vstr, vlen); } else if (o->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *p = lpSeek(o->ptr, index); + unsigned char *p = lpSeek(objectGetVal(o), index); if (p) { - o->ptr = lpReplace(o->ptr, &p, (unsigned char *)vstr, vlen); + objectSetVal(o, lpReplace(objectGetVal(o), &p, (unsigned char *)vstr, vlen)); replaced = 1; } } else { @@ -390,9 +392,9 @@ int listTypeReplaceAtIndex(robj *o, int index, robj *value) { int listTypeEqual(listTypeEntry *entry, robj *o) { serverAssertWithInfo(NULL, o, sdsEncodedObject(o)); if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) { - return quicklistCompare(&entry->entry, o->ptr, sdslen(o->ptr)); + return quicklistCompare(&entry->entry, objectGetVal(o), sdslen(objectGetVal(o))); } else if (entry->li->encoding == OBJ_ENCODING_LISTPACK) { - return lpCompare(entry->lpe, o->ptr, sdslen(o->ptr)); + return lpCompare(entry->lpe, objectGetVal(o), sdslen(objectGetVal(o))); } else { serverPanic("Unknown list encoding"); } @@ -404,18 +406,18 @@ void listTypeDelete(listTypeIterator *iter, listTypeEntry *entry) { quicklistDelEntry(iter->iter, &entry->entry); } else if (entry->li->encoding == OBJ_ENCODING_LISTPACK) { unsigned char *p = entry->lpe; - iter->subject->ptr = lpDelete(iter->subject->ptr, p, &p); + objectSetVal(iter->subject, lpDelete(objectGetVal(iter->subject), p, &p)); /* Update position of the iterator depending on the direction */ if (iter->direction == LIST_TAIL) iter->lpi = p; else { if (p) { - iter->lpi = lpPrev(iter->subject->ptr, p); + iter->lpi = lpPrev(objectGetVal(iter->subject), p); } else { /* We deleted the last element, so we need to set the * iterator to the last element. */ - iter->lpi = lpLast(iter->subject->ptr); + iter->lpi = lpLast(objectGetVal(iter->subject)); } } } else { @@ -434,8 +436,8 @@ robj *listTypeDup(robj *o) { serverAssert(o->type == OBJ_LIST); switch (o->encoding) { - case OBJ_ENCODING_LISTPACK: lobj = createObject(OBJ_LIST, lpDup(o->ptr)); break; - case OBJ_ENCODING_QUICKLIST: lobj = createObject(OBJ_LIST, quicklistDup(o->ptr)); break; + case OBJ_ENCODING_LISTPACK: lobj = createObject(OBJ_LIST, lpDup(objectGetVal(o))); break; + case OBJ_ENCODING_QUICKLIST: lobj = createObject(OBJ_LIST, quicklistDup(objectGetVal(o))); break; default: serverPanic("Unknown list encoding"); break; } lobj->encoding = o->encoding; @@ -445,9 +447,9 @@ robj *listTypeDup(robj *o) { /* Delete a range of elements from the list. */ void listTypeDelRange(robj *subject, long start, long count) { if (subject->encoding == OBJ_ENCODING_QUICKLIST) { - quicklistDelRange(subject->ptr, start, count); + quicklistDelRange(objectGetVal(subject), start, count); } else if (subject->encoding == OBJ_ENCODING_LISTPACK) { - subject->ptr = lpDeleteRange(subject->ptr, start, count); + objectSetVal(subject, lpDeleteRange(objectGetVal(subject), start, count)); } else { serverPanic("Unknown list encoding"); } @@ -515,9 +517,9 @@ void linsertCommand(client *c) { listTypeEntry entry; int inserted = 0; - if (strcasecmp(c->argv[2]->ptr, "after") == 0) { + if (strcasecmp(objectGetVal(c->argv[2]), "after") == 0) { where = LIST_TAIL; - } else if (strcasecmp(c->argv[2]->ptr, "before") == 0) { + } else if (strcasecmp(objectGetVal(c->argv[2]), "before") == 0) { where = LIST_HEAD; } else { addReplyErrorObject(c, shared.syntaxerr); @@ -658,7 +660,7 @@ void addListQuicklistRangeReply(client *c, robj *o, int from, int rangelen, int addWritePreparedReplyArrayLen(wpc, rangelen); int direction = reverse ? AL_START_TAIL : AL_START_HEAD; - quicklistIter *iter = quicklistGetIteratorAtIdx(o->ptr, direction, from); + quicklistIter *iter = quicklistGetIteratorAtIdx(objectGetVal(o), direction, from); while (rangelen--) { quicklistEntry qe; serverAssert(quicklistNext(iter, &qe)); /* fail on corrupt data */ @@ -679,7 +681,7 @@ void addListListpackRangeReply(client *c, robj *o, int from, int rangelen, int r if (!wpc) return; /* Return the result in form of a multi-bulk reply */ addWritePreparedReplyArrayLen(wpc, rangelen); - unsigned char *p = lpSeek(o->ptr, from); + unsigned char *p = lpSeek(objectGetVal(o), from); unsigned char *vstr; unsigned int vlen; long long lval; @@ -692,7 +694,7 @@ void addListListpackRangeReply(client *c, robj *o, int from, int rangelen, int r } else { addWritePreparedReplyBulkLongLong(wpc, lval); } - p = reverse ? lpPrev(o->ptr, p) : lpNext(o->ptr, p); + p = reverse ? lpPrev(objectGetVal(o), p) : lpNext(objectGetVal(o), p); } } @@ -893,11 +895,11 @@ void ltrimCommand(client *c) { /* Remove list elements to perform the trim */ if (o->encoding == OBJ_ENCODING_QUICKLIST) { - quicklistDelRange(o->ptr, 0, ltrim); - quicklistDelRange(o->ptr, -rtrim, rtrim); + quicklistDelRange(objectGetVal(o), 0, ltrim); + quicklistDelRange(objectGetVal(o), -rtrim, rtrim); } else if (o->encoding == OBJ_ENCODING_LISTPACK) { - o->ptr = lpDeleteRange(o->ptr, 0, ltrim); - o->ptr = lpDeleteRange(o->ptr, -rtrim, rtrim); + objectSetVal(o, lpDeleteRange(objectGetVal(o), 0, ltrim)); + objectSetVal(o, lpDeleteRange(objectGetVal(o), -rtrim, rtrim)); } else { serverPanic("Unknown list encoding"); } @@ -940,7 +942,7 @@ void lposCommand(client *c) { /* Parse the optional arguments. */ for (int j = 3; j < c->argc; j++) { - char *opt = c->argv[j]->ptr; + char *opt = objectGetVal(c->argv[j]); int moreargs = (c->argc - 1) - j; if (!strcasecmp(opt, "RANK") && moreargs) { @@ -1082,9 +1084,9 @@ void lmoveHandlePush(client *c, robj *dstkey, robj *dstobj, robj *value, int whe } int getListPositionFromObjectOrReply(client *c, robj *arg, int *position) { - if (strcasecmp(arg->ptr, "right") == 0) { + if (strcasecmp(objectGetVal(arg), "right") == 0) { *position = LIST_TAIL; - } else if (strcasecmp(arg->ptr, "left") == 0) { + } else if (strcasecmp(objectGetVal(arg), "left") == 0) { *position = LIST_HEAD; } else { addReplyErrorObject(c, shared.syntaxerr); @@ -1300,7 +1302,7 @@ void lmpopGenericCommand(client *c, int numkeys_idx, int is_block) { /* Parse the optional arguments. */ for (j = where_idx + 1; j < c->argc; j++) { - char *opt = c->argv[j]->ptr; + char *opt = objectGetVal(c->argv[j]); int moreargs = (c->argc - 1) - j; if (count == -1 && !strcasecmp(opt, "COUNT") && moreargs) { diff --git a/src/t_set.c b/src/t_set.c index 770b3307d..94e61f3d1 100644 --- a/src/t_set.c +++ b/src/t_set.c @@ -56,7 +56,7 @@ robj *setTypeCreate(sds value, size_t size_hint) { /* We may oversize the set by using the hint if the hint is not accurate, * but we will assume this is acceptable to maximize performance. */ robj *o = createSetObject(); - hashtableExpand(o->ptr, size_hint); + hashtableExpand(objectGetVal(o), size_hint); return o; } @@ -80,7 +80,7 @@ static size_t intsetMaxEntries(void) { /* Converts intset to HT if it contains too many entries. */ static void maybeConvertIntset(robj *subject) { serverAssert(subject->encoding == OBJ_ENCODING_INTSET); - if (intsetLen(subject->ptr) > intsetMaxEntries()) setTypeConvert(subject, OBJ_ENCODING_HASHTABLE); + if (intsetLen(objectGetVal(subject)) > intsetMaxEntries()) setTypeConvert(subject, OBJ_ENCODING_HASHTABLE); } /* When you know all set elements are integers, call this to convert the set to @@ -106,7 +106,7 @@ static void maybeConvertToIntset(robj *set) { } setTypeReleaseIterator(si); freeSetObject(set); /* frees the internals but not robj itself */ - set->ptr = is; + objectSetVal(set, is); set->encoding = OBJ_ENCODING_INTSET; } @@ -129,7 +129,7 @@ int setTypeAddAux(robj *set, char *str, size_t len, int64_t llval, int str_is_sd if (!str) { if (set->encoding == OBJ_ENCODING_INTSET) { uint8_t success = 0; - set->ptr = intsetAdd(set->ptr, llval, &success); + objectSetVal(set, intsetAdd(objectGetVal(set), llval, &success)); if (success) maybeConvertIntset(set); return success; } @@ -143,7 +143,7 @@ int setTypeAddAux(robj *set, char *str, size_t len, int64_t llval, int str_is_sd if (set->encoding == OBJ_ENCODING_HASHTABLE) { /* Avoid duping the string if it is an sds string. */ sds sdsval = str_is_sds ? (sds)str : sdsnewlen(str, len); - hashtable *ht = set->ptr; + hashtable *ht = objectGetVal(set); hashtablePosition position; if (hashtableFindPositionForInsert(ht, sdsval, &position, NULL)) { /* Key doesn't already exist in the set. Add it but dup the key. */ @@ -156,7 +156,7 @@ int setTypeAddAux(robj *set, char *str, size_t len, int64_t llval, int str_is_sd return 0; } } else if (set->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *lp = set->ptr; + unsigned char *lp = objectGetVal(set); unsigned char *p = lpFirst(lp); if (p != NULL) p = lpFind(lp, p, (unsigned char *)str, len, 0); if (p == NULL) { @@ -170,11 +170,11 @@ int setTypeAddAux(robj *set, char *str, size_t len, int64_t llval, int str_is_sd } else { lp = lpAppend(lp, (unsigned char *)str, len); } - set->ptr = lp; + objectSetVal(set, lp); } else { /* Size limit is reached. Convert to hashtable and add. */ setTypeConvertAndExpand(set, OBJ_ENCODING_HASHTABLE, lpLength(lp) + 1, 1); - serverAssert(hashtableAdd(set->ptr, sdsnewlen(str, len))); + serverAssert(hashtableAdd(objectGetVal(set), sdsnewlen(str, len))); } return 1; } @@ -182,7 +182,7 @@ int setTypeAddAux(robj *set, char *str, size_t len, int64_t llval, int str_is_sd long long value; if (string2ll(str, len, &value)) { uint8_t success = 0; - set->ptr = intsetAdd(set->ptr, value, &success); + objectSetVal(set, intsetAdd(objectGetVal(set), value, &success)); if (success) { maybeConvertIntset(set); return 1; @@ -190,31 +190,31 @@ int setTypeAddAux(robj *set, char *str, size_t len, int64_t llval, int str_is_sd } else { /* Check if listpack encoding is safe not to cross any threshold. */ size_t maxelelen = 0, totsize = 0; - unsigned long n = intsetLen(set->ptr); + unsigned long n = intsetLen(objectGetVal(set)); if (n != 0) { - size_t elelen1 = sdigits10(intsetMax(set->ptr)); - size_t elelen2 = sdigits10(intsetMin(set->ptr)); + size_t elelen1 = sdigits10(intsetMax(objectGetVal(set))); + size_t elelen2 = sdigits10(intsetMin(objectGetVal(set))); maxelelen = max(elelen1, elelen2); - size_t s1 = lpEstimateBytesRepeatedInteger(intsetMax(set->ptr), n); - size_t s2 = lpEstimateBytesRepeatedInteger(intsetMin(set->ptr), n); + size_t s1 = lpEstimateBytesRepeatedInteger(intsetMax(objectGetVal(set)), n); + size_t s2 = lpEstimateBytesRepeatedInteger(intsetMin(objectGetVal(set)), n); totsize = max(s1, s2); } - if (intsetLen((const intset *)set->ptr) < server.set_max_listpack_entries && + if (intsetLen((const intset *)objectGetVal(set)) < server.set_max_listpack_entries && len <= server.set_max_listpack_value && maxelelen <= server.set_max_listpack_value && lpSafeToAdd(NULL, totsize + len)) { /* In the "safe to add" check above we assumed all elements in * the intset are of size maxelelen. This is an upper bound. */ - setTypeConvertAndExpand(set, OBJ_ENCODING_LISTPACK, intsetLen(set->ptr) + 1, 1); - unsigned char *lp = set->ptr; + setTypeConvertAndExpand(set, OBJ_ENCODING_LISTPACK, intsetLen(objectGetVal(set)) + 1, 1); + unsigned char *lp = objectGetVal(set); lp = lpAppend(lp, (unsigned char *)str, len); lp = lpShrinkToFit(lp); - set->ptr = lp; + objectSetVal(set, lp); return 1; } else { - setTypeConvertAndExpand(set, OBJ_ENCODING_HASHTABLE, intsetLen(set->ptr) + 1, 1); + setTypeConvertAndExpand(set, OBJ_ENCODING_HASHTABLE, intsetLen(objectGetVal(set)) + 1, 1); /* The set *was* an intset and this value is not integer * encodable, so hashtableAdd should always work. */ - serverAssert(hashtableAdd(set->ptr, sdsnewlen(str, len))); + serverAssert(hashtableAdd(objectGetVal(set), sdsnewlen(str, len))); return 1; } } @@ -241,7 +241,7 @@ int setTypeRemoveAux(robj *setobj, char *str, size_t len, int64_t llval, int str if (!str) { if (setobj->encoding == OBJ_ENCODING_INTSET) { int success; - setobj->ptr = intsetRemove(setobj->ptr, llval, &success); + objectSetVal(setobj, intsetRemove(objectGetVal(setobj), llval, &success)); return success; } len = ll2string(tmpbuf, sizeof tmpbuf, llval); @@ -251,24 +251,24 @@ int setTypeRemoveAux(robj *setobj, char *str, size_t len, int64_t llval, int str if (setobj->encoding == OBJ_ENCODING_HASHTABLE) { sds sdsval = str_is_sds ? (sds)str : sdsnewlen(str, len); - int deleted = hashtableDelete(setobj->ptr, sdsval); + int deleted = hashtableDelete(objectGetVal(setobj), sdsval); if (sdsval != str) sdsfree(sdsval); /* free temp copy */ return deleted; } else if (setobj->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *lp = setobj->ptr; + unsigned char *lp = objectGetVal(setobj); unsigned char *p = lpFirst(lp); if (p == NULL) return 0; p = lpFind(lp, p, (unsigned char *)str, len, 0); if (p != NULL) { lp = lpDelete(lp, p, NULL); - setobj->ptr = lp; + objectSetVal(setobj, lp); return 1; } } else if (setobj->encoding == OBJ_ENCODING_INTSET) { long long llval; if (string2ll(str, len, &llval)) { int success; - setobj->ptr = intsetRemove(setobj->ptr, llval, &success); + objectSetVal(setobj, intsetRemove(objectGetVal(setobj), llval, &success)); if (success) return 1; } } else { @@ -292,24 +292,24 @@ int setTypeIsMember(robj *subject, sds value) { int setTypeIsMemberAux(robj *set, char *str, size_t len, int64_t llval, int str_is_sds) { char tmpbuf[LONG_STR_SIZE]; if (!str) { - if (set->encoding == OBJ_ENCODING_INTSET) return intsetFind(set->ptr, llval); + if (set->encoding == OBJ_ENCODING_INTSET) return intsetFind(objectGetVal(set), llval); len = ll2string(tmpbuf, sizeof tmpbuf, llval); str = tmpbuf; str_is_sds = 0; } if (set->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *lp = set->ptr; + unsigned char *lp = objectGetVal(set); unsigned char *p = lpFirst(lp); return p && lpFind(lp, p, (unsigned char *)str, len, 0); } else if (set->encoding == OBJ_ENCODING_INTSET) { long long llval; - return string2ll(str, len, &llval) && intsetFind(set->ptr, llval); + return string2ll(str, len, &llval) && intsetFind(objectGetVal(set), llval); } else if (set->encoding == OBJ_ENCODING_HASHTABLE && str_is_sds) { - return hashtableFind(set->ptr, (sds)str, NULL); + return hashtableFind(objectGetVal(set), (sds)str, NULL); } else if (set->encoding == OBJ_ENCODING_HASHTABLE) { sds sdsval = sdsnewlen(str, len); - int result = hashtableFind(set->ptr, sdsval, NULL); + int result = hashtableFind(objectGetVal(set), sdsval, NULL); sdsfree(sdsval); return result; } else { @@ -322,7 +322,7 @@ setTypeIterator *setTypeInitIterator(robj *subject) { si->subject = subject; si->encoding = subject->encoding; if (si->encoding == OBJ_ENCODING_HASHTABLE) { - si->hashtable_iterator = hashtableCreateIterator(subject->ptr, 0); + si->hashtable_iterator = hashtableCreateIterator(objectGetVal(subject), 0); } else if (si->encoding == OBJ_ENCODING_INTSET) { si->ii = 0; } else if (si->encoding == OBJ_ENCODING_LISTPACK) { @@ -367,10 +367,10 @@ int setTypeNext(setTypeIterator *si, char **str, size_t *len, int64_t *llele) { *len = sdslen(*str); *llele = -123456789; /* Not needed. Defensive. */ } else if (si->encoding == OBJ_ENCODING_INTSET) { - if (!intsetGet(si->subject->ptr, si->ii++, llele)) return -1; + if (!intsetGet(objectGetVal(si->subject), si->ii++, llele)) return -1; *str = NULL; } else if (si->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *lp = si->subject->ptr; + unsigned char *lp = objectGetVal(si->subject); unsigned char *lpi = si->lpi; if (lpi == NULL) { lpi = lpFirst(lp); @@ -421,15 +421,15 @@ sds setTypeNextObject(setTypeIterator *si) { int setTypeRandomElement(robj *setobj, char **str, size_t *len, int64_t *llele) { if (setobj->encoding == OBJ_ENCODING_HASHTABLE) { void *entry = NULL; - hashtableFairRandomEntry(setobj->ptr, &entry); + hashtableFairRandomEntry(objectGetVal(setobj), &entry); *str = entry; *len = sdslen(*str); *llele = -123456789; /* Not needed. Defensive. */ } else if (setobj->encoding == OBJ_ENCODING_INTSET) { - *llele = intsetRandom(setobj->ptr); + *llele = intsetRandom(objectGetVal(setobj)); *str = NULL; /* Not needed. Defensive. */ } else if (setobj->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *lp = setobj->ptr; + unsigned char *lp = objectGetVal(setobj); int r = rand() % lpLength(lp); unsigned char *p = lpSeek(lp, r); unsigned int l; @@ -447,7 +447,7 @@ robj *setTypePopRandom(robj *set) { if (set->encoding == OBJ_ENCODING_LISTPACK) { /* Find random and delete it without re-seeking the listpack. */ unsigned int i = 0; - unsigned char *p = lpNextRandom(set->ptr, lpFirst(set->ptr), &i, 1, 0); + unsigned char *p = lpNextRandom(objectGetVal(set), lpFirst(objectGetVal(set)), &i, 1, 0); unsigned int len = 0; /* initialize to silence warning */ long long llele = 0; /* initialize to silence warning */ char *str = (char *)lpGetValue(p, &len, &llele); @@ -455,7 +455,7 @@ robj *setTypePopRandom(robj *set) { obj = createStringObject(str, len); else obj = createStringObjectFromLongLong(llele); - set->ptr = lpDelete(set->ptr, p, NULL); + objectSetVal(set, lpDelete(objectGetVal(set), p, NULL)); } else { char *str; size_t len = 0; @@ -472,11 +472,11 @@ robj *setTypePopRandom(robj *set) { unsigned long setTypeSize(const robj *subject) { if (subject->encoding == OBJ_ENCODING_HASHTABLE) { - return hashtableSize((const hashtable *)subject->ptr); + return hashtableSize((const hashtable *)objectGetVal(subject)); } else if (subject->encoding == OBJ_ENCODING_INTSET) { - return intsetLen((const intset *)subject->ptr); + return intsetLen((const intset *)objectGetVal(subject)); } else if (subject->encoding == OBJ_ENCODING_LISTPACK) { - return lpLength((unsigned char *)subject->ptr); + return lpLength((unsigned char *)objectGetVal(subject)); } else { serverPanic("Unknown set encoding"); } @@ -518,14 +518,14 @@ int setTypeConvertAndExpand(robj *setobj, int enc, unsigned long cap, int panic) freeSetObject(setobj); /* frees the internals but not setobj itself */ setobj->encoding = OBJ_ENCODING_HASHTABLE; - setobj->ptr = ht; + objectSetVal(setobj, ht); } else if (enc == OBJ_ENCODING_LISTPACK) { /* Preallocate the minimum two bytes per element (enc/value + backlen) */ size_t estcap = cap * 2; if (setobj->encoding == OBJ_ENCODING_INTSET && setTypeSize(setobj) > 0) { /* If we're converting from intset, we have a better estimate. */ - size_t s1 = lpEstimateBytesRepeatedInteger(intsetMin(setobj->ptr), cap); - size_t s2 = lpEstimateBytesRepeatedInteger(intsetMax(setobj->ptr), cap); + size_t s1 = lpEstimateBytesRepeatedInteger(intsetMin(objectGetVal(setobj)), cap); + size_t s2 = lpEstimateBytesRepeatedInteger(intsetMax(objectGetVal(setobj)), cap); estcap = max(s1, s2); } unsigned char *lp = lpNew(estcap); @@ -543,7 +543,7 @@ int setTypeConvertAndExpand(robj *setobj, int enc, unsigned long cap, int panic) freeSetObject(setobj); /* frees the internals but not setobj itself */ setobj->encoding = OBJ_ENCODING_LISTPACK; - setobj->ptr = lp; + objectSetVal(setobj, lp); } else { serverPanic("Unsupported set conversion"); } @@ -563,14 +563,14 @@ robj *setTypeDup(robj *o) { /* Create a new set object that have the same encoding as the original object's encoding */ if (o->encoding == OBJ_ENCODING_INTSET) { - intset *is = o->ptr; + intset *is = objectGetVal(o); size_t size = intsetBlobLen(is); intset *newis = zmalloc(size); memcpy(newis, is, size); set = createObject(OBJ_SET, newis); set->encoding = OBJ_ENCODING_INTSET; } else if (o->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *lp = o->ptr; + unsigned char *lp = objectGetVal(o); size_t sz = lpBytes(lp); unsigned char *new_lp = zmalloc(sz); memcpy(new_lp, lp, sz); @@ -578,8 +578,8 @@ robj *setTypeDup(robj *o) { set->encoding = OBJ_ENCODING_LISTPACK; } else if (o->encoding == OBJ_ENCODING_HASHTABLE) { set = createSetObject(); - hashtable *ht = o->ptr; - hashtableExpand(set->ptr, hashtableSize(ht)); + hashtable *ht = objectGetVal(o); + hashtableExpand(objectGetVal(set), hashtableSize(ht)); si = setTypeInitIterator(o); char *str; size_t len; @@ -602,14 +602,14 @@ void saddCommand(client *c) { if (checkType(c, set, OBJ_SET)) return; if (set == NULL) { - set = setTypeCreate(c->argv[2]->ptr, c->argc - 2); + set = setTypeCreate(objectGetVal(c->argv[2]), c->argc - 2); dbAdd(c->db, c->argv[1], &set); } else { setTypeMaybeConvert(set, c->argc - 2); } for (j = 2; j < c->argc; j++) { - if (setTypeAdd(set, c->argv[j]->ptr)) added++; + if (setTypeAdd(set, objectGetVal(c->argv[j]))) added++; } if (added) { signalModifiedKey(c, c->db, c->argv[1]); @@ -626,7 +626,7 @@ void sremCommand(client *c) { if ((set = lookupKeyWriteOrReply(c, c->argv[1], shared.czero)) == NULL || checkType(c, set, OBJ_SET)) return; for (j = 2; j < c->argc; j++) { - if (setTypeRemove(set, c->argv[j]->ptr)) { + if (setTypeRemove(set, objectGetVal(c->argv[j]))) { deleted++; if (setTypeSize(set) == 0) { dbDelete(c->db, c->argv[1]); @@ -662,12 +662,12 @@ void smoveCommand(client *c) { /* If srcset and dstset are equal, SMOVE is a no-op */ if (srcset == dstset) { - addReply(c, setTypeIsMember(srcset, ele->ptr) ? shared.cone : shared.czero); + addReply(c, setTypeIsMember(srcset, objectGetVal(ele)) ? shared.cone : shared.czero); return; } /* If the element cannot be removed from the src set, return 0. */ - if (!setTypeRemove(srcset, ele->ptr)) { + if (!setTypeRemove(srcset, objectGetVal(ele))) { addReply(c, shared.czero); return; } @@ -681,7 +681,7 @@ void smoveCommand(client *c) { /* Create the destination set when it doesn't exist */ if (!dstset) { - dstset = setTypeCreate(ele->ptr, 1); + dstset = setTypeCreate(objectGetVal(ele), 1); dbAdd(c->db, c->argv[2], &dstset); } @@ -689,7 +689,7 @@ void smoveCommand(client *c) { server.dirty++; /* An extra key has changed when ele was successfully added to dstset */ - if (setTypeAdd(dstset, ele->ptr)) { + if (setTypeAdd(dstset, objectGetVal(ele))) { server.dirty++; signalModifiedKey(c, c->db, c->argv[2]); notifyKeyspaceEvent(NOTIFY_SET, "sadd", c->argv[2], c->db->id); @@ -702,7 +702,7 @@ void sismemberCommand(client *c) { if ((set = lookupKeyReadOrReply(c, c->argv[1], shared.czero)) == NULL || checkType(c, set, OBJ_SET)) return; - if (setTypeIsMember(set, c->argv[2]->ptr)) + if (setTypeIsMember(set, objectGetVal(c->argv[2]))) addReply(c, shared.cone); else addReply(c, shared.czero); @@ -720,7 +720,7 @@ void smismemberCommand(client *c) { addReplyArrayLen(c, c->argc - 2); for (j = 2; j < c->argc; j++) { - if (set && setTypeIsMember(set, c->argv[j]->ptr)) + if (set && setTypeIsMember(set, objectGetVal(c->argv[j]))) addReply(c, shared.cone); else addReply(c, shared.czero); @@ -815,7 +815,7 @@ void spopWithCountCommand(client *c) { * the set. */ if (remaining * SPOP_MOVE_STRATEGY_MUL > count && set->encoding == OBJ_ENCODING_LISTPACK) { /* Specialized case for listpack. Traverse it only once. */ - unsigned char *lp = set->ptr; + unsigned char *lp = objectGetVal(set); unsigned char *p = lpFirst(lp); unsigned int index = 0; unsigned char **ps = zmalloc(sizeof(char *) * count); @@ -847,7 +847,7 @@ void spopWithCountCommand(client *c) { } lp = lpBatchDelete(lp, ps, count); zfree(ps); - set->ptr = lp; + objectSetVal(set, lp); } else if (remaining * SPOP_MOVE_STRATEGY_MUL > count) { for (unsigned long i = 0; i < count; i++) { propargv[propindex] = setTypePopRandom(set); @@ -877,7 +877,7 @@ void spopWithCountCommand(client *c) { if (set->encoding == OBJ_ENCODING_LISTPACK) { /* Specialized case for listpack. Traverse it only once. */ newset = createSetListpackObject(); - unsigned char *lp = set->ptr; + unsigned char *lp = objectGetVal(set); unsigned char *p = lpFirst(lp); unsigned int index = 0; unsigned char **ps = zmalloc(sizeof(char *) * remaining); @@ -892,7 +892,7 @@ void spopWithCountCommand(client *c) { } lp = lpBatchDelete(lp, ps, remaining); zfree(ps); - set->ptr = lp; + objectSetVal(set, lp); } else { while (remaining--) { int encoding = setTypeRandomElement(set, &str, &len, &llele); @@ -1043,7 +1043,7 @@ void srandmemberWithCountCommand(client *c) { while (count) { sample_count = count > limit ? limit : count; count -= sample_count; - lpRandomEntries(set->ptr, sample_count, entries); + lpRandomEntries(objectGetVal(set), sample_count, entries); for (unsigned long i = 0; i < sample_count; i++) { if (entries[i].sval) addReplyBulkCBuffer(c, entries[i].sval, entries[i].slen); @@ -1097,7 +1097,7 @@ void srandmemberWithCountCommand(client *c) { * And it is inefficient to repeatedly pick one random element from a * listpack in CASE 4. So we use this instead. */ if (set->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *lp = set->ptr; + unsigned char *lp = objectGetVal(set); unsigned char *p = lpFirst(lp); unsigned int i = 0; addReplyArrayLen(c, count); @@ -1317,7 +1317,7 @@ void sinterGenericCommand(client *c, /* To avoid many reallocs, we estimate that the result is a listpack * of approximately the same size as the first set. Then we shrink * it or possibly convert it to intset in the end. */ - unsigned char *lp = lpNew(lpBytes(sets[0]->ptr)); + unsigned char *lp = lpNew(lpBytes(objectGetVal(sets[0]))); dstset = createObject(OBJ_SET, lp); dstset->encoding = OBJ_ENCODING_LISTPACK; } else { @@ -1383,7 +1383,7 @@ void sinterGenericCommand(client *c, if (dstset->encoding == OBJ_ENCODING_LISTPACK) { /* We allocated too much memory when we created it to avoid * frequent reallocs. Therefore, we shrink it now. */ - dstset->ptr = lpShrinkToFit(dstset->ptr); + objectSetVal(dstset, lpShrinkToFit(objectGetVal(dstset))); } setKey(c, c->db, dstkey, &dstset, 0); notifyKeyspaceEvent(NOTIFY_SET, "sinterstore", dstkey, c->db->id); @@ -1423,7 +1423,7 @@ void sinterCardCommand(client *c) { } for (j = 2 + numkeys; j < c->argc; j++) { - char *opt = c->argv[j]->ptr; + char *opt = objectGetVal(c->argv[j]); int moreargs = (c->argc - 1) - j; if (!strcasecmp(opt, "LIMIT") && moreargs) { @@ -1650,7 +1650,7 @@ void sscanCommand(client *c) { robj *set; unsigned long long cursor; - if (parseScanCursorOrReply(c, c->argv[2]->ptr, &cursor) == C_ERR) return; + if (parseScanCursorOrReply(c, objectGetVal(c->argv[2]), &cursor) == C_ERR) return; if ((set = lookupKeyReadOrReply(c, c->argv[1], shared.emptyscan)) == NULL || checkType(c, set, OBJ_SET)) return; scanGenericCommand(c, set, cursor); } diff --git a/src/t_stream.c b/src/t_stream.c index b953b84eb..d81687947 100644 --- a/src/t_stream.c +++ b/src/t_stream.c @@ -94,7 +94,7 @@ void freeStream(stream *s) { /* Return the length of a stream. */ unsigned long streamLength(const robj *subject) { - stream *s = subject->ptr; + stream *s = objectGetVal(subject); return s->length; } @@ -170,8 +170,8 @@ robj *streamDup(robj *o) { stream *s; stream *new_s; - s = o->ptr; - new_s = sobj->ptr; + s = objectGetVal(o); + new_s = objectGetVal(sobj); raxIterator ri; uint64_t rax_key[2]; @@ -462,7 +462,7 @@ int streamAppendItem(stream *s, robj **argv, int64_t numfields, streamID *added_ * can't be bigger than 32bit length. */ size_t totelelen = 0; for (int64_t i = 0; i < numfields * 2; i++) { - sds ele = argv[i]->ptr; + sds ele = objectGetVal(argv[i]); totelelen += sdslen(ele); } if (totelelen > STREAM_LISTPACK_MAX_SIZE) { @@ -566,7 +566,7 @@ int streamAppendItem(stream *s, robj **argv, int64_t numfields, streamID *added_ lp = lpAppendInteger(lp, 0); /* Zero deleted so far. */ lp = lpAppendInteger(lp, numfields); for (int64_t i = 0; i < numfields; i++) { - sds field = argv[i * 2]->ptr; + sds field = objectGetVal(argv[i * 2]); lp = lpAppend(lp, (unsigned char *)field, sdslen(field)); } lp = lpAppendInteger(lp, 0); /* primary entry zero terminator. */ @@ -595,7 +595,7 @@ int streamAppendItem(stream *s, robj **argv, int64_t numfields, streamID *added_ if (numfields == primary_fields_count) { int64_t i; for (i = 0; i < primary_fields_count; i++) { - sds field = argv[i * 2]->ptr; + sds field = objectGetVal(argv[i * 2]); int64_t e_len; unsigned char buf[LP_INTBUF_SIZE]; unsigned char *e = lpGet(lp_ele, &e_len, buf); @@ -636,7 +636,7 @@ int streamAppendItem(stream *s, robj **argv, int64_t numfields, streamID *added_ lp = lpAppendInteger(lp, id.seq - primary_id.seq); if (!(flags & STREAM_ITEM_FLAG_SAMEFIELDS)) lp = lpAppendInteger(lp, numfields); for (int64_t i = 0; i < numfields; i++) { - sds field = argv[i * 2]->ptr, value = argv[i * 2 + 1]->ptr; + sds field = objectGetVal(argv[i * 2]), value = objectGetVal(argv[i * 2 + 1]); if (!(flags & STREAM_ITEM_FLAG_SAMEFIELDS)) lp = lpAppend(lp, (unsigned char *)field, sdslen(field)); lp = lpAppend(lp, (unsigned char *)value, sdslen(value)); } @@ -897,7 +897,7 @@ static int streamParseAddOrTrimArgsOrReply(client *c, streamAddTrimArgs *args, i int limit_given = 0; for (; i < c->argc; i++) { int moreargs = (c->argc - 1) - i; /* Number of additional arguments. */ - char *opt = c->argv[i]->ptr; + char *opt = objectGetVal(c->argv[i]); if (xadd && opt[0] == '*' && opt[1] == '\0') { /* This is just a fast path for the common case of auto-ID * creation. */ @@ -908,7 +908,7 @@ static int streamParseAddOrTrimArgsOrReply(client *c, streamAddTrimArgs *args, i return -1; } args->approx_trim = 0; - char *next = c->argv[i + 1]->ptr; + char *next = objectGetVal(c->argv[i + 1]); /* Check for the form MAXLEN ~ . */ if (moreargs >= 2 && next[0] == '~' && next[1] == '\0') { args->approx_trim = 1; @@ -931,7 +931,7 @@ static int streamParseAddOrTrimArgsOrReply(client *c, streamAddTrimArgs *args, i return -1; } args->approx_trim = 0; - char *next = c->argv[i + 1]->ptr; + char *next = objectGetVal(c->argv[i + 1]); /* Check for the form MINID ~ */ if (moreargs >= 2 && next[0] == '~' && next[1] == '\0') { args->approx_trim = 1; @@ -1870,8 +1870,8 @@ int streamGenericParseIDOrReply(client *c, int strict, int *seq_given) { char buf[128]; - if (sdslen(o->ptr) > sizeof(buf) - 1) goto invalid; - memcpy(buf, o->ptr, sdslen(o->ptr) + 1); + if (sdslen(objectGetVal(o)) > sizeof(buf) - 1) goto invalid; + memcpy(buf, objectGetVal(o), sdslen(objectGetVal(o)) + 1); if (strict && (buf[0] == '-' || buf[0] == '+') && buf[1] == '\0') goto invalid; @@ -1943,7 +1943,7 @@ int streamParseStrictIDOrReply(client *c, robj *o, streamID *id, uint64_t missin * called in that case. */ int streamParseIntervalIDOrReply(client *c, robj *o, streamID *id, int *exclude, uint64_t missing_seq) { - char *p = o->ptr; + char *p = objectGetVal(o); size_t len = sdslen(p); int invalid = 0; @@ -2005,7 +2005,7 @@ void xaddCommand(client *c) { robj *o; stream *s; if ((o = streamTypeLookupWriteOrCreate(c, c->argv[1], parsed_args.no_mkstream)) == NULL) return; - s = o->ptr; + s = objectGetVal(o); /* Return ASAP if the stream has reached the last possible ID */ if (s->last_id.ms == UINT64_MAX && s->last_id.seq == UINT64_MAX) { @@ -2098,7 +2098,7 @@ void xrangeGenericCommand(client *c, int rev) { if (c->argc > 4) { for (int j = 4; j < c->argc; j++) { int additional = c->argc - j - 1; - if (strcasecmp(c->argv[j]->ptr, "COUNT") == 0 && additional >= 1) { + if (strcasecmp(objectGetVal(c->argv[j]), "COUNT") == 0 && additional >= 1) { if (getLongLongFromObjectOrReply(c, c->argv[j + 1], &count, NULL) != C_OK) return; if (count < 0) count = 0; j++; /* Consume additional arg. */ @@ -2112,7 +2112,7 @@ void xrangeGenericCommand(client *c, int rev) { /* Return the specified range to the user. */ if ((o = lookupKeyReadOrReply(c, c->argv[1], shared.emptyarray)) == NULL || checkType(c, o, OBJ_STREAM)) return; - s = o->ptr; + s = objectGetVal(o); if (count == 0) { addReplyNullArray(c); @@ -2136,7 +2136,7 @@ void xrevrangeCommand(client *c) { void xlenCommand(client *c) { robj *o; if ((o = lookupKeyReadOrReply(c, c->argv[1], shared.czero)) == NULL || checkType(c, o, OBJ_STREAM)) return; - stream *s = o->ptr; + stream *s = objectGetVal(o); addReplyLongLong(c, s->length); } @@ -2157,14 +2157,14 @@ void xreadCommand(client *c) { streamID static_ids[STREAMID_STATIC_VECTOR_LEN]; streamID *ids = static_ids; streamCG **groups = NULL; - int xreadgroup = sdslen(c->argv[0]->ptr) == 10; /* XREAD or XREADGROUP? */ + int xreadgroup = sdslen(objectGetVal(c->argv[0])) == 10; /* XREAD or XREADGROUP? */ robj *groupname = NULL; robj *consumername = NULL; /* Parse arguments. */ for (int i = 1; i < c->argc; i++) { int moreargs = c->argc - i - 1; - char *o = c->argv[i]->ptr; + char *o = objectGetVal(c->argv[i]); if (!strcasecmp(o, "BLOCK") && moreargs) { i++; if (getTimeoutFromObjectOrReply(c, c->argv[i], &timeout, UNIT_MILLISECONDS) != C_OK) return; @@ -2238,18 +2238,18 @@ void xreadCommand(client *c) { /* If a group was specified, than we need to be sure that the * key and group actually exist. */ if (groupname) { - if (o == NULL || (group = streamLookupCG(o->ptr, groupname->ptr)) == NULL) { + if (o == NULL || (group = streamLookupCG(objectGetVal(o), objectGetVal(groupname))) == NULL) { addReplyErrorFormat(c, "-NOGROUP No such key '%s' or consumer " "group '%s' in XREADGROUP with GROUP " "option", - (char *)key->ptr, (char *)groupname->ptr); + (char *)objectGetVal(key), (char *)objectGetVal(groupname)); goto cleanup; } groups[id_idx] = group; } - if (strcmp(c->argv[i]->ptr, "$") == 0) { + if (strcmp(objectGetVal(c->argv[i]), "$") == 0) { if (xreadgroup) { addReplyError(c, "The $ ID is meaningless in the context of " "XREADGROUP: you want to read the history of " @@ -2259,14 +2259,14 @@ void xreadCommand(client *c) { goto cleanup; } if (o) { - stream *s = o->ptr; + stream *s = objectGetVal(o); ids[id_idx] = s->last_id; } else { ids[id_idx].ms = 0; ids[id_idx].seq = 0; } continue; - } else if (strcmp(c->argv[i]->ptr, "+") == 0) { + } else if (strcmp(objectGetVal(c->argv[i]), "+") == 0) { if (xreadgroup) { addReplyError(c, "The + ID is meaningless in the context of " "XREADGROUP: you want to read the history of " @@ -2276,7 +2276,7 @@ void xreadCommand(client *c) { goto cleanup; } if (o) { - stream *s = o->ptr; + stream *s = objectGetVal(o); ids[id_idx] = s->last_id; if (streamDecrID(&ids[id_idx]) != C_OK) { /* shouldn't happen */ @@ -2288,7 +2288,7 @@ void xreadCommand(client *c) { ids[id_idx].seq = 0; } continue; - } else if (strcmp(c->argv[i]->ptr, ">") == 0) { + } else if (strcmp(objectGetVal(c->argv[i]), ">") == 0) { if (!xreadgroup) { addReplyError(c, "The > ID can be specified only when calling " "XREADGROUP using the GROUP " @@ -2311,7 +2311,7 @@ void xreadCommand(client *c) { for (int i = 0; i < streams_count; i++) { robj *o = lookupKeyRead(c->db, c->argv[streams_arg + i]); if (o == NULL) continue; - stream *s = o->ptr; + stream *s = objectGetVal(o); streamID *gt = ids + i; /* ID must be greater than this. */ int serve_synchronously = 0; int serve_history = 0; /* True for XREADGROUP with ID != ">". */ @@ -2338,9 +2338,9 @@ void xreadCommand(client *c) { *gt = *last; } } - consumer = streamLookupConsumer(groups[i], consumername->ptr); + consumer = streamLookupConsumer(groups[i], objectGetVal(consumername)); if (consumer == NULL) { - consumer = streamCreateConsumer(groups[i], consumername->ptr, c->argv[streams_arg + i], c->db->id, + consumer = streamCreateConsumer(groups[i], objectGetVal(consumername), c->argv[streams_arg + i], c->db->id, SCC_DEFAULT); if (noack) streamPropagateConsumerCreation(c, spi.keyname, spi.groupname, consumer->name); } @@ -2400,7 +2400,7 @@ void xreadCommand(client *c) { */ for (int id_idx = 0; id_idx < streams_count; id_idx++) { int arg_idx = id_idx + streams_arg + streams_count; - if (strcmp(c->argv[arg_idx]->ptr, "$") == 0) { + if (strcmp(objectGetVal(c->argv[arg_idx]), "$") == 0) { robj *argv_streamid = createObjectFromStreamID(&ids[id_idx]); rewriteClientCommandArgument(c, arg_idx, argv_streamid); decrRefCount(argv_streamid); @@ -2562,7 +2562,7 @@ void xgroupCommand(client *c) { stream *s = NULL; sds grpname = NULL; streamCG *cg = NULL; - char *opt = c->argv[1]->ptr; /* Subcommand name. */ + char *opt = objectGetVal(c->argv[1]); /* Subcommand name. */ int mkstream = 0; long long entries_read = SCG_INVALID_ENTRIES_READ; robj *o; @@ -2574,10 +2574,10 @@ void xgroupCommand(client *c) { int create_subcmd = !strcasecmp(opt, "CREATE"); int setid_subcmd = !strcasecmp(opt, "SETID"); while (i < c->argc) { - if (create_subcmd && !strcasecmp(c->argv[i]->ptr, "MKSTREAM")) { + if (create_subcmd && !strcasecmp(objectGetVal(c->argv[i]), "MKSTREAM")) { mkstream = 1; i++; - } else if ((create_subcmd || setid_subcmd) && !strcasecmp(c->argv[i]->ptr, "ENTRIESREAD") && + } else if ((create_subcmd || setid_subcmd) && !strcasecmp(objectGetVal(c->argv[i]), "ENTRIESREAD") && i + 1 < c->argc) { if (getLongLongFromObjectOrReply(c, c->argv[i + 1], &entries_read, NULL) != C_OK) return; if (entries_read < 0 && entries_read != SCG_INVALID_ENTRIES_READ) { @@ -2594,9 +2594,9 @@ void xgroupCommand(client *c) { o = lookupKeyWrite(c->db, c->argv[2]); if (o) { if (checkType(c, o, OBJ_STREAM)) return; - s = o->ptr; + s = objectGetVal(o); } - grpname = c->argv[3]->ptr; + grpname = objectGetVal(c->argv[3]); } /* Check for missing key/group. */ @@ -2615,7 +2615,7 @@ void xgroupCommand(client *c) { addReplyErrorFormat(c, "-NOGROUP No such consumer group '%s' " "for key name '%s'", - (char *)grpname, (char *)c->argv[2]->ptr); + (char *)grpname, (char *)objectGetVal(c->argv[2])); return; } } @@ -2642,7 +2642,7 @@ void xgroupCommand(client *c) { addReplyHelp(c, help); } else if (!strcasecmp(opt, "CREATE") && (c->argc >= 5 && c->argc <= 8)) { streamID id; - if (!strcmp(c->argv[4]->ptr, "$")) { + if (!strcmp(objectGetVal(c->argv[4]), "$")) { if (s) { id = s->last_id; } else { @@ -2658,7 +2658,7 @@ void xgroupCommand(client *c) { serverAssert(mkstream); o = createStreamObject(); dbAdd(c->db, c->argv[2], &o); - s = o->ptr; + s = objectGetVal(o); signalModifiedKey(c, c->db, c->argv[2]); } @@ -2672,7 +2672,7 @@ void xgroupCommand(client *c) { } } else if (!strcasecmp(opt, "SETID") && (c->argc == 5 || c->argc == 7)) { streamID id; - if (!strcmp(c->argv[4]->ptr, "$")) { + if (!strcmp(objectGetVal(c->argv[4]), "$")) { id = s->last_id; } else if (streamParseIDOrReply(c, c->argv[4], &id, 0) != C_OK) { return; @@ -2695,11 +2695,11 @@ void xgroupCommand(client *c) { addReply(c, shared.czero); } } else if (!strcasecmp(opt, "CREATECONSUMER") && c->argc == 5) { - streamConsumer *created = streamCreateConsumer(cg, c->argv[4]->ptr, c->argv[2], c->db->id, SCC_DEFAULT); + streamConsumer *created = streamCreateConsumer(cg, objectGetVal(c->argv[4]), c->argv[2], c->db->id, SCC_DEFAULT); addReplyLongLong(c, created ? 1 : 0); } else if (!strcasecmp(opt, "DELCONSUMER") && c->argc == 5) { long long pending = 0; - streamConsumer *consumer = streamLookupConsumer(cg, c->argv[4]->ptr); + streamConsumer *consumer = streamLookupConsumer(cg, objectGetVal(c->argv[4])); if (consumer) { /* Delete the consumer and returns the number of pending messages * that were yet associated with such a consumer. */ @@ -2727,7 +2727,7 @@ void xsetidCommand(client *c) { int i = 3; while (i < c->argc) { int moreargs = (c->argc - 1) - i; /* Number of additional arguments. */ - char *opt = c->argv[i]->ptr; + char *opt = objectGetVal(c->argv[i]); if (!strcasecmp(opt, "ENTRIESADDED") && moreargs) { if (getLongLongFromObjectOrReply(c, c->argv[i + 1], &entries_added, NULL) != C_OK) { return; @@ -2752,7 +2752,7 @@ void xsetidCommand(client *c) { robj *o = lookupKeyWriteOrReply(c, c->argv[1], shared.nokeyerr); if (o == NULL || checkType(c, o, OBJ_STREAM)) return; - stream *s = o->ptr; + stream *s = objectGetVal(o); if (streamCompareID(&id, &s->max_deleted_entry_id) < 0) { addReplyError(c, "The ID specified in XSETID is smaller than current max_deleted_entry_id"); @@ -2799,7 +2799,7 @@ void xackCommand(client *c) { robj *o = lookupKeyRead(c->db, c->argv[1]); if (o) { if (checkType(c, o, OBJ_STREAM)) return; /* Type error. */ - group = streamLookupCG(o->ptr, c->argv[2]->ptr); + group = streamLookupCG(objectGetVal(o), objectGetVal(c->argv[2])); } /* No key or group? Nothing to ack. */ @@ -2874,7 +2874,7 @@ void xpendingCommand(client *c) { if (c->argc >= 6) { int startidx = 3; /* Without IDLE */ - if (!strcasecmp(c->argv[3]->ptr, "IDLE")) { + if (!strcasecmp(objectGetVal(c->argv[3]), "IDLE")) { if (getLongLongFromObjectOrReply(c, c->argv[4], &minidle, NULL) == C_ERR) return; if (c->argc < 8) { /* If IDLE was provided we must have at least 'start end count' */ @@ -2912,11 +2912,11 @@ void xpendingCommand(client *c) { streamCG *group; if (checkType(c, o, OBJ_STREAM)) return; - if (o == NULL || (group = streamLookupCG(o->ptr, groupname->ptr)) == NULL) { + if (o == NULL || (group = streamLookupCG(objectGetVal(o), objectGetVal(groupname))) == NULL) { addReplyErrorFormat(c, "-NOGROUP No such key '%s' or consumer " "group '%s'", - (char *)key->ptr, (char *)groupname->ptr); + (char *)objectGetVal(key), (char *)objectGetVal(groupname)); return; } @@ -2965,7 +2965,7 @@ void xpendingCommand(client *c) { } else { /* , and provided, return actual pending entries (not just info) */ streamConsumer *consumer = NULL; if (consumername) { - consumer = streamLookupConsumer(group, consumername->ptr); + consumer = streamLookupConsumer(group, objectGetVal(consumername)); /* If a consumer name was mentioned but it does not exist, we can * just return an empty array. */ @@ -3098,7 +3098,7 @@ void xclaimCommand(client *c) { if (o) { if (checkType(c, o, OBJ_STREAM)) return; /* Type error. */ - group = streamLookupCG(o->ptr, c->argv[2]->ptr); + group = streamLookupCG(objectGetVal(o), objectGetVal(c->argv[2])); } /* No key or group? Send an error given that the group creation @@ -3107,7 +3107,7 @@ void xclaimCommand(client *c) { addReplyErrorFormat(c, "-NOGROUP No such key '%s' or " "consumer group '%s'", - (char *)c->argv[1]->ptr, (char *)c->argv[2]->ptr); + (char *)objectGetVal(c->argv[1]), (char *)objectGetVal(c->argv[2])); return; } @@ -3136,7 +3136,7 @@ void xclaimCommand(client *c) { int propagate_last_id = 0; for (; j < c->argc; j++) { int moreargs = (c->argc - 1) - j; /* Number of additional arguments. */ - char *opt = c->argv[j]->ptr; + char *opt = objectGetVal(c->argv[j]); if (!strcasecmp(opt, "FORCE")) { force = 1; } else if (!strcasecmp(opt, "JUSTID")) { @@ -3188,9 +3188,9 @@ void xclaimCommand(client *c) { } /* Do the actual claiming. */ - streamConsumer *consumer = streamLookupConsumer(group, c->argv[3]->ptr); + streamConsumer *consumer = streamLookupConsumer(group, objectGetVal(c->argv[3])); if (consumer == NULL) { - consumer = streamCreateConsumer(group, c->argv[3]->ptr, c->argv[1], c->db->id, SCC_DEFAULT); + consumer = streamCreateConsumer(group, objectGetVal(c->argv[3]), c->argv[1], c->db->id, SCC_DEFAULT); } consumer->seen_time = commandTimeSnapshot(); @@ -3207,7 +3207,7 @@ void xclaimCommand(client *c) { streamNACK *nack = result; /* Item must exist for us to transfer it to another consumer. */ - if (!streamEntryExists(o->ptr, &id)) { + if (!streamEntryExists(objectGetVal(o), &id)) { /* Clear this entry from the PEL, it no longer exists */ if (nack != NULL) { /* Propagate this change (we are going to delete the NACK). */ @@ -3268,7 +3268,7 @@ void xclaimCommand(client *c) { if (justid) { addReplyStreamID(c, &id); } else { - serverAssert(streamReplyWithRange(c, o->ptr, &id, &id, 1, 0, NULL, NULL, STREAM_RWR_RAWENTRIES, NULL) == + serverAssert(streamReplyWithRange(c, objectGetVal(o), &id, &id, 1, 0, NULL, NULL, STREAM_RWR_RAWENTRIES, NULL) == 1); } arraylen++; @@ -3332,7 +3332,7 @@ void xautoclaimCommand(client *c) { int j = 6; /* options start at argv[6] */ while (j < c->argc) { int moreargs = (c->argc - 1) - j; /* Number of additional arguments. */ - char *opt = c->argv[j]->ptr; + char *opt = objectGetVal(c->argv[j]); if (!strcasecmp(opt, "COUNT") && moreargs) { long max_count = LONG_MAX / (max(sizeof(streamID), attempts_factor)); if (getRangeLongFromObjectOrReply(c, c->argv[j + 1], 1, max_count, &count, "COUNT must be > 0") != C_OK) @@ -3349,14 +3349,14 @@ void xautoclaimCommand(client *c) { if (o) { if (checkType(c, o, OBJ_STREAM)) return; /* Type error. */ - group = streamLookupCG(o->ptr, c->argv[2]->ptr); + group = streamLookupCG(objectGetVal(o), objectGetVal(c->argv[2])); } /* No key or group? Send an error given that the group creation * is mandatory. */ if (o == NULL || group == NULL) { - addReplyErrorFormat(c, "-NOGROUP No such key '%s' or consumer group '%s'", (char *)c->argv[1]->ptr, - (char *)c->argv[2]->ptr); + addReplyErrorFormat(c, "-NOGROUP No such key '%s' or consumer group '%s'", (char *)objectGetVal(c->argv[1]), + (char *)objectGetVal(c->argv[2])); return; } @@ -3367,9 +3367,9 @@ void xautoclaimCommand(client *c) { } /* Do the actual claiming. */ - streamConsumer *consumer = streamLookupConsumer(group, c->argv[3]->ptr); + streamConsumer *consumer = streamLookupConsumer(group, objectGetVal(c->argv[3])); if (consumer == NULL) { - consumer = streamCreateConsumer(group, c->argv[3]->ptr, c->argv[1], c->db->id, SCC_DEFAULT); + consumer = streamCreateConsumer(group, objectGetVal(c->argv[3]), c->argv[1], c->db->id, SCC_DEFAULT); } consumer->seen_time = commandTimeSnapshot(); @@ -3394,7 +3394,7 @@ void xautoclaimCommand(client *c) { streamDecodeID(ri.key, &id); /* Item must exist for us to transfer it to another consumer. */ - if (!streamEntryExists(o->ptr, &id)) { + if (!streamEntryExists(objectGetVal(o), &id)) { /* Propagate this change (we are going to delete the NACK). */ robj *idstr = createObjectFromStreamID(&id); streamPropagateXCLAIM(c, c->argv[1], group, c->argv[2], idstr, nack); @@ -3438,7 +3438,7 @@ void xautoclaimCommand(client *c) { if (justid) { addReplyStreamID(c, &id); } else { - serverAssert(streamReplyWithRange(c, o->ptr, &id, &id, 1, 0, NULL, NULL, STREAM_RWR_RAWENTRIES, NULL) == 1); + serverAssert(streamReplyWithRange(c, objectGetVal(o), &id, &id, 1, 0, NULL, NULL, STREAM_RWR_RAWENTRIES, NULL) == 1); } arraylen++; count--; @@ -3484,7 +3484,7 @@ void xdelCommand(client *c) { robj *o; if ((o = lookupKeyWriteOrReply(c, c->argv[1], shared.czero)) == NULL || checkType(c, o, OBJ_STREAM)) return; - stream *s = o->ptr; + stream *s = objectGetVal(o); /* We need to sanity check the IDs passed to start. Even if not * a big issue, it is not great that the command is only partially @@ -3571,7 +3571,7 @@ void xtrimCommand(client *c) { /* If the key does not exist, we are ok returning zero, that is, the * number of elements removed from the stream. */ if ((o = lookupKeyWriteOrReply(c, c->argv[1], shared.czero)) == NULL || checkType(c, o, OBJ_STREAM)) return; - stream *s = o->ptr; + stream *s = objectGetVal(o); /* Perform the trimming. */ int64_t deleted = streamTrim(s, &parsed_args); @@ -3613,14 +3613,14 @@ void xinfoReplyWithStreamInfo(client *c, stream *s) { } /* First option must be "FULL" */ - if (strcasecmp(optv[0]->ptr, "full")) { + if (strcasecmp(objectGetVal(optv[0]), "full")) { addReplySubcommandSyntaxError(c); return; } if (optc == 3) { /* First option must be "FULL" */ - if (strcasecmp(optv[1]->ptr, "count")) { + if (strcasecmp(objectGetVal(optv[1]), "count")) { addReplySubcommandSyntaxError(c); return; } @@ -3807,7 +3807,7 @@ void xinfoCommand(client *c) { robj *key; /* HELP is special. Handle it ASAP. */ - if (!strcasecmp(c->argv[1]->ptr, "HELP")) { + if (!strcasecmp(objectGetVal(c->argv[1]), "HELP")) { const char *help[] = { "CONSUMERS ", " Show consumers of .", @@ -3823,23 +3823,23 @@ void xinfoCommand(client *c) { /* With the exception of HELP handled before any other sub commands, all * the ones are in the form of " ". */ - opt = c->argv[1]->ptr; + opt = objectGetVal(c->argv[1]); key = c->argv[2]; /* Lookup the key now, this is common for all the subcommands but HELP. */ robj *o = lookupKeyReadOrReply(c, key, shared.nokeyerr); if (o == NULL || checkType(c, o, OBJ_STREAM)) return; - s = o->ptr; + s = objectGetVal(o); /* Dispatch the different subcommands. */ if (!strcasecmp(opt, "CONSUMERS") && c->argc == 4) { /* XINFO CONSUMERS . */ - streamCG *cg = streamLookupCG(s, c->argv[3]->ptr); + streamCG *cg = streamLookupCG(s, objectGetVal(c->argv[3])); if (cg == NULL) { addReplyErrorFormat(c, "-NOGROUP No such consumer group '%s' " "for key name '%s'", - (char *)c->argv[3]->ptr, (char *)key->ptr); + (char *)objectGetVal(c->argv[3]), (char *)objectGetVal(key)); return; } diff --git a/src/t_string.c b/src/t_string.c index a8c46a8a9..612b95c93 100644 --- a/src/t_string.c +++ b/src/t_string.c @@ -171,7 +171,7 @@ void setGenericCommand(client *c, int j; robj **argv = zmalloc((c->argc - 1) * sizeof(robj *)); for (j = 0; j < c->argc; j++) { - char *a = c->argv[j]->ptr; + char *a = objectGetVal(c->argv[j]); /* Skip GET which may be repeated multiple times. */ if (j >= 3 && (a[0] == 'g' || a[0] == 'G') && (a[1] == 'e' || a[1] == 'E') && (a[2] == 't' || a[2] == 'T') && a[3] == '\0') @@ -400,7 +400,7 @@ void getsetCommand(client *c) { void setrangeCommand(client *c) { robj *o; long offset; - sds value = c->argv[3]->ptr; + sds value = objectGetVal(c->argv[3]); if (getLongFromObjectOrReply(c, c->argv[2], &offset, NULL) != C_OK) return; @@ -446,12 +446,12 @@ void setrangeCommand(client *c) { o = dbUnshareStringValue(c->db, c->argv[1], o); } - o->ptr = sdsgrowzero(o->ptr, offset + sdslen(value)); - memcpy((char *)o->ptr + offset, value, sdslen(value)); + objectSetVal(o, sdsgrowzero(objectGetVal(o), offset + sdslen(value))); + memcpy((char *)objectGetVal(o) + offset, value, sdslen(value)); signalModifiedKey(c, c->db, c->argv[1]); notifyKeyspaceEvent(NOTIFY_STRING, "setrange", c->argv[1], c->db->id); server.dirty++; - addReplyLongLong(c, sdslen(o->ptr)); + addReplyLongLong(c, sdslen(objectGetVal(o))); } void getrangeCommand(client *c) { @@ -469,9 +469,9 @@ void getrangeCommand(client *c) { if (o->encoding == OBJ_ENCODING_INT) { str = llbuf; - strlen = ll2string(llbuf, sizeof(llbuf), (long)o->ptr); + strlen = ll2string(llbuf, sizeof(llbuf), (long)objectGetVal(o)); } else { - str = o->ptr; + str = objectGetVal(o); strlen = sdslen(str); } @@ -574,7 +574,7 @@ void incrDecrCommand(client *c, long long incr) { if (o && o->refcount == 1 && o->encoding == OBJ_ENCODING_INT && value >= LONG_MIN && value <= LONG_MAX) { new = o; - o->ptr = (void *)((long)value); + objectSetVal(o, (void *)((long)value)); } else { new = createStringObjectFromLongLongForValue(value); if (o) { @@ -667,13 +667,13 @@ void appendCommand(client *c) { /* "append" is an argument, so always an sds */ append = c->argv[2]; - if (checkStringLength(c, stringObjectLen(o), sdslen(append->ptr)) != C_OK) + if (checkStringLength(c, stringObjectLen(o), sdslen(objectGetVal(append))) != C_OK) return; /* Append the value */ o = dbUnshareStringValue(c->db, c->argv[1], o); - o->ptr = sdscatlen(o->ptr, append->ptr, sdslen(append->ptr)); - totlen = sdslen(o->ptr); + objectSetVal(o, sdscatlen(objectGetVal(o), objectGetVal(append), sdslen(objectGetVal(append)))); + totlen = sdslen(objectGetVal(o)); } signalModifiedKey(c, c->db, c->argv[1]); notifyKeyspaceEvent(NOTIFY_STRING, "append", c->argv[1], c->db->id); @@ -710,11 +710,11 @@ void lcsCommand(client *c) { } obja = obja ? getDecodedObject(obja) : createStringObject("", 0); objb = objb ? getDecodedObject(objb) : createStringObject("", 0); - a = obja->ptr; - b = objb->ptr; + a = objectGetVal(obja); + b = objectGetVal(objb); for (j = 3; j < (uint32_t)c->argc; j++) { - char *opt = c->argv[j]->ptr; + char *opt = objectGetVal(c->argv[j]); int moreargs = (c->argc - 1) - j; if (!strcasecmp(opt, "IDX")) { diff --git a/src/t_zset.c b/src/t_zset.c index e5ca114fa..33adf822a 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -604,26 +604,26 @@ static int zslParseRange(robj *min, robj *max, zrangespec *spec) { * ZRANGEBYSCORE zset (1.5 (2.5 will match min < x < max * ZRANGEBYSCORE zset 1.5 2.5 will instead match min <= x <= max */ if (min->encoding == OBJ_ENCODING_INT) { - spec->min = (long)min->ptr; + spec->min = (long)objectGetVal(min); } else { - if (((char *)min->ptr)[0] == '(') { - spec->min = valkey_strtod((char *)min->ptr + 1, &eptr); + if (((char *)objectGetVal(min))[0] == '(') { + spec->min = valkey_strtod((char *)objectGetVal(min) + 1, &eptr); if (eptr[0] != '\0' || isnan(spec->min)) return C_ERR; spec->minex = 1; } else { - spec->min = valkey_strtod((char *)min->ptr, &eptr); + spec->min = valkey_strtod((char *)objectGetVal(min), &eptr); if (eptr[0] != '\0' || isnan(spec->min)) return C_ERR; } } if (max->encoding == OBJ_ENCODING_INT) { - spec->max = (long)max->ptr; + spec->max = (long)objectGetVal(max); } else { - if (((char *)max->ptr)[0] == '(') { - spec->max = valkey_strtod((char *)max->ptr + 1, &eptr); + if (((char *)objectGetVal(max))[0] == '(') { + spec->max = valkey_strtod((char *)objectGetVal(max) + 1, &eptr); if (eptr[0] != '\0' || isnan(spec->max)) return C_ERR; spec->maxex = 1; } else { - spec->max = valkey_strtod((char *)max->ptr, &eptr); + spec->max = valkey_strtod((char *)objectGetVal(max), &eptr); if (eptr[0] != '\0' || isnan(spec->max)) return C_ERR; } } @@ -647,7 +647,7 @@ static int zslParseRange(robj *min, robj *max, zrangespec *spec) { * If the string is not a valid range C_ERR is returned, and the value * of *dest and *ex is undefined. */ static int zslParseLexRangeItem(robj *item, sds *dest, int *ex) { - char *c = item->ptr; + char *c = objectGetVal(item); switch (c[0]) { case '+': @@ -1237,9 +1237,9 @@ unsigned char *zzlDeleteRangeByRank(unsigned char *zl, unsigned int start, unsig unsigned long zsetLength(const robj *zobj) { unsigned long length = 0; if (zobj->encoding == OBJ_ENCODING_LISTPACK) { - length = zzlLength(zobj->ptr); + length = zzlLength(objectGetVal(zobj)); } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - length = ((const zset *)zobj->ptr)->zsl->length; + length = ((const zset *)objectGetVal(zobj))->zsl->length; } else { serverPanic("Unknown sorted set encoding"); } @@ -1260,7 +1260,7 @@ robj *zsetTypeCreate(size_t size_hint, size_t val_len_hint) { } robj *zobj = createZsetObject(); - zset *zs = zobj->ptr; + zset *zs = objectGetVal(zobj); hashtableExpand(zs->ht, size_hint); return zobj; } @@ -1290,7 +1290,7 @@ void zsetConvertAndExpand(robj *zobj, int encoding, unsigned long cap) { if (zobj->encoding == encoding) return; if (zobj->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = zobj->ptr; + unsigned char *zl = objectGetVal(zobj); unsigned char *eptr, *sptr; unsigned char *vstr; unsigned int vlen; @@ -1325,8 +1325,8 @@ void zsetConvertAndExpand(robj *zobj, int encoding, unsigned long cap) { zzlNext(zl, &eptr, &sptr); } - zfree(zobj->ptr); - zobj->ptr = zs; + zfree(objectGetVal(zobj)); + objectSetVal(zobj, zs); zobj->encoding = OBJ_ENCODING_SKIPLIST; } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { unsigned char *zl = lpNew(0); @@ -1335,7 +1335,7 @@ void zsetConvertAndExpand(robj *zobj, int encoding, unsigned long cap) { /* Approach similar to zslFree(), since we want to free the skiplist at * the same time as creating the listpack. */ - zs = zobj->ptr; + zs = objectGetVal(zobj); hashtableRelease(zs->ht); node = zs->zsl->header->level[0].forward; zfree(zs->zsl->header); @@ -1349,7 +1349,7 @@ void zsetConvertAndExpand(robj *zobj, int encoding, unsigned long cap) { } zfree(zs); - zobj->ptr = zl; + objectSetVal(zobj, zl); zobj->encoding = OBJ_ENCODING_LISTPACK; } else { serverPanic("Unknown sorted set encoding"); @@ -1361,7 +1361,7 @@ void zsetConvertAndExpand(robj *zobj, int encoding, unsigned long cap) { * are within the expected ranges. */ void zsetConvertToListpackIfNeeded(robj *zobj, size_t maxelelen, size_t totelelen) { if (zobj->encoding == OBJ_ENCODING_LISTPACK) return; - zset *zset = zobj->ptr; + zset *zset = objectGetVal(zobj); if (zset->zsl->length <= server.zset_max_listpack_entries && maxelelen <= server.zset_max_listpack_value && lpSafeToAdd(NULL, totelelen)) { @@ -1377,9 +1377,9 @@ int zsetScore(robj *zobj, sds member, double *score) { if (!zobj || !member) return C_ERR; if (zobj->encoding == OBJ_ENCODING_LISTPACK) { - if (zzlFind(zobj->ptr, member, score) == NULL) return C_ERR; + if (zzlFind(objectGetVal(zobj), member, score) == NULL) return C_ERR; } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zobj->ptr; + zset *zs = objectGetVal(zobj); void *entry; if (!hashtableFind(zs->ht, member, &entry)) return C_ERR; zskiplistNode *setElement = entry; @@ -1455,7 +1455,7 @@ int zsetAdd(robj *zobj, double score, sds ele, int in_flags, int *out_flags, dou if (zobj->encoding == OBJ_ENCODING_LISTPACK) { unsigned char *eptr; - if ((eptr = zzlFind(zobj->ptr, ele, &curscore)) != NULL) { + if ((eptr = zzlFind(objectGetVal(zobj), ele, &curscore)) != NULL) { /* NX? Return, same element already exists. */ if (nx) { *out_flags |= ZADD_OUT_NOP; @@ -1481,19 +1481,19 @@ int zsetAdd(robj *zobj, double score, sds ele, int in_flags, int *out_flags, dou /* Remove and re-insert when score changed. */ if (score != curscore) { - zobj->ptr = zzlDelete(zobj->ptr, eptr); - zobj->ptr = zzlInsert(zobj->ptr, ele, score); + objectSetVal(zobj, zzlDelete(objectGetVal(zobj), eptr)); + objectSetVal(zobj, zzlInsert(objectGetVal(zobj), ele, score)); *out_flags |= ZADD_OUT_UPDATED; } return 1; } else if (!xx) { /* check if the element is too large or the list * becomes too long *before* executing zzlInsert. */ - if (zzlLength(zobj->ptr) + 1 > server.zset_max_listpack_entries || - sdslen(ele) > server.zset_max_listpack_value || !lpSafeToAdd(zobj->ptr, sdslen(ele))) { + if (zzlLength(objectGetVal(zobj)) + 1 > server.zset_max_listpack_entries || + sdslen(ele) > server.zset_max_listpack_value || !lpSafeToAdd(objectGetVal(zobj), sdslen(ele))) { zsetConvertAndExpand(zobj, OBJ_ENCODING_SKIPLIST, zsetLength(zobj) + 1); } else { - zobj->ptr = zzlInsert(zobj->ptr, ele, score); + objectSetVal(zobj, zzlInsert(objectGetVal(zobj), ele, score)); if (newscore) *newscore = score; *out_flags |= ZADD_OUT_ADDED; return 1; @@ -1507,7 +1507,7 @@ int zsetAdd(robj *zobj, double score, sds ele, int in_flags, int *out_flags, dou /* Note that the above block handling listpack would have either returned or * converted the key to skiplist. */ if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zobj->ptr; + zset *zs = objectGetVal(zobj); void **node_ref_in_hashtable = hashtableFindRef(zs->ht, ele); if (node_ref_in_hashtable != NULL) { @@ -1584,12 +1584,12 @@ int zsetDel(robj *zobj, sds ele) { if (zobj->encoding == OBJ_ENCODING_LISTPACK) { unsigned char *eptr; - if ((eptr = zzlFind(zobj->ptr, ele, NULL)) != NULL) { - zobj->ptr = zzlDelete(zobj->ptr, eptr); + if ((eptr = zzlFind(objectGetVal(zobj), ele, NULL)) != NULL) { + objectSetVal(zobj, zzlDelete(objectGetVal(zobj), eptr)); return 1; } } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zobj->ptr; + zset *zs = objectGetVal(zobj); if (zsetRemoveFromSkiplist(zs, ele)) { return 1; } @@ -1617,7 +1617,7 @@ static long zsetRank(robj *zobj, sds ele, int reverse, double *output_score) { llen = zsetLength(zobj); if (zobj->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = zobj->ptr; + unsigned char *zl = objectGetVal(zobj); unsigned char *eptr, *sptr; eptr = lpSeek(zl, 0); @@ -1642,7 +1642,7 @@ static long zsetRank(robj *zobj, sds ele, int reverse, double *output_score) { return -1; } } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zobj->ptr; + zset *zs = objectGetVal(zobj); void *entry; if (!hashtableFind(zs->ht, ele, &entry)) return -1; @@ -1675,7 +1675,7 @@ robj *zsetDup(robj *o) { /* Create a new sorted set object that have the same encoding as the original object's encoding */ if (o->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = o->ptr; + unsigned char *zl = objectGetVal(o); size_t sz = lpBytes(zl); unsigned char *new_zl = zmalloc(sz); memcpy(new_zl, zl, sz); @@ -1683,8 +1683,8 @@ robj *zsetDup(robj *o) { zobj->encoding = OBJ_ENCODING_LISTPACK; } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { zobj = createZsetObject(); - zs = o->ptr; - new_zs = zobj->ptr; + zs = objectGetVal(o); + new_zs = objectGetVal(zobj); hashtableExpand(new_zs->ht, hashtableSize(zs->ht)); zskiplist *zsl = zs->zsl; zskiplistNode *ln; @@ -1730,7 +1730,7 @@ void zsetReplyFromListpackEntry(client *c, listpackEntry *e) { * 'score' can be NULL in which case it's not extracted. */ static void zsetTypeRandomElement(robj *zsetobj, unsigned long zsetsize, listpackEntry *key, double *score) { if (zsetobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zsetobj->ptr; + zset *zs = objectGetVal(zsetobj); void *entry; hashtableFairRandomEntry(zs->ht, &entry); zskiplistNode *node = entry; @@ -1740,7 +1740,7 @@ static void zsetTypeRandomElement(robj *zsetobj, unsigned long zsetsize, listpac if (score) *score = node->score; } else if (zsetobj->encoding == OBJ_ENCODING_LISTPACK) { listpackEntry val; - lpRandomPair(zsetobj->ptr, zsetsize, key, &val); + lpRandomPair(objectGetVal(zsetobj), zsetsize, key, &val); if (score) { if (val.sval) { *score = zzlStrtod(val.sval, val.slen); @@ -1781,7 +1781,7 @@ static void zaddGenericCommand(client *c, int flags) { * of the score of the first score-element pair. */ scoreidx = 2; while (scoreidx < c->argc) { - char *opt = c->argv[scoreidx]->ptr; + char *opt = objectGetVal(c->argv[scoreidx]); if (!strcasecmp(opt, "nx")) flags |= ZADD_IN_NX; else if (!strcasecmp(opt, "xx")) @@ -1838,7 +1838,7 @@ static void zaddGenericCommand(client *c, int flags) { scores = zmalloc(sizeof(double) * elements); for (j = 0; j < elements; j++) { if (getDoubleFromObjectOrReply(c, c->argv[scoreidx + j * 2], &scores[j], NULL) != C_OK) goto cleanup; - ele = c->argv[scoreidx + 1 + j * 2]->ptr; + ele = objectGetVal(c->argv[scoreidx + 1 + j * 2]); size_t elelen = sdslen(ele); if (elelen > maxelelen) maxelelen = elelen; } @@ -1859,7 +1859,7 @@ static void zaddGenericCommand(client *c, int flags) { score = scores[j]; int retflags = 0; - ele = c->argv[scoreidx + 1 + j * 2]->ptr; + ele = objectGetVal(c->argv[scoreidx + 1 + j * 2]); int retval = zsetAdd(zobj, score, ele, flags, &retflags, &newscore); if (retval == 0) { reply_err = 1; @@ -1909,7 +1909,7 @@ void zremCommand(client *c) { if ((zobj = lookupKeyWriteOrReply(c, key, shared.czero)) == NULL || checkType(c, zobj, OBJ_ZSET)) return; for (j = 2; j < c->argc; j++) { - if (zsetDel(zobj, c->argv[j]->ptr)) deleted++; + if (zsetDel(zobj, objectGetVal(c->argv[j]))) deleted++; if (zsetLength(zobj) == 0) { dbDelete(c->db, key); keyremoved = 1; @@ -1989,16 +1989,16 @@ void zremrangeGenericCommand(client *c, zrange_type rangetype) { if (zobj->encoding == OBJ_ENCODING_LISTPACK) { switch (rangetype) { case ZRANGE_AUTO: - case ZRANGE_RANK: zobj->ptr = zzlDeleteRangeByRank(zobj->ptr, start + 1, end + 1, &deleted); break; - case ZRANGE_SCORE: zobj->ptr = zzlDeleteRangeByScore(zobj->ptr, &range, &deleted); break; - case ZRANGE_LEX: zobj->ptr = zzlDeleteRangeByLex(zobj->ptr, &lexrange, &deleted); break; + case ZRANGE_RANK: objectSetVal(zobj, zzlDeleteRangeByRank(objectGetVal(zobj), start + 1, end + 1, &deleted)); break; + case ZRANGE_SCORE: objectSetVal(zobj, zzlDeleteRangeByScore(objectGetVal(zobj), &range, &deleted)); break; + case ZRANGE_LEX: objectSetVal(zobj, zzlDeleteRangeByLex(objectGetVal(zobj), &lexrange, &deleted)); break; } - if (zzlLength(zobj->ptr) == 0) { + if (zzlLength(objectGetVal(zobj)) == 0) { dbDelete(c->db, key); keyremoved = 1; } } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zobj->ptr; + zset *zs = objectGetVal(zobj); hashtablePauseAutoShrink(zs->ht); switch (rangetype) { case ZRANGE_AUTO: @@ -2107,12 +2107,12 @@ static void zuiInitIterator(zsetopsrc *op) { if (op->type == OBJ_SET) { iterset *it = &op->iter.set; if (op->encoding == OBJ_ENCODING_INTSET) { - it->is.is = op->subject->ptr; + it->is.is = objectGetVal(op->subject); it->is.ii = 0; } else if (op->encoding == OBJ_ENCODING_HASHTABLE) { - it->ht.iter = hashtableCreateIterator(op->subject->ptr, 0); + it->ht.iter = hashtableCreateIterator(objectGetVal(op->subject), 0); } else if (op->encoding == OBJ_ENCODING_LISTPACK) { - it->lp.lp = op->subject->ptr; + it->lp.lp = objectGetVal(op->subject); it->lp.p = lpFirst(it->lp.lp); } else { serverPanic("Unknown set encoding"); @@ -2123,14 +2123,14 @@ static void zuiInitIterator(zsetopsrc *op) { * ZDIFF/ZINTER/ZUNION */ iterzset *it = &op->iter.zset; if (op->encoding == OBJ_ENCODING_LISTPACK) { - it->zl.zl = op->subject->ptr; + it->zl.zl = objectGetVal(op->subject); it->zl.eptr = lpSeek(it->zl.zl, -2); if (it->zl.eptr != NULL) { it->zl.sptr = lpNext(it->zl.zl, it->zl.eptr); serverAssert(it->zl.sptr != NULL); } } else if (op->encoding == OBJ_ENCODING_SKIPLIST) { - it->sl.zs = op->subject->ptr; + it->sl.zs = objectGetVal(op->subject); it->sl.node = it->sl.zs->zsl->tail; } else { serverPanic("Unknown sorted set encoding"); @@ -2183,9 +2183,9 @@ static unsigned long zuiLength(zsetopsrc *op) { return setTypeSize(op->subject); } else if (op->type == OBJ_ZSET) { if (op->encoding == OBJ_ENCODING_LISTPACK) { - return zzlLength(op->subject->ptr); + return zzlLength(objectGetVal(op->subject)); } else if (op->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = op->subject->ptr; + zset *zs = objectGetVal(op->subject); return zs->zsl->length; } else { serverPanic("Unknown sorted set encoding"); @@ -2305,14 +2305,14 @@ static int zuiFind(zsetopsrc *op, zsetopval *val, double *score) { zuiSdsFromValue(val); if (op->encoding == OBJ_ENCODING_LISTPACK) { - if (zzlFind(op->subject->ptr, val->ele, score) != NULL) { + if (zzlFind(objectGetVal(op->subject), val->ele, score) != NULL) { /* Score is already set by zzlFind. */ return 1; } else { return 0; } } else if (op->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = op->subject->ptr; + zset *zs = objectGetVal(op->subject); void *entry; if (hashtableFind(zs->ht, val->ele, &entry)) { zskiplistNode *node = entry; @@ -2619,7 +2619,7 @@ static void zunionInterDiffGenericCommand(client *c, robj *dstkey, int numkeysIn while (remaining) { if (op != SET_OP_DIFF && !cardinality_only && remaining >= (setnum + 1) && - !strcasecmp(c->argv[j]->ptr, "weights")) { + !strcasecmp(objectGetVal(c->argv[j]), "weights")) { j++; remaining--; for (i = 0; i < setnum; i++, j++, remaining--) { @@ -2630,14 +2630,14 @@ static void zunionInterDiffGenericCommand(client *c, robj *dstkey, int numkeysIn } } } else if (op != SET_OP_DIFF && !cardinality_only && remaining >= 2 && - !strcasecmp(c->argv[j]->ptr, "aggregate")) { + !strcasecmp(objectGetVal(c->argv[j]), "aggregate")) { j++; remaining--; - if (!strcasecmp(c->argv[j]->ptr, "sum")) { + if (!strcasecmp(objectGetVal(c->argv[j]), "sum")) { aggregate = REDIS_AGGR_SUM; - } else if (!strcasecmp(c->argv[j]->ptr, "min")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "min")) { aggregate = REDIS_AGGR_MIN; - } else if (!strcasecmp(c->argv[j]->ptr, "max")) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "max")) { aggregate = REDIS_AGGR_MAX; } else { zfree(src); @@ -2646,11 +2646,11 @@ static void zunionInterDiffGenericCommand(client *c, robj *dstkey, int numkeysIn } j++; remaining--; - } else if (remaining >= 1 && !dstkey && !cardinality_only && !strcasecmp(c->argv[j]->ptr, "withscores")) { + } else if (remaining >= 1 && !dstkey && !cardinality_only && !strcasecmp(objectGetVal(c->argv[j]), "withscores")) { j++; remaining--; withscores = 1; - } else if (cardinality_only && remaining >= 2 && !strcasecmp(c->argv[j]->ptr, "limit")) { + } else if (cardinality_only && remaining >= 2 && !strcasecmp(objectGetVal(c->argv[j]), "limit")) { j++; remaining--; if (getPositiveLongFromObjectOrReply(c, c->argv[j], &limit, "LIMIT can't be negative") != C_OK) { @@ -2679,7 +2679,7 @@ static void zunionInterDiffGenericCommand(client *c, robj *dstkey, int numkeysIn * In SINTERCARD case, we don't need the temp obj, so we can avoid creating it. */ if (!cardinality_only) { dstobj = createZsetObject(); - dstzset = dstobj->ptr; + dstzset = objectGetVal(dstobj); } memset(&zval, 0, sizeof(zval)); @@ -3077,7 +3077,7 @@ void genericZrangebyrankCommand(zrange_result_handler *handler, handler->beginResultEmission(handler, rangelen); if (zobj->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = zobj->ptr; + unsigned char *zl = objectGetVal(zobj); unsigned char *eptr, *sptr; unsigned char *vstr; unsigned int vlen; @@ -3112,7 +3112,7 @@ void genericZrangebyrankCommand(zrange_result_handler *handler, } } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zobj->ptr; + zset *zs = objectGetVal(zobj); zskiplist *zsl = zs->zsl; zskiplistNode *ln; @@ -3179,7 +3179,7 @@ void genericZrangebyscoreCommand(zrange_result_handler *handler, } if (zobj->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = zobj->ptr; + unsigned char *zl = objectGetVal(zobj); unsigned char *eptr, *sptr; unsigned char *vstr; unsigned int vlen; @@ -3231,7 +3231,7 @@ void genericZrangebyscoreCommand(zrange_result_handler *handler, } } } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zobj->ptr; + zset *zs = objectGetVal(zobj); zskiplist *zsl = zs->zsl; zskiplistNode *ln; @@ -3298,7 +3298,7 @@ void zcountCommand(client *c) { if ((zobj = lookupKeyReadOrReply(c, key, shared.czero)) == NULL || checkType(c, zobj, OBJ_ZSET)) return; if (zobj->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = zobj->ptr; + unsigned char *zl = objectGetVal(zobj); unsigned char *eptr, *sptr; double score; @@ -3329,7 +3329,7 @@ void zcountCommand(client *c) { } } } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zobj->ptr; + zset *zs = objectGetVal(zobj); zskiplist *zsl = zs->zsl; zskiplistNode *zn; long rank; @@ -3375,7 +3375,7 @@ void zlexcountCommand(client *c) { } if (zobj->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = zobj->ptr; + unsigned char *zl = objectGetVal(zobj); unsigned char *eptr, *sptr; /* Use the first element in range as the starting point */ @@ -3403,7 +3403,7 @@ void zlexcountCommand(client *c) { } } } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zobj->ptr; + zset *zs = objectGetVal(zobj); zskiplist *zsl = zs->zsl; zskiplistNode *zn; unsigned long rank; @@ -3446,7 +3446,7 @@ void genericZrangebylexCommand(zrange_result_handler *handler, handler->beginResultEmission(handler, -1); if (zobj->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = zobj->ptr; + unsigned char *zl = objectGetVal(zobj); unsigned char *eptr, *sptr; unsigned char *vstr; unsigned int vlen; @@ -3500,7 +3500,7 @@ void genericZrangebylexCommand(zrange_result_handler *handler, } } } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zobj->ptr; + zset *zs = objectGetVal(zobj); zskiplist *zsl = zs->zsl; zskiplistNode *ln; @@ -3584,19 +3584,19 @@ void zrangeGenericCommand(zrange_result_handler *handler, /* Step 1: Skip the args and parse remaining optional arguments. */ for (int j = argc_start + 3; j < c->argc; j++) { int leftargs = c->argc - j - 1; - if (!store && !strcasecmp(c->argv[j]->ptr, "withscores")) { + if (!store && !strcasecmp(objectGetVal(c->argv[j]), "withscores")) { opt_withscores = 1; - } else if (!strcasecmp(c->argv[j]->ptr, "limit") && leftargs >= 2) { + } else if (!strcasecmp(objectGetVal(c->argv[j]), "limit") && leftargs >= 2) { if ((getLongFromObjectOrReply(c, c->argv[j + 1], &opt_offset, NULL) != C_OK) || (getLongFromObjectOrReply(c, c->argv[j + 2], &opt_limit, NULL) != C_OK)) { return; } j += 2; - } else if (direction == ZRANGE_DIRECTION_AUTO && !strcasecmp(c->argv[j]->ptr, "rev")) { + } else if (direction == ZRANGE_DIRECTION_AUTO && !strcasecmp(objectGetVal(c->argv[j]), "rev")) { direction = ZRANGE_DIRECTION_REVERSE; - } else if (rangetype == ZRANGE_AUTO && !strcasecmp(c->argv[j]->ptr, "bylex")) { + } else if (rangetype == ZRANGE_AUTO && !strcasecmp(objectGetVal(c->argv[j]), "bylex")) { rangetype = ZRANGE_LEX; - } else if (rangetype == ZRANGE_AUTO && !strcasecmp(c->argv[j]->ptr, "byscore")) { + } else if (rangetype == ZRANGE_AUTO && !strcasecmp(objectGetVal(c->argv[j]), "byscore")) { rangetype = ZRANGE_SCORE; } else { addReplyErrorObject(c, shared.syntaxerr); @@ -3715,7 +3715,7 @@ void zscoreCommand(client *c) { if ((zobj = lookupKeyReadOrReply(c, key, shared.null[c->resp])) == NULL || checkType(c, zobj, OBJ_ZSET)) return; - if (zsetScore(zobj, c->argv[2]->ptr, &score) == C_ERR) { + if (zsetScore(zobj, objectGetVal(c->argv[2]), &score) == C_ERR) { addReplyNull(c); } else { addReplyDouble(c, score); @@ -3732,7 +3732,7 @@ void zmscoreCommand(client *c) { addReplyArrayLen(c, c->argc - 2); for (int j = 2; j < c->argc; j++) { /* Treat a missing set the same way as an empty set */ - if (zobj == NULL || zsetScore(zobj, c->argv[j]->ptr, &score) == C_ERR) { + if (zobj == NULL || zsetScore(zobj, objectGetVal(c->argv[j]), &score) == C_ERR) { addReplyNull(c); } else { addReplyDouble(c, score); @@ -3754,7 +3754,7 @@ void zrankGenericCommand(client *c, int reverse) { return; } if (c->argc > 3) { - if (!strcasecmp(c->argv[3]->ptr, "withscore")) { + if (!strcasecmp(objectGetVal(c->argv[3]), "withscore")) { opt_withscore = 1; } else { addReplyErrorObject(c, shared.syntaxerr); @@ -3766,7 +3766,7 @@ void zrankGenericCommand(client *c, int reverse) { return; } serverAssertWithInfo(c, ele, sdsEncodedObject(ele)); - rank = zsetRank(zobj, ele->ptr, reverse, opt_withscore ? &score : NULL); + rank = zsetRank(zobj, objectGetVal(ele), reverse, opt_withscore ? &score : NULL); if (rank >= 0) { if (opt_withscore) { addReplyArrayLen(c, 2); @@ -3796,7 +3796,7 @@ void zscanCommand(client *c) { robj *o; unsigned long long cursor; - if (parseScanCursorOrReply(c, c->argv[2]->ptr, &cursor) == C_ERR) return; + if (parseScanCursorOrReply(c, objectGetVal(c->argv[2]), &cursor) == C_ERR) return; if ((o = lookupKeyReadOrReply(c, c->argv[1], shared.emptyscan)) == NULL || checkType(c, o, OBJ_ZSET)) return; scanGenericCommand(c, o, cursor); } @@ -3894,7 +3894,7 @@ void genericZpopCommand(client *c, /* Remove the element. */ do { if (zobj->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = zobj->ptr; + unsigned char *zl = objectGetVal(zobj); unsigned char *eptr, *sptr; unsigned char *vstr; unsigned int vlen; @@ -3914,7 +3914,7 @@ void genericZpopCommand(client *c, serverAssertWithInfo(c, zobj, sptr != NULL); score = zzlGetScore(sptr); } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zobj->ptr; + zset *zs = objectGetVal(zobj); zskiplist *zsl = zs->zsl; zskiplistNode *zln; @@ -4127,7 +4127,7 @@ void zrandmemberWithCountCommand(client *c, long l, int withscores) { else addReplyArrayLen(c, count); if (zsetobj->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = zsetobj->ptr; + zset *zs = objectGetVal(zsetobj); while (count--) { void *entry; serverAssert(hashtableFairRandomEntry(zs->ht, &entry)); @@ -4147,7 +4147,7 @@ void zrandmemberWithCountCommand(client *c, long l, int withscores) { while (count) { sample_count = count > limit ? limit : count; count -= sample_count; - lpRandomPairs(zsetobj->ptr, sample_count, keys, vals); + lpRandomPairs(objectGetVal(zsetobj), sample_count, keys, vals); zrandmemberReplyWithListpack(c, sample_count, keys, vals); if (c->flag.close_asap) break; } @@ -4197,7 +4197,7 @@ void zrandmemberWithCountCommand(client *c, long l, int withscores) { listpackEntry *keys, *vals = NULL; keys = zmalloc(sizeof(listpackEntry) * count); if (withscores) vals = zmalloc(sizeof(listpackEntry) * count); - serverAssert(lpRandomPairsUnique(zsetobj->ptr, count, keys, vals) == count); + serverAssert(lpRandomPairsUnique(objectGetVal(zsetobj), count, keys, vals) == count); zrandmemberReplyWithListpack(c, count, keys, vals); zfree(keys); zfree(vals); @@ -4218,7 +4218,7 @@ void zrandmemberWithCountCommand(client *c, long l, int withscores) { /* Hashtable encoding (generic implementation) */ hashtable *ht = hashtableCreate(&zsetHashtableType); hashtableExpand(ht, size); - zset *zs = src.subject->ptr; + zset *zs = objectGetVal(src.subject); hashtableIterator iter; hashtableInitIterator(&iter, zs->ht, 0); void *entry; @@ -4298,7 +4298,7 @@ void zrandmemberCommand(client *c) { if (c->argc >= 3) { if (getRangeLongFromObjectOrReply(c, c->argv[2], -LONG_MAX, LONG_MAX, &l, NULL) != C_OK) return; - if (c->argc > 4 || (c->argc == 4 && strcasecmp(c->argv[3]->ptr, "withscores"))) { + if (c->argc > 4 || (c->argc == 4 && strcasecmp(objectGetVal(c->argv[3]), "withscores"))) { addReplyErrorObject(c, shared.syntaxerr); return; } else if (c->argc == 4) { @@ -4342,9 +4342,9 @@ void zmpopGenericCommand(client *c, int numkeys_idx, int is_block) { addReplyErrorObject(c, shared.syntaxerr); return; } - if (!strcasecmp(c->argv[where_idx]->ptr, "MIN")) { + if (!strcasecmp(objectGetVal(c->argv[where_idx]), "MIN")) { where = ZSET_MIN; - } else if (!strcasecmp(c->argv[where_idx]->ptr, "MAX")) { + } else if (!strcasecmp(objectGetVal(c->argv[where_idx]), "MAX")) { where = ZSET_MAX; } else { addReplyErrorObject(c, shared.syntaxerr); @@ -4353,7 +4353,7 @@ void zmpopGenericCommand(client *c, int numkeys_idx, int is_block) { /* Parse the optional arguments. */ for (j = where_idx + 1; j < c->argc; j++) { - char *opt = c->argv[j]->ptr; + char *opt = objectGetVal(c->argv[j]); int moreargs = (c->argc - 1) - j; if (count == -1 && !strcasecmp(opt, "COUNT") && moreargs) { diff --git a/src/tracking.c b/src/tracking.c index a34e4e1eb..40943e66a 100644 --- a/src/tracking.c +++ b/src/tracking.c @@ -122,12 +122,12 @@ int checkPrefixCollisionsOrReply(client *c, robj **prefixes, size_t numprefix) { raxStart(&ri, c->pubsub_data->client_tracking_prefixes); raxSeek(&ri, "^", NULL, 0); while (raxNext(&ri)) { - if (stringCheckPrefix(ri.key, ri.key_len, prefixes[i]->ptr, sdslen(prefixes[i]->ptr))) { + if (stringCheckPrefix(ri.key, ri.key_len, objectGetVal(prefixes[i]), sdslen(objectGetVal(prefixes[i])))) { sds collision = sdsnewlen(ri.key, ri.key_len); addReplyErrorFormat(c, "Prefix '%s' overlaps with an existing prefix '%s'. " "Prefixes for a single client must not overlap.", - (unsigned char *)prefixes[i]->ptr, (unsigned char *)collision); + (unsigned char *)objectGetVal(prefixes[i]), (unsigned char *)collision); sdsfree(collision); raxStop(&ri); return 0; @@ -137,12 +137,12 @@ int checkPrefixCollisionsOrReply(client *c, robj **prefixes, size_t numprefix) { } /* Check input has no overlap with itself. */ for (size_t j = i + 1; j < numprefix; j++) { - if (stringCheckPrefix(prefixes[i]->ptr, sdslen(prefixes[i]->ptr), prefixes[j]->ptr, - sdslen(prefixes[j]->ptr))) { + if (stringCheckPrefix(objectGetVal(prefixes[i]), sdslen(objectGetVal(prefixes[i])), objectGetVal(prefixes[j]), + sdslen(objectGetVal(prefixes[j])))) { addReplyErrorFormat(c, "Prefix '%s' overlaps with another provided prefix '%s'. " "Prefixes for a single client must not overlap.", - (unsigned char *)prefixes[i]->ptr, (unsigned char *)prefixes[j]->ptr); + (unsigned char *)objectGetVal(prefixes[i]), (unsigned char *)objectGetVal(prefixes[j])); return i; } } @@ -202,7 +202,7 @@ void enableTracking(client *c, uint64_t redirect_to, struct ClientFlags options, c->flag.tracking_bcast = 1; if (numprefix == 0) enableBcastTrackingForPrefix(c, "", 0); for (size_t j = 0; j < numprefix; j++) { - sds sdsprefix = prefix[j]->ptr; + sds sdsprefix = objectGetVal(prefix[j]); enableBcastTrackingForPrefix(c, sdsprefix, sdslen(sdsprefix)); } } @@ -245,7 +245,7 @@ void trackingRememberKeys(client *tracking, client *executing) { for (int j = 0; j < numkeys; j++) { int idx = keys[j].pos; - sds sdskey = executing->argv[idx]->ptr; + sds sdskey = objectGetVal(executing->argv[idx]); void *result; rax *ids; if (!raxFind(TrackingTable, (unsigned char *)sdskey, sdslen(sdskey), &result)) { @@ -373,8 +373,8 @@ void trackingRememberKeyToBroadcast(client *c, char *keyname, size_t keylen) { void trackingInvalidateKey(client *c, robj *keyobj, int bcast) { if (TrackingTable == NULL) return; - unsigned char *key = (unsigned char *)keyobj->ptr; - size_t keylen = sdslen(keyobj->ptr); + unsigned char *key = (unsigned char *)objectGetVal(keyobj); + size_t keylen = sdslen(objectGetVal(keyobj)); if (bcast && raxSize(PrefixTable) > 0) trackingRememberKeyToBroadcast(c, (char *)key, keylen); @@ -411,7 +411,7 @@ void trackingInvalidateKey(client *c, robj *keyobj, int bcast) { incrRefCount(keyobj); listAddNodeTail(server.tracking_pending_keys, keyobj); } else { - sendTrackingMessage(target, (char *)keyobj->ptr, sdslen(keyobj->ptr), 0); + sendTrackingMessage(target, (char *)objectGetVal(keyobj), sdslen(objectGetVal(keyobj)), 0); } } raxStop(&ri); @@ -440,10 +440,10 @@ void trackingHandlePendingKeyInvalidations(void) { * message only when current_client is still alive */ if (server.current_client != NULL) { if (key != NULL) { - sendTrackingMessage(server.current_client, (char *)key->ptr, sdslen(key->ptr), 0); + sendTrackingMessage(server.current_client, (char *)objectGetVal(key), sdslen(objectGetVal(key)), 0); } else { - sendTrackingMessage(server.current_client, shared.null[server.current_client->resp]->ptr, - sdslen(shared.null[server.current_client->resp]->ptr), 1); + sendTrackingMessage(server.current_client, objectGetVal(shared.null[server.current_client->resp]), + sdslen(objectGetVal(shared.null[server.current_client->resp])), 1); } } if (key != NULL) decrRefCount(key); @@ -479,7 +479,7 @@ void trackingInvalidateKeysOnFlush(int async) { /* We use a special NULL to indicate that we should send null */ listAddNodeTail(server.tracking_pending_keys, NULL); } else { - sendTrackingMessage(c, shared.null[c->resp]->ptr, sdslen(shared.null[c->resp]->ptr), 1); + sendTrackingMessage(c, objectGetVal(shared.null[c->resp]), sdslen(objectGetVal(shared.null[c->resp])), 1); } } } diff --git a/src/unit/test_files.h b/src/unit/test_files.h index 09dbfe590..c28847c64 100644 --- a/src/unit/test_files.h +++ b/src/unit/test_files.h @@ -123,6 +123,9 @@ int test_addRepliesWithOffloadsToList(int argc, char **argv, int flags); int test_addBufferToReplyIOV(int argc, char **argv, int flags); int test_object_with_key(int argc, char **argv, int flags); int test_embedded_string_with_key(int argc, char **argv, int flags); +int test_embedded_string_with_key_and_expire(int argc, char **argv, int flags); +int test_embedded_value(int argc, char **argv, int flags); +int test_unembed_value(int argc, char **argv, int flags); int test_quicklistCreateList(int argc, char **argv, int flags); int test_quicklistAddToTailOfEmptyList(int argc, char **argv, int flags); int test_quicklistAddToHeadOfEmptyList(int argc, char **argv, int flags); @@ -273,7 +276,7 @@ unitTest __test_intset_c[] = {{"test_intsetValueEncodings", test_intsetValueEnco unitTest __test_kvstore_c[] = {{"test_kvstoreAdd16Keys", test_kvstoreAdd16Keys}, {"test_kvstoreIteratorRemoveAllKeysNoDeleteEmptyHashtable", test_kvstoreIteratorRemoveAllKeysNoDeleteEmptyHashtable}, {"test_kvstoreIteratorRemoveAllKeysDeleteEmptyHashtable", test_kvstoreIteratorRemoveAllKeysDeleteEmptyHashtable}, {"test_kvstoreHashtableIteratorRemoveAllKeysNoDeleteEmptyHashtable", test_kvstoreHashtableIteratorRemoveAllKeysNoDeleteEmptyHashtable}, {"test_kvstoreHashtableIteratorRemoveAllKeysDeleteEmptyHashtable", test_kvstoreHashtableIteratorRemoveAllKeysDeleteEmptyHashtable}, {"test_kvstoreHashtableExpand", test_kvstoreHashtableExpand}, {NULL, NULL}}; unitTest __test_listpack_c[] = {{"test_listpackCreateIntList", test_listpackCreateIntList}, {"test_listpackCreateList", test_listpackCreateList}, {"test_listpackLpPrepend", test_listpackLpPrepend}, {"test_listpackLpPrependInteger", test_listpackLpPrependInteger}, {"test_listpackGetELementAtIndex", test_listpackGetELementAtIndex}, {"test_listpackPop", test_listpackPop}, {"test_listpackGetELementAtIndex2", test_listpackGetELementAtIndex2}, {"test_listpackIterate0toEnd", test_listpackIterate0toEnd}, {"test_listpackIterate1toEnd", test_listpackIterate1toEnd}, {"test_listpackIterate2toEnd", test_listpackIterate2toEnd}, {"test_listpackIterateBackToFront", test_listpackIterateBackToFront}, {"test_listpackIterateBackToFrontWithDelete", test_listpackIterateBackToFrontWithDelete}, {"test_listpackDeleteWhenNumIsMinusOne", test_listpackDeleteWhenNumIsMinusOne}, {"test_listpackDeleteWithNegativeIndex", test_listpackDeleteWithNegativeIndex}, {"test_listpackDeleteInclusiveRange0_0", test_listpackDeleteInclusiveRange0_0}, {"test_listpackDeleteInclusiveRange0_1", test_listpackDeleteInclusiveRange0_1}, {"test_listpackDeleteInclusiveRange1_2", test_listpackDeleteInclusiveRange1_2}, {"test_listpackDeleteWitStartIndexOutOfRange", test_listpackDeleteWitStartIndexOutOfRange}, {"test_listpackDeleteWitNumOverflow", test_listpackDeleteWitNumOverflow}, {"test_listpackBatchDelete", test_listpackBatchDelete}, {"test_listpackDeleteFooWhileIterating", test_listpackDeleteFooWhileIterating}, {"test_listpackReplaceWithSameSize", test_listpackReplaceWithSameSize}, {"test_listpackReplaceWithDifferentSize", test_listpackReplaceWithDifferentSize}, {"test_listpackRegressionGt255Bytes", test_listpackRegressionGt255Bytes}, {"test_listpackCreateLongListAndCheckIndices", test_listpackCreateLongListAndCheckIndices}, {"test_listpackCompareStrsWithLpEntries", test_listpackCompareStrsWithLpEntries}, {"test_listpackLpMergeEmptyLps", test_listpackLpMergeEmptyLps}, {"test_listpackLpMergeLp1Larger", test_listpackLpMergeLp1Larger}, {"test_listpackLpMergeLp2Larger", test_listpackLpMergeLp2Larger}, {"test_listpackLpNextRandom", test_listpackLpNextRandom}, {"test_listpackLpNextRandomCC", test_listpackLpNextRandomCC}, {"test_listpackRandomPairWithOneElement", test_listpackRandomPairWithOneElement}, {"test_listpackRandomPairWithManyElements", test_listpackRandomPairWithManyElements}, {"test_listpackRandomPairsWithOneElement", test_listpackRandomPairsWithOneElement}, {"test_listpackRandomPairsWithManyElements", test_listpackRandomPairsWithManyElements}, {"test_listpackRandomPairsUniqueWithOneElement", test_listpackRandomPairsUniqueWithOneElement}, {"test_listpackRandomPairsUniqueWithManyElements", test_listpackRandomPairsUniqueWithManyElements}, {"test_listpackPushVariousEncodings", test_listpackPushVariousEncodings}, {"test_listpackLpFind", test_listpackLpFind}, {"test_listpackLpValidateIntegrity", test_listpackLpValidateIntegrity}, {"test_listpackNumberOfElementsExceedsLP_HDR_NUMELE_UNKNOWN", test_listpackNumberOfElementsExceedsLP_HDR_NUMELE_UNKNOWN}, {"test_listpackStressWithRandom", test_listpackStressWithRandom}, {"test_listpackSTressWithVariableSize", test_listpackSTressWithVariableSize}, {"test_listpackBenchmarkInit", test_listpackBenchmarkInit}, {"test_listpackBenchmarkLpAppend", test_listpackBenchmarkLpAppend}, {"test_listpackBenchmarkLpFindString", test_listpackBenchmarkLpFindString}, {"test_listpackBenchmarkLpFindNumber", test_listpackBenchmarkLpFindNumber}, {"test_listpackBenchmarkLpSeek", test_listpackBenchmarkLpSeek}, {"test_listpackBenchmarkLpValidateIntegrity", test_listpackBenchmarkLpValidateIntegrity}, {"test_listpackBenchmarkLpCompareWithString", test_listpackBenchmarkLpCompareWithString}, {"test_listpackBenchmarkLpCompareWithNumber", test_listpackBenchmarkLpCompareWithNumber}, {"test_listpackBenchmarkFree", test_listpackBenchmarkFree}, {NULL, NULL}}; unitTest __test_networking_c[] = {{"test_writeToReplica", test_writeToReplica}, {"test_postWriteToReplica", test_postWriteToReplica}, {"test_backupAndUpdateClientArgv", test_backupAndUpdateClientArgv}, {"test_rewriteClientCommandArgument", test_rewriteClientCommandArgument}, {"test_addRepliesWithOffloadsToBuffer", test_addRepliesWithOffloadsToBuffer}, {"test_addRepliesWithOffloadsToList", test_addRepliesWithOffloadsToList}, {"test_addBufferToReplyIOV", test_addBufferToReplyIOV}, {NULL, NULL}}; -unitTest __test_object_c[] = {{"test_object_with_key", test_object_with_key}, {"test_embedded_string_with_key", test_embedded_string_with_key}, {NULL, NULL}}; +unitTest __test_object_c[] = {{"test_object_with_key", test_object_with_key}, {"test_embedded_string_with_key", test_embedded_string_with_key}, {"test_embedded_string_with_key_and_expire", test_embedded_string_with_key_and_expire}, {"test_embedded_value", test_embedded_value}, {"test_unembed_value", test_unembed_value}, {NULL, NULL}}; unitTest __test_quicklist_c[] = {{"test_quicklistCreateList", test_quicklistCreateList}, {"test_quicklistAddToTailOfEmptyList", test_quicklistAddToTailOfEmptyList}, {"test_quicklistAddToHeadOfEmptyList", test_quicklistAddToHeadOfEmptyList}, {"test_quicklistAddToTail5xAtCompress", test_quicklistAddToTail5xAtCompress}, {"test_quicklistAddToHead5xAtCompress", test_quicklistAddToHead5xAtCompress}, {"test_quicklistAddToTail500xAtCompress", test_quicklistAddToTail500xAtCompress}, {"test_quicklistAddToHead500xAtCompress", test_quicklistAddToHead500xAtCompress}, {"test_quicklistRotateEmpty", test_quicklistRotateEmpty}, {"test_quicklistComprassionPlainNode", test_quicklistComprassionPlainNode}, {"test_quicklistNextPlainNode", test_quicklistNextPlainNode}, {"test_quicklistRotatePlainNode", test_quicklistRotatePlainNode}, {"test_quicklistRotateOneValOnce", test_quicklistRotateOneValOnce}, {"test_quicklistRotate500Val5000TimesAtCompress", test_quicklistRotate500Val5000TimesAtCompress}, {"test_quicklistPopEmpty", test_quicklistPopEmpty}, {"test_quicklistPop1StringFrom1", test_quicklistPop1StringFrom1}, {"test_quicklistPopHead1NumberFrom1", test_quicklistPopHead1NumberFrom1}, {"test_quicklistPopHead500From500", test_quicklistPopHead500From500}, {"test_quicklistPopHead5000From500", test_quicklistPopHead5000From500}, {"test_quicklistIterateForwardOver500List", test_quicklistIterateForwardOver500List}, {"test_quicklistIterateReverseOver500List", test_quicklistIterateReverseOver500List}, {"test_quicklistInsertAfter1Element", test_quicklistInsertAfter1Element}, {"test_quicklistInsertBefore1Element", test_quicklistInsertBefore1Element}, {"test_quicklistInsertHeadWhileHeadNodeIsFull", test_quicklistInsertHeadWhileHeadNodeIsFull}, {"test_quicklistInsertTailWhileTailNodeIsFull", test_quicklistInsertTailWhileTailNodeIsFull}, {"test_quicklistInsertOnceInElementsWhileIteratingAtCompress", test_quicklistInsertOnceInElementsWhileIteratingAtCompress}, {"test_quicklistInsertBefore250NewInMiddleOf500ElementsAtCompress", test_quicklistInsertBefore250NewInMiddleOf500ElementsAtCompress}, {"test_quicklistInsertAfter250NewInMiddleOf500ElementsAtCompress", test_quicklistInsertAfter250NewInMiddleOf500ElementsAtCompress}, {"test_quicklistDuplicateEmptyList", test_quicklistDuplicateEmptyList}, {"test_quicklistDuplicateListOf1Element", test_quicklistDuplicateListOf1Element}, {"test_quicklistDuplicateListOf500", test_quicklistDuplicateListOf500}, {"test_quicklistIndex1200From500ListAtFill", test_quicklistIndex1200From500ListAtFill}, {"test_quicklistIndex12From500ListAtFill", test_quicklistIndex12From500ListAtFill}, {"test_quicklistIndex100From500ListAtFill", test_quicklistIndex100From500ListAtFill}, {"test_quicklistIndexTooBig1From50ListAtFill", test_quicklistIndexTooBig1From50ListAtFill}, {"test_quicklistDeleteRangeEmptyList", test_quicklistDeleteRangeEmptyList}, {"test_quicklistDeleteRangeOfEntireNodeInListOfOneNode", test_quicklistDeleteRangeOfEntireNodeInListOfOneNode}, {"test_quicklistDeleteRangeOfEntireNodeWithOverflowCounts", test_quicklistDeleteRangeOfEntireNodeWithOverflowCounts}, {"test_quicklistDeleteMiddle100Of500List", test_quicklistDeleteMiddle100Of500List}, {"test_quicklistDeleteLessThanFillButAcrossNodes", test_quicklistDeleteLessThanFillButAcrossNodes}, {"test_quicklistDeleteNegative1From500List", test_quicklistDeleteNegative1From500List}, {"test_quicklistDeleteNegative1From500ListWithOverflowCounts", test_quicklistDeleteNegative1From500ListWithOverflowCounts}, {"test_quicklistDeleteNegative100From500List", test_quicklistDeleteNegative100From500List}, {"test_quicklistDelete10Count5From50List", test_quicklistDelete10Count5From50List}, {"test_quicklistNumbersOnlyListRead", test_quicklistNumbersOnlyListRead}, {"test_quicklistNumbersLargerListRead", test_quicklistNumbersLargerListRead}, {"test_quicklistNumbersLargerListReadB", test_quicklistNumbersLargerListReadB}, {"test_quicklistLremTestAtCompress", test_quicklistLremTestAtCompress}, {"test_quicklistIterateReverseDeleteAtCompress", test_quicklistIterateReverseDeleteAtCompress}, {"test_quicklistIteratorAtIndexTestAtCompress", test_quicklistIteratorAtIndexTestAtCompress}, {"test_quicklistLtrimTestAAtCompress", test_quicklistLtrimTestAAtCompress}, {"test_quicklistLtrimTestBAtCompress", test_quicklistLtrimTestBAtCompress}, {"test_quicklistLtrimTestCAtCompress", test_quicklistLtrimTestCAtCompress}, {"test_quicklistLtrimTestDAtCompress", test_quicklistLtrimTestDAtCompress}, {"test_quicklistVerifySpecificCompressionOfInteriorNodes", test_quicklistVerifySpecificCompressionOfInteriorNodes}, {"test_quicklistBookmarkGetUpdatedToNextItem", test_quicklistBookmarkGetUpdatedToNextItem}, {"test_quicklistBookmarkLimit", test_quicklistBookmarkLimit}, {"test_quicklistCompressAndDecompressQuicklistListpackNode", test_quicklistCompressAndDecompressQuicklistListpackNode}, {"test_quicklistCompressAndDecomressQuicklistPlainNodeLargeThanUINT32MAX", test_quicklistCompressAndDecomressQuicklistPlainNodeLargeThanUINT32MAX}, {NULL, NULL}}; unitTest __test_rax_c[] = {{"test_raxRandomWalk", test_raxRandomWalk}, {"test_raxIteratorUnitTests", test_raxIteratorUnitTests}, {"test_raxTryInsertUnitTests", test_raxTryInsertUnitTests}, {"test_raxRegressionTest1", test_raxRegressionTest1}, {"test_raxRegressionTest2", test_raxRegressionTest2}, {"test_raxRegressionTest3", test_raxRegressionTest3}, {"test_raxRegressionTest4", test_raxRegressionTest4}, {"test_raxRegressionTest5", test_raxRegressionTest5}, {"test_raxRegressionTest6", test_raxRegressionTest6}, {"test_raxBenchmark", test_raxBenchmark}, {"test_raxHugeKey", test_raxHugeKey}, {"test_raxFuzz", test_raxFuzz}, {"test_raxRecompressHugeKey", test_raxRecompressHugeKey}, {NULL, NULL}}; unitTest __test_sds_c[] = {{"test_sds", test_sds}, {"test_typesAndAllocSize", test_typesAndAllocSize}, {"test_sdsHeaderSizes", test_sdsHeaderSizes}, {"test_sdssplitargs", test_sdssplitargs}, {NULL, NULL}}; diff --git a/src/unit/test_object.c b/src/unit/test_object.c index 8c4eb0794..8e655fe27 100644 --- a/src/unit/test_object.c +++ b/src/unit/test_object.c @@ -14,37 +14,38 @@ int test_object_with_key(int argc, char **argv, int flags) { sds key = sdsnew("foo"); robj *val = createStringObject("bar", strlen("bar")); TEST_ASSERT(val->encoding == OBJ_ENCODING_EMBSTR); + TEST_ASSERT(sdslen(objectGetVal(val)) == 3); /* Prevent objectSetKeyAndExpire from freeing the old val when reallocating it. */ incrRefCount(val); - /* Create valkey: val with key. */ - robj *valkey = objectSetKeyAndExpire(val, key, -1); - TEST_ASSERT(valkey->encoding == OBJ_ENCODING_EMBSTR); - TEST_ASSERT(objectGetKey(valkey) != NULL); + robj *o = objectSetKeyAndExpire(val, key, -1); + TEST_ASSERT(o->encoding == OBJ_ENCODING_EMBSTR); + TEST_ASSERT(objectGetKey(o) != NULL); /* Check embedded key "foo" */ - TEST_ASSERT(sdslen(objectGetKey(valkey)) == 3); + TEST_ASSERT(sdslen(objectGetKey(o)) == 3); TEST_ASSERT(sdslen(key) == 3); - TEST_ASSERT(sdscmp(objectGetKey(valkey), key) == 0); - TEST_ASSERT(strcmp(objectGetKey(valkey), "foo") == 0); + TEST_ASSERT(sdscmp(objectGetKey(o), key) == 0); + TEST_ASSERT(strcmp(objectGetKey(o), "foo") == 0); /* Check embedded value "bar" (EMBSTR content) */ - TEST_ASSERT(sdscmp(valkey->ptr, val->ptr) == 0); - TEST_ASSERT(strcmp(valkey->ptr, "bar") == 0); + TEST_ASSERT(sdscmp(objectGetVal(o), objectGetVal(val)) == 0); + TEST_ASSERT(strcmp(objectGetVal(o), "bar") == 0); + TEST_ASSERT(sdslen(objectGetVal(o)) == 3); /* Either they're two separate objects, or one object with refcount == 2. */ - if (valkey == val) { - TEST_ASSERT(valkey->refcount == 2); + if (o == val) { + TEST_ASSERT(o->refcount == 2); } else { - TEST_ASSERT(valkey->refcount == 1); + TEST_ASSERT(o->refcount == 1); TEST_ASSERT(val->refcount == 1); } /* Free them. */ sdsfree(key); decrRefCount(val); - decrRefCount(valkey); + decrRefCount(o); return 0; } @@ -52,28 +53,129 @@ int test_embedded_string_with_key(int argc, char **argv, int flags) { UNUSED(argc); UNUSED(argv); UNUSED(flags); - int is_32bit = sizeof(void *) == 4; /* key of length 32 - type 8 */ sds key = sdsnew("k:123456789012345678901234567890"); + TEST_ASSERT(sdslen(key) == 32); - /* value of length 7 should be embedded (length 11 for 32-bit) */ - const char *short_value = is_32bit ? "v:123456789" : "v:12345"; + /* 32B key and 79B value should be embedded within 128B. Contents: + * - 8B robj (no ptr) + 1B key header size + * - 3B key header + 32B key + 1B null terminator + * - 3B val header + 79B val + 1B null terminator + * because no pointers are stored, there is no difference for 32 bit builds*/ + const char *short_value = "1234567890123456789012345678901234567890123456789012345678901234567890123456789"; + TEST_ASSERT(strlen(short_value) == 79); robj *short_val_obj = createStringObject(short_value, strlen(short_value)); - - /* value of length 8 should be raw (12 for 32-bit), because the total size - * is over 64. */ - const char *longer_value = is_32bit ? "v:1234567890" : "v:123456"; - robj *longer_val_obj = createStringObject(longer_value, strlen(longer_value)); - robj *embstr_obj = objectSetKeyAndExpire(short_val_obj, key, -1); TEST_ASSERT(embstr_obj->encoding == OBJ_ENCODING_EMBSTR); + TEST_ASSERT(sdslen(objectGetKey(embstr_obj)) == 32); + TEST_ASSERT(sdscmp(objectGetKey(embstr_obj), key) == 0); + TEST_ASSERT(sdslen(objectGetVal(embstr_obj)) == 79); + TEST_ASSERT(strcmp(objectGetVal(embstr_obj), short_value) == 0); + /* value of length 80 cannot be embedded with other contents within 128B */ + const char *longer_value = "12345678901234567890123456789012345678901234567890123456789012345678901234567890"; + TEST_ASSERT(strlen(longer_value) == 80); + robj *longer_val_obj = createStringObject(longer_value, strlen(longer_value)); robj *raw_obj = objectSetKeyAndExpire(longer_val_obj, key, -1); TEST_ASSERT(raw_obj->encoding == OBJ_ENCODING_RAW); + TEST_ASSERT(sdslen(objectGetKey(raw_obj)) == 32); + TEST_ASSERT(sdscmp(objectGetKey(raw_obj), key) == 0); + TEST_ASSERT(sdslen(objectGetVal(raw_obj)) == 80); + TEST_ASSERT(strcmp(objectGetVal(raw_obj), longer_value) == 0); sdsfree(key); decrRefCount(embstr_obj); decrRefCount(raw_obj); return 0; } + +int test_embedded_string_with_key_and_expire(int argc, char **argv, int flags) { + UNUSED(argc); + UNUSED(argv); + UNUSED(flags); + + /* key of length 32 - type 8 */ + sds key = sdsnew("k:123456789012345678901234567890"); + TEST_ASSERT(sdslen(key) == 32); + + /* 32B key and 71B value should be embedded within 128B. Contents: + * - 8B robj (no ptr) + 8B expire + 1B key header size + * - 3B key header + 32B key + 1B null terminator + * - 3B val header + 71B val + 1B null terminator + * because no pointers are stored, there is no difference for 32 bit builds*/ + const char *short_value = "12345678901234567890123456789012345678901234567890123456789012345678901"; + TEST_ASSERT(strlen(short_value) == 71); + robj *short_val_obj = createStringObject(short_value, strlen(short_value)); + robj *embstr_obj = objectSetKeyAndExpire(short_val_obj, key, 128); + TEST_ASSERT(embstr_obj->encoding == OBJ_ENCODING_EMBSTR); + TEST_ASSERT(sdslen(objectGetKey(embstr_obj)) == 32); + TEST_ASSERT(sdscmp(objectGetKey(embstr_obj), key) == 0); + TEST_ASSERT(sdslen(objectGetVal(embstr_obj)) == 71); + TEST_ASSERT(strcmp(objectGetVal(embstr_obj), short_value) == 0); + + /* value of length 72 cannot be embedded with other contents within 64B */ + const char *longer_value = "123456789012345678901234567890123456789012345678901234567890123456789012"; + TEST_ASSERT(strlen(longer_value) == 72); + robj *longer_val_obj = createStringObject(longer_value, strlen(longer_value)); + robj *raw_obj = objectSetKeyAndExpire(longer_val_obj, key, 128); + TEST_ASSERT(raw_obj->encoding == OBJ_ENCODING_RAW); + TEST_ASSERT(sdslen(objectGetKey(raw_obj)) == 32); + TEST_ASSERT(sdscmp(objectGetKey(raw_obj), key) == 0); + TEST_ASSERT(sdslen(objectGetVal(raw_obj)) == 72); + TEST_ASSERT(strcmp(objectGetVal(raw_obj), longer_value) == 0); + + sdsfree(key); + decrRefCount(embstr_obj); + decrRefCount(raw_obj); + return 0; +} + +int test_embedded_value(int argc, char **argv, int flags) { + UNUSED(argc); + UNUSED(argv); + UNUSED(flags); + + /* with only value there is only 12B overhead, so we can embed up to 52B. + * 8B robj (no ptr) + 3B val header + 52B val + 1B null terminator */ + const char *val = "v:12345678901234567890123456789012345678901234567890"; + TEST_ASSERT(strlen(val) == 52); + robj *embstr_obj = createStringObject(val, strlen(val)); + TEST_ASSERT(embstr_obj->encoding == OBJ_ENCODING_EMBSTR); + TEST_ASSERT(sdslen(objectGetVal(embstr_obj)) == 52); + TEST_ASSERT(strcmp(objectGetVal(embstr_obj), val) == 0); + + decrRefCount(embstr_obj); + return 0; +} + +int test_unembed_value(int argc, char **argv, int flags) { + UNUSED(argc); + UNUSED(argv); + UNUSED(flags); + + const char *short_value = "embedded value"; + robj *short_val_obj = createStringObject(short_value, strlen(short_value)); + sds key = sdsnew("embedded key"); + long long expire = 155; + + robj *obj = objectSetKeyAndExpire(short_val_obj, key, expire); + TEST_ASSERT(obj->encoding == OBJ_ENCODING_EMBSTR); + TEST_ASSERT(strcmp(objectGetVal(obj), short_value) == 0); + TEST_ASSERT(sdscmp(objectGetKey(obj), key) == 0); + TEST_ASSERT(objectGetExpire(obj) == expire); + TEST_ASSERT(objectGetVal(obj) != short_value); + + /* Unembed the value - it uses a separate allocation now. + * the other embedded data gets shifted, so check them too */ + objectUnembedVal(obj); + TEST_ASSERT(obj->encoding == OBJ_ENCODING_RAW); + TEST_ASSERT(strcmp(objectGetVal(obj), short_value) == 0); + TEST_ASSERT(sdscmp(objectGetKey(obj), key) == 0); + TEST_ASSERT(objectGetExpire(obj) == expire); + TEST_ASSERT(objectGetVal(obj) != short_value); /* different allocation, different copy */ + + sdsfree(key); + decrRefCount(obj); + return 0; +} diff --git a/src/valkey-check-rdb.c b/src/valkey-check-rdb.c index e1fbcf02a..42a942e56 100644 --- a/src/valkey-check-rdb.c +++ b/src/valkey-check-rdb.c @@ -252,7 +252,7 @@ void computeDatasetProfile(int dbid, robj *keyobj, robj *o, long long expiretime rdbStats *stats = rdbstate.stats[o->type + dbid * OBJ_TYPE_MAX]; - stats->all_key_size += sdslen(keyobj->ptr); + stats->all_key_size += sdslen(objectGetVal(keyobj)); stats->keys++; /* Check if the key already expired. */ @@ -285,7 +285,7 @@ void computeDatasetProfile(int dbid, robj *keyobj, robj *o, long long expiretime statsRecordCount(setTypeSize(o), stats); } else if (o->type == OBJ_ZSET) { if (o->encoding == OBJ_ENCODING_LISTPACK) { - unsigned char *zl = o->ptr; + unsigned char *zl = objectGetVal(o); unsigned char *eptr, *sptr; unsigned char *vstr; unsigned int vlen; @@ -315,9 +315,9 @@ void computeDatasetProfile(int dbid, robj *keyobj, robj *o, long long expiretime statsRecordElementSize(eleLen, 1, stats); zzlNext(zl, &eptr, &sptr); } - statsRecordCount(lpLength(o->ptr), stats); + statsRecordCount(lpLength(objectGetVal(o)), stats); } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { - zset *zs = o->ptr; + zset *zs = objectGetVal(o); hashtableIterator iter; hashtableInitIterator(&iter, zs->ht, 0); @@ -357,7 +357,7 @@ void computeDatasetProfile(int dbid, robj *keyobj, robj *o, long long expiretime statsRecordCount(hashTypeLength(o), stats); } else if (o->type == OBJ_STREAM) { streamIterator si; - streamIteratorStart(&si, o->ptr, NULL, NULL, 0); + streamIteratorStart(&si, objectGetVal(o), NULL, NULL, 0); streamID id; int64_t numfields; @@ -524,7 +524,7 @@ void rdbCheckError(const char *fmt, ...) { printf("--- RDB ERROR DETECTED ---\n"); printf("[offset %llu] %s\n", (unsigned long long)(rdbstate.rio ? rdbstate.rio->processed_bytes : 0), msg); printf("[additional info] While doing: %s\n", rdb_check_doing_string[rdbstate.doing]); - if (rdbstate.key) printf("[additional info] Reading key '%s'\n", (char *)rdbstate.key->ptr); + if (rdbstate.key) printf("[additional info] Reading key '%s'\n", (char *)objectGetVal(rdbstate.key)); if (rdbstate.key_type != -1) printf("[additional info] Reading type %d (%s)\n", rdbstate.key_type, ((unsigned)rdbstate.key_type < sizeof(rdb_type_string) / sizeof(char *)) @@ -725,11 +725,11 @@ int redis_check_rdb(char *rdbfilename, FILE *fp) { decrRefCount(auxkey); goto eoferr; } - if (!strcasecmp(auxkey->ptr, "lua")) { + if (!strcasecmp(objectGetVal(auxkey), "lua")) { /* In older version before 7.0, we may save lua scripts in a replication RDB. */ rdbstate.lua_scripts++; } - rdbCheckInfo("AUX FIELD %s = '%s'", (char *)auxkey->ptr, (char *)auxval->ptr); + rdbCheckInfo("AUX FIELD %s = '%s'", (char *)objectGetVal(auxkey), (char *)objectGetVal(auxval)); decrRefCount(auxkey); decrRefCount(auxval); continue; /* Read type again. */ @@ -788,7 +788,7 @@ int redis_check_rdb(char *rdbfilename, FILE *fp) { rdbstate.keys++; /* Read value */ rdbstate.doing = RDB_CHECK_DOING_READ_OBJECT_VALUE; - if ((val = rdbLoadObject(type, &rdb, key->ptr, selected_dbid, NULL)) == NULL) goto eoferr; + if ((val = rdbLoadObject(type, &rdb, objectGetVal(key), selected_dbid, NULL)) == NULL) goto eoferr; if (rdbCheckStats) { int max_stats_num = (rdbstate.databases + 1) * OBJ_TYPE_MAX; if (max_stats_num > rdbstate.stats_num) { diff --git a/tests/unit/type/string.tcl b/tests/unit/type/string.tcl index 1dce7fb51..401b4c2f1 100644 --- a/tests/unit/type/string.tcl +++ b/tests/unit/type/string.tcl @@ -816,22 +816,31 @@ if {[string match {*jemalloc*} [s mem_allocator]]} { if {[string match {*jemalloc*} [s mem_allocator]]} { test {Memory usage of embedded string value} { - # Check that we can fit 9 bytes of key + value into a 32 byte + # Check that we can fit 9 bytes of key + value into a 24 byte # allocation, including the serverObject itself. r set quux xyzzy - assert_lessthan_equal [r memory usage quux] 32 + assert_lessthan_equal [r memory usage quux] 24 # Check that the SDS overhead of the embedded key and value is 6 bytes # (sds5 + sds8). This is the memory layout: # - # +--------------+--------------+---------------+----------------+ - # | serverObject | | sds5 key | sds8 value | - # | header | key-hdr-size | hdr "quux" \0 | hdr "xyzzy" \0 | - # | 16 bytes | 1 | 1 + 4 + 1 | 3 + 5 + 1 | - # +--------------+--------------+---------------+----------------+ + # +-------------------+----------+---------------+----------------+ + # | robj header | key sds | sds5 key | sds8 value | + # | excluding val_ptr | hdr size | hdr "quux" \0 | hdr "xyzzy" \0 | + # | 8 bytes | 1 | 1 + 4 + 1 | 3 + 5 + 1 | + # +-------------------+----------+---------------+----------------+ # + # The test must work when the server is compiled for 32 bit and TCL is + # compiled and run on a 64 bit system or vice versa. The size of a + # pointer in the server is what matters. + set info_server [r info server] + regexp {arch_bits:(\d+)} $info_server _ arch_bits + set pointer_size [expr {$arch_bits / 8}] + set content_size [expr {[string length quux] + [string length xyzzy]}] regexp {robj:(\d+)} [r debug structsize] _ obj_header_size + # remove the size of the void *ptr (which is reused when value is embedded) + set obj_header_size [expr {$obj_header_size - $pointer_size}] set debug_sdslen [r debug sdslen quux] regexp {key_sds_len:4 key_sds_avail:0 obj_alloc:(\d+)} $debug_sdslen _ obj_alloc regexp {val_sds_len:5 val_sds_avail:(\d+) val_alloc:(\d+)} $debug_sdslen _ avail val_alloc