Repository: valkey-io/valkey
File: src/networking.c (C)

Code before:
    listRewind(c->reply,&li);

    /* Here, c->buf is not used, thus we confirm c->bufpos remains 0. */
    serverAssert(c->bufpos == 0);
    while ((ln = listNext(&li)) != NULL) {
        val_block = (clientReplyBlock *)listNodeValue(ln);
        cmd_response = sdscatlen(cmd_response, val_block->buf,val_block->used);
    }
    return cmd_response;
}

/* This function creates and returns a fake client for recording the command response 
 * to initiate caching of any command response.
 *
 * It needs be paired with `stopCaching` function to stop caching. */
client *createCachedResponseClient(void) {
    struct client *recording_client = createClient(NULL);
    /* Allocating the `conn` allows to prepare the caching client before adding
     * data to the clients output buffer by `prepareClientToWrite`. */
    recording_client->conn  = zcalloc(sizeof(connection));
    return recording_client;
}

/* This function is used to stop caching of any command response after `createCachedResponseClient` is called.
 * It returns the command response as SDS from the recording_client's reply buffer. */
sds stopCaching(client *recording_client) {
    zfree(recording_client->conn);
    recording_client->conn = NULL;
    sds output_buff = getClientOutputBuffer(recording_client);
    freeClient(recording_client);
    return output_buff;
}

/* -----------------------------------------------------------------------------
 * Low level functions to add more data to output buffers.
 * -------------------------------------------------------------------------- */

/* Attempts to add the reply to the static buffer in the client struct.
 * Returns the length of data that is added to the reply buffer.
 *
 * Sanitizer suppression: client->buf_usable_size determined by
 * zmalloc_usable_size() call. Writing beyond client->buf boundaries confuses
 * sanitizer and generates a false positive out-of-bounds error */
VALKEY_NO_SANITIZE("bounds")
size_t _addReplyToBuffer(client *c, const char *s, size_t len) {
    size_t available = c->buf_usable_size - c->bufpos;

    /* If there already are entries in the reply list, we cannot
     * add anything more to the static buffer. */
    if (listLength(c->reply) > 0) return 0;


Review comment (performance):
I would suggest moving `getClientOutputBuffer` out of this function and renaming `stopCaching` to `deleteCachedResponseClient` to match `createCachedResponseClient`, to improve readability. 

Code after:
    listRewind(c->reply,&li);

    /* Here, c->buf is not used, thus we confirm c->bufpos remains 0. */
    serverAssert(c->bufpos == 0);
    while ((ln = listNext(&li)) != NULL) {
        val_block = (clientReplyBlock *)listNodeValue(ln);
        cmd_response = sdscatlen(cmd_response, val_block->buf,val_block->used);
    }
    return cmd_response;
}

/* This function creates and returns a fake client for recording the command response 
 * to initiate caching of any command response.
 *
 * It needs be paired with `deleteCachedResponseClient` function to stop caching. */
client *createCachedResponseClient(void) {
    struct client *recording_client = createClient(NULL);
    /* Allocating the `conn` allows to prepare the caching client before adding
     * data to the clients output buffer by `prepareClientToWrite`. */
    recording_client->conn  = zcalloc(sizeof(connection));
    return recording_client;
}

/* This function is used to stop caching of any command response after `createCachedResponseClient` is called.
 * It returns the command response as SDS from the recording_client's reply buffer. */
void deleteCachedResponseClient(client *recording_client) {
    zfree(recording_client->conn);
    recording_client->conn = NULL;
    freeClient(recording_client);
}

/* -----------------------------------------------------------------------------
 * Low level functions to add more data to output buffers.
 * -------------------------------------------------------------------------- */

/* Attempts to add the reply to the static buffer in the client struct.
 * Returns the length of data that is added to the reply buffer.
 *
 * Sanitizer suppression: client->buf_usable_size determined by
 * zmalloc_usable_size() call. Writing beyond client->buf boundaries confuses
 * sanitizer and generates a false positive out-of-bounds error */
VALKEY_NO_SANITIZE("bounds")
size_t _addReplyToBuffer(client *c, const char *s, size_t len) {
    size_t available = c->buf_usable_size - c->bufpos;

    /* If there already are entries in the reply list, we cannot
     * add anything more to the static buffer. */
    if (listLength(c->reply) > 0) return 0;

    size_t reply_len = len > available ? available : len;
    memcpy(c->buf+c->bufpos,s,reply_len);