mirror of https://github.com/valkey-io/valkey
Merge 7afb48b24a into 8ab0152bef
This commit is contained in:
commit
d3289f84c7
60
src/acl.c
60
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 [<count> | 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;
|
||||
}
|
||||
|
|
|
|||
16
src/aof.c
16
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);
|
||||
|
|
|
|||
60
src/bitops.c
60
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 {
|
||||
|
|
|
|||
|
|
@ -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 <key> */
|
||||
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 <slot> */
|
||||
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 <slot> <count> */
|
||||
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 <NODE ID> */
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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 <SLOT> MIGRATING <NODE> */
|
||||
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 <SLOT> IMPORTING <NODE> */
|
||||
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 <SLOT> 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 <SLOT> NODE <NODE ID> */
|
||||
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 <SLOT> 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 <SLOT> NODE <NODE ID> */
|
||||
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 <ip> <port> [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> [slot] ... */
|
||||
/* CLUSTER DELSLOTS <slot> [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 <start slot> <end slot> [<start slot> <end slot> ...] */
|
||||
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 <node ID> */
|
||||
/* SETSLOT 10 IMPORTING <node ID> */
|
||||
/* SETSLOT 10 STABLE */
|
||||
/* SETSLOT 10 NODE <node ID> */
|
||||
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 <NODE ID> */
|
||||
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 (<NODE ID> | 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 <NODE ID> */
|
||||
/* 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 <NODE ID> */
|
||||
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 <NODE ID>]
|
||||
* 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 <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 <slot> [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 <start slot> <end slot> [<start slot> <end slot> ...] NODE <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 <subcommand>*/
|
||||
clusterCommandSyncSlots(c);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -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 <args> */
|
||||
clusterCommandSyncSlotsEstablish(c);
|
||||
return;
|
||||
}
|
||||
if (!strcasecmp(c->argv[2]->ptr, "finish")) {
|
||||
if (!strcasecmp(objectGetVal(c->argv[2]), "finish")) {
|
||||
/* CLUSTER SYNCSLOTS FINISH <args> */
|
||||
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 <field> [<field>...] */
|
||||
clusterCommandSyncSlotsCapa(c);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 [<count>]",
|
||||
" Return top <count> 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 <count> <type>",
|
||||
" Return top <count> entries of the specified <type> 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. */
|
||||
|
|
|
|||
14
src/config.c
14
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);
|
||||
}
|
||||
|
|
|
|||
150
src/db.c
150
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) {
|
||||
|
|
|
|||
218
src/debug.c
218
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 <microsec>",
|
||||
" 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);
|
||||
|
|
|
|||
55
src/defrag.c
55
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 {
|
||||
|
|
|
|||
50
src/eval.c
50
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) [<engine_name>]",
|
||||
" 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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
28
src/geo.c
28
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <key> */
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
|
|
|
|||
|
|
@ -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 <event> */
|
||||
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 <event> */
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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()");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
182
src/module.c
182
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 <name>
|
||||
*/
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
228
src/networking.c
228
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 $<length>\r\n<data>\r\n */
|
||||
c->net_output_bytes_curr_cmd += (num_len + 3); /* $<length>\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 <addr> */
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
372
src/object.c
372
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 <key>",
|
||||
" Return the kind of internal representation used in order to store the value",
|
||||
" associated with a <key>.",
|
||||
|
|
@ -1647,13 +1711,13 @@ void objectCommand(client *c) {
|
|||
" <key>.",
|
||||
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 <key> */
|
||||
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
|
||||
|
|
|
|||
30
src/pubsub.c
30
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 [<pattern>]",
|
||||
" Return the currently active channels matching a <pattern> (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 [<pattern>] */
|
||||
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);
|
||||
|
|
|
|||
178
src/rdb.c
178
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 */
|
||||
|
|
|
|||
|
|
@ -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 <client-id> 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 <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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(), "<value> 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;
|
||||
}
|
||||
|
|
|
|||
12
src/sds.c
12
src/sds.c
|
|
@ -33,7 +33,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#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)) {
|
||||
|
|
|
|||
12
src/sds.h
12
src/sds.h
|
|
@ -38,6 +38,7 @@ extern const char *SDS_NOINIT;
|
|||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* 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]);
|
||||
|
|
|
|||
148
src/sentinel.c
148
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 <primary-name>",
|
||||
" 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 <name> */
|
||||
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 <primary-name> */
|
||||
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 <primary-name> */
|
||||
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 <ip> <port> <current-epoch> <runid>
|
||||
*
|
||||
* 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 <pattern> */
|
||||
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 <primary-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 <primary-name> */
|
||||
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 <name> <ip> <port> <quorum> */
|
||||
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 <name> */
|
||||
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 <name> */
|
||||
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 <param> [<param> <param> ...] / SET <param> <value> [<param> "
|
||||
"<value> ...] are supported.");
|
||||
} else if (!strcasecmp(c->argv[1]->ptr, "info-cache")) {
|
||||
} else if (!strcasecmp(objectGetVal(c->argv[1]), "info-cache")) {
|
||||
/* SENTINEL INFO-CACHE <name> */
|
||||
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 <path> */
|
||||
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 <path> */
|
||||
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 <password> */
|
||||
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 <username> */
|
||||
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 <oldname> <newname> */
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
58
src/server.c
58
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 */
|
||||
|
|
|
|||
26
src/server.h
26
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);
|
||||
|
|
|
|||
44
src/sort.c
44
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);
|
||||
}
|
||||
|
|
|
|||
148
src/t_hash.c
148
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);
|
||||
|
|
|
|||
112
src/t_list.c
112
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) {
|
||||
|
|
|
|||
136
src/t_set.c
136
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);
|
||||
}
|
||||
|
|
|
|||
144
src/t_stream.c
144
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 ~ <count>. */
|
||||
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 ~ <id> */
|
||||
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 <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 { /* <start>, <stop> and <count> 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 <key> <groupname>",
|
||||
" Show consumers of <groupname>.",
|
||||
|
|
@ -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 "<subcommand> <key>". */
|
||||
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 <key> <group>. */
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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")) {
|
||||
|
|
|
|||
186
src/t_zset.c
186
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 <src> <min> <max> 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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue