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

Code before:
                                struct serverCommand *cmd,
                                void (*reply_function)(client *, struct serverCommand *),
                                int use_map) {
    if (!cmd->subcommands_ht) {
        addReplySetLen(c, 0);
        return;
    }

    if (use_map)
        addReplyMapLen(c, hashtableSize(cmd->subcommands_ht));
    else
        addReplyArrayLen(c, hashtableSize(cmd->subcommands_ht));

    void *next;
    hashtableIterator iter;
    hashtableInitIterator(&iter, cmd->subcommands_ht, HASHTABLE_ITER_SAFE);
    while (hashtableNext(&iter, &next)) {
        struct serverCommand *sub = next;
        if (use_map) addReplyBulkCBuffer(c, sub->fullname, sdslen(sub->fullname));
        reply_function(c, sub);
    }
    hashtableResetIterator(&iter);
}

/* Forward declaration */
void addReplyCommandInfo(client *c, struct serverCommand *cmd);

/* Generate and cache the command info response for a given protocol version */
static void cacheCommandInfo(struct serverCommand *cmd, int resp) {
    client *caching_client = createCachedResponseClient(resp);
    
    int firstkey = 0, lastkey = 0, keystep = 0;
    if (cmd->legacy_range_key_spec.begin_search_type != KSPEC_BS_INVALID) {
        firstkey = cmd->legacy_range_key_spec.bs.index.pos;
        lastkey = cmd->legacy_range_key_spec.fk.range.lastkey;
        if (lastkey >= 0) lastkey += firstkey;
        keystep = cmd->legacy_range_key_spec.fk.range.keystep;
    }

    addReplyArrayLen(caching_client, 10);
    addReplyBulkCBuffer(caching_client, cmd->fullname, sdslen(cmd->fullname));
    addReplyLongLong(caching_client, cmd->arity);
    addReplyFlagsForCommand(caching_client, cmd);
    addReplyLongLong(caching_client, firstkey);
    addReplyLongLong(caching_client, lastkey);
    addReplyLongLong(caching_client, keystep);
    addReplyCommandCategories(caching_client, cmd);
    addReplyCommandTips(caching_client, cmd);
    addReplyCommandKeySpecs(caching_client, cmd);
    addReplyCommandSubCommands(caching_client, cmd, addReplyCommandInfo, 0);


Review comment (refactor):
There is a block of forward declarations near the top of this file where we could move this declaration, under

    /*============================ Internal prototypes ========================== */


Code after:
    addReplyBulkCBuffer(caching_client, cmd->fullname, sdslen(cmd->fullname));
    addReplyLongLong(caching_client, cmd->arity);
    addReplyFlagsForCommand(caching_client, cmd);
    addReplyLongLong(caching_client, firstkey);
    addReplyLongLong(caching_client, lastkey);
    addReplyLongLong(caching_client, keystep);
    addReplyCommandCategories(caching_client, cmd);
    addReplyCommandTips(caching_client, cmd);
    addReplyCommandKeySpecs(caching_client, cmd);
    addReplyCommandSubCommands(caching_client, cmd, addReplyCommandInfo, 0);

    sds command_info_response = aggregateClientOutputBuffer(caching_client);
    deleteCachedResponseClient(caching_client);
    return command_info_response;
}

int verifyCachedCommandInfoResponse(struct serverCommand *cmd, sds cached_response, int resp) {
    sds generated_response = generateCommandInfoResponse(cmd, resp);
    int is_equal = !sdscmp(generated_response, cached_response);
    /* Here, we use LL_WARNING so this gets printed when debug assertions are enabled and the system is about to crash. */
    if (!is_equal)
        serverLog(LL_WARNING, "\ngenerated_response:\n%s\n\ncached_response:\n%s", generated_response, cached_response);
    sdsfree(generated_response);
    return is_equal;
}

/* Output the representation of a server command. Used by the COMMAND command and COMMAND INFO. */
void addReplyCommandInfo(client *c, struct serverCommand *cmd) {
    if (!cmd) {
        addReplyNull(c);
    } else {
        /* Use cached response if available for the client's protocol version */
        int cache_idx = RESP_CACHE_INDEX(c->resp);
        sds cache = cmd->info_cache[cache_idx];

        if (cache == NULL) {
            cache = generateCommandInfoResponse(cmd, c->resp);
            cmd->info_cache[cache_idx] = cache;
        } else {
            debugServerAssertWithInfo(c, NULL, verifyCachedCommandInfoResponse(cmd, cache, c->resp));
        }

        addReplyProto(c, cache, sdslen(cache));
    }
}

/* Output the representation of a server command. Used by the COMMAND DOCS. */
void addReplyCommandDocs(client *c, struct serverCommand *cmd) {
    /* Count our reply len so we don't have to use deferred reply. */
    long maplen = 1;
    if (cmd->summary) maplen++;