Avoid redundant calls to sdslen(c->querybuf) in processMultibulkBuffer (#13787)

Optimize processMultibulkBuffer by avoiding redundant calls to
sdslen(c->querybuf).
The cached length is updated only when querybuf is modified.
This commit is contained in:
Filipe Oliveira (Redis) 2025-02-24 12:06:14 +00:00 committed by GitHub
parent 658424fc83
commit d7a448f9ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2438,6 +2438,7 @@ int processMultibulkBuffer(client *c) {
char *newline = NULL;
int ok;
long long ll;
size_t querybuf_len = sdslen(c->querybuf); /* Cache sdslen */
if (c->multibulklen == 0) {
/* The client should have been reset */
@ -2446,14 +2447,14 @@ int processMultibulkBuffer(client *c) {
/* Multi bulk length cannot be read without a \r\n */
newline = strchr(c->querybuf+c->qb_pos,'\r');
if (newline == NULL) {
if (sdslen(c->querybuf)-c->qb_pos > PROTO_INLINE_MAX_SIZE) {
if (querybuf_len-c->qb_pos > PROTO_INLINE_MAX_SIZE) {
c->read_error = CLIENT_READ_TOO_BIG_MBULK_COUNT_STRING;
}
return C_ERR;
}
/* Buffer should also contain \n */
if (newline-(c->querybuf+c->qb_pos) > (ssize_t)(sdslen(c->querybuf)-c->qb_pos-2))
if (newline-(c->querybuf+c->qb_pos) > (ssize_t)(querybuf_len-c->qb_pos-2))
return C_ERR;
/* We know for sure there is a whole line since newline != NULL,
@ -2494,7 +2495,7 @@ int processMultibulkBuffer(client *c) {
if (c->bulklen == -1) {
newline = strchr(c->querybuf+c->qb_pos,'\r');
if (newline == NULL) {
if (sdslen(c->querybuf)-c->qb_pos > PROTO_INLINE_MAX_SIZE) {
if (querybuf_len-c->qb_pos > PROTO_INLINE_MAX_SIZE) {
c->read_error = CLIENT_READ_TOO_BIG_BUCK_COUNT_STRING;
return C_ERR;
}
@ -2502,7 +2503,7 @@ int processMultibulkBuffer(client *c) {
}
/* Buffer should also contain \n */
if (newline-(c->querybuf+c->qb_pos) > (ssize_t)(sdslen(c->querybuf)-c->qb_pos-2))
if (newline-(c->querybuf+c->qb_pos) > (ssize_t)(querybuf_len-c->qb_pos-2))
break;
if (c->querybuf[c->qb_pos] != '$') {
@ -2535,23 +2536,24 @@ int processMultibulkBuffer(client *c) {
* or equal to ll+2. If the data length is greater than
* ll+2, trimming querybuf is just a waste of time, because
* at this time the querybuf contains not only our bulk. */
if (sdslen(c->querybuf)-c->qb_pos <= (size_t)ll+2) {
if (querybuf_len-c->qb_pos <= (size_t)ll+2) {
sdsrange(c->querybuf,c->qb_pos,-1);
querybuf_len = sdslen(c->querybuf);
c->qb_pos = 0;
/* Hint the sds library about the amount of bytes this string is
* going to contain. */
c->querybuf = sdsMakeRoomForNonGreedy(c->querybuf,ll+2-sdslen(c->querybuf));
c->querybuf = sdsMakeRoomForNonGreedy(c->querybuf,ll+2-querybuf_len);
/* We later set the peak to the used portion of the buffer, but here we over
* allocated because we know what we need, make sure it'll not be shrunk before used. */
if (c->querybuf_peak < (size_t)ll + 2) c->querybuf_peak = ll + 2;
querybuf_len = sdslen(c->querybuf); /* Update cached length */
}
}
c->bulklen = ll;
}
/* Read bulk argument */
if (sdslen(c->querybuf)-c->qb_pos < (size_t)(c->bulklen+2)) {
/* Not enough data (+2 == trailing \r\n) */
if (querybuf_len-c->qb_pos < (size_t)(c->bulklen+2)) {
break;
} else {
/* Check if we have space in argv, grow if needed */
@ -2567,7 +2569,7 @@ int processMultibulkBuffer(client *c) {
if (!(c->flags & CLIENT_MASTER) &&
c->qb_pos == 0 &&
c->bulklen >= PROTO_MBULK_BIG_ARG &&
sdslen(c->querybuf) == (size_t)(c->bulklen+2))
querybuf_len == (size_t)(c->bulklen+2))
{
c->argv[c->argc++] = createObject(OBJ_STRING,c->querybuf);
c->argv_len_sum += c->bulklen;
@ -2576,6 +2578,7 @@ int processMultibulkBuffer(client *c) {
* likely... */
c->querybuf = sdsnewlen(SDS_NOINIT,c->bulklen+2);
sdsclear(c->querybuf);
querybuf_len = sdslen(c->querybuf); /* Update cached length */
} else {
c->argv[c->argc++] =
createStringObject(c->querybuf+c->qb_pos,c->bulklen);