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

Code before:
    freeReplyObject(reply);
    valkeyFree(c);
    return cfg;
fail:
    if (reply && reply->type == VALKEY_REPLY_ERROR && !strncmp(reply->str, "NOAUTH", 6)) {
        if (ct != VALKEY_CONN_UNIX)
            fprintf(stderr, "Node %s:%d replied with error:\n%s\n", ip_or_path, port, reply->str);
        else
            fprintf(stderr, "Node %s replied with error:\n%s\n", ip_or_path, reply->str);
        abort_test = 1;
    }
    freeReplyObject(reply);
    valkeyFree(c);
    freeServerConfig(cfg);
    if (abort_test) exit(1);
    return NULL;
}
static void freeServerConfig(serverConfig *cfg) {
    if (cfg->save) sdsfree(cfg->save);
    if (cfg->appendonly) sdsfree(cfg->appendonly);
    zfree(cfg);
}

void resetPlaceholders(void) {
    if (placeholders.indices[0])
        zfree(placeholders.indices[0]); /* indices are a single contiguous allocation */
    memset(&placeholders, 0, sizeof(placeholders));
}

void initPlaceholders(const char *cmd, size_t cmd_len) {
    resetPlaceholders();
    placeholders.cmd_len = cmd_len;

    /* store placeholder locations in temp arrays */
    size_t total_count = 0;
    size_t *temp_indices[PLACEHOLDER_COUNT];
    for (size_t placeholder = 0; placeholder < PLACEHOLDER_COUNT; placeholder++) {
        size_t *count = &placeholders.count[placeholder];
        *count = 0;

        size_t temp_size = RANDPTR_INITIAL_SIZE;
        temp_indices[placeholder] = zmalloc(sizeof(size_t) * temp_size);
        const char *p = cmd;
        const char *end = cmd + cmd_len;
        while ((p = strstr(p, BENCHMARK_PLACEHOLDERS[placeholder])) != NULL && p < end) {
            if (*count == temp_size) {
                temp_size *= 2;
                temp_indices[placeholder] = zrealloc(temp_indices[placeholder], sizeof(size_t) * temp_size);
            }
            size_t index = p - cmd;
            temp_indices[placeholder][*count] = index;

Review comment (suggestion):
Oh, confusing!

Let's use a separate struct field for the indices continuous allocation and let each of them point into this one, i.e. even indices[0] can point to the beginning of the continuous allocation.

```suggestion
    if (placeholders.all_indices)
        zfree(placeholders.all_indices); /* indices are a single contiguous allocation */
```

Code after:
    for (; i < 2; i++) {
        int res = valkeyGetReply(c, &r);
        if (reply) freeReplyObject(reply);
        reply = res == VALKEY_OK ? ((valkeyReply *)r) : NULL;
        if (res != VALKEY_OK || !r) goto fail;
        if (reply->type == VALKEY_REPLY_ERROR) {
            goto fail;
        }
        if (reply->type != VALKEY_REPLY_ARRAY || reply->elements < 2) goto fail;
        sub_reply = reply->element[1];
        char *value = sub_reply->str;
        if (!value) value = "";
        switch (i) {
        case 0: cfg->save = sdsnew(value); break;
        case 1: cfg->appendonly = sdsnew(value); break;
        }
    }
    freeReplyObject(reply);
    valkeyFree(c);
    return cfg;
fail:
    if (reply && reply->type == VALKEY_REPLY_ERROR && !strncmp(reply->str, "NOAUTH", 6)) {
        if (ct != VALKEY_CONN_UNIX)
            fprintf(stderr, "Node %s:%d replied with error:\n%s\n", ip_or_path, port, reply->str);
        else
            fprintf(stderr, "Node %s replied with error:\n%s\n", ip_or_path, reply->str);
        abort_test = 1;
    }
    freeReplyObject(reply);
    valkeyFree(c);
    freeServerConfig(cfg);
    if (abort_test) exit(1);
    return NULL;
}
static void freeServerConfig(serverConfig *cfg) {
    if (cfg->save) sdsfree(cfg->save);
    if (cfg->appendonly) sdsfree(cfg->appendonly);
    zfree(cfg);
}

void resetPlaceholders(void) {
    if (placeholders.index_data)
        zfree(placeholders.index_data); /* indices are a single contiguous allocation */
    memset(&placeholders, 0, sizeof(placeholders));
}

void initPlaceholders(const char *cmd, size_t cmd_len) {
    resetPlaceholders();
    placeholders.cmd_len = cmd_len;

    /* store placeholder locations in temp arrays */