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

Code before:
    int is_updating_slots = atomic_load_explicit(&config.is_updating_slots, memory_order_relaxed);
    /* If updateClusterSlotsConfiguration is updating the slots array,
     * call updateClusterSlotsConfiguration is order to block the thread
     * since the mutex is locked. When the slots will be updated by the
     * thread that's actually performing the update, the execution of
     * updateClusterSlotsConfiguration won't actually do anything, since
     * the updated_slots_count array will be already NULL. */
    if (is_updating_slots) updateClusterSlotsConfiguration();
    int slot = node->slots[rand() % node->slots_count];
    const char *tag = crc16_slot_table[slot];
    int taglen = strlen(tag);
    size_t i;
    for (i = 0; i < c->staglen; i++) {
        char *p = c->stagptr[i] + 1;
        p[0] = tag[0];
        p[1] = (taglen >= 2 ? tag[1] : '}');
        p[2] = (taglen == 3 ? tag[2] : '}');
    }
}

static long long acquireTokenOrWait(int tokens) {
    if (config.num_threads) pthread_mutex_lock(&(config.token_bucket_mutex));

    long long last_time_ = config.last_time;
    long long time_per_token_ = config.time_per_token;
    long long time_per_burst_ = config.time_per_burst;
    long long new_time = 0;

    long long now_since_epoch = nstime();
    long long min_time = now_since_epoch - time_per_burst_;
    if (min_time > last_time_) {
        new_time = min_time + (time_per_token_ * tokens);
    } else {
        new_time = last_time_ + (time_per_token_ * tokens);
    }

    long long delay_time = 0;
    if (new_time > now_since_epoch) {
        delay_time = new_time - now_since_epoch;
    } else {
        config.last_time = new_time;
    }
    if (config.num_threads) pthread_mutex_unlock(&(config.token_bucket_mutex));
    return delay_time;
}

static void clientDone(client c) {
    int requests_finished = atomic_load_explicit(&config.requests_finished, memory_order_relaxed);
    if (requests_finished >= config.requests) {
        freeClient(c);
        if (!config.num_threads && config.el) aeStop(config.el);

Review comment (suggestion):
Trailing underscore in variable names is a funny style. We don't have this style in this project so far. I prefer that we don't start using it.

```suggestion
    long long last_time = config.last_time;
    long long time_per_token = config.time_per_token;
    long long time_per_burst = config.time_per_burst;
```

Code after:
            *p = '0' + key % 10;
            key /= 10;
            p--;
        }
    }
}

static void setClusterKeyHashTag(client c) {
    assert(c->thread_id >= 0);
    clusterNode *node = c->cluster_node;
    assert(node);
    int is_updating_slots = atomic_load_explicit(&config.is_updating_slots, memory_order_relaxed);
    /* If updateClusterSlotsConfiguration is updating the slots array,
     * call updateClusterSlotsConfiguration is order to block the thread
     * since the mutex is locked. When the slots will be updated by the
     * thread that's actually performing the update, the execution of
     * updateClusterSlotsConfiguration won't actually do anything, since
     * the updated_slots_count array will be already NULL. */
    if (is_updating_slots) updateClusterSlotsConfiguration();
    int slot = node->slots[rand() % node->slots_count];
    const char *tag = crc16_slot_table[slot];
    int taglen = strlen(tag);
    size_t i;
    for (i = 0; i < c->staglen; i++) {
        char *p = c->stagptr[i] + 1;
        p[0] = tag[0];
        p[1] = (taglen >= 2 ? tag[1] : '}');
        p[2] = (taglen == 3 ? tag[2] : '}');
    }
}

/* Acquires the specified number of tokens from the token bucket or calculates the wait time if tokens are not available.
 * This function implements a token bucket rate limiting algorithm to control access to a resource.
 *
 * The tokens parameter is the number of tokens to acquire.
 *
 * Returns the delay time in milliseconds that the caller should wait before proceeding, or 0 if tokens are immediately available.
 *
 * Token Bucket Algorithm Explanation:
 * - The token bucket algorithm allows a certain number of tokens to be accumulated over time, which can then be used to control the rate of requests.
 * - Due to the time event only allowing a delay of 1ms, a request for the next 1ms is issued.
 *
 * The function is thread-safe. */
static long long acquireTokenOrWait(int tokens) {
    uint64_t time_per_token = config.time_per_token;
    uint64_t time_per_burst = config.time_per_burst;
    uint64_t new_time = 0;
    uint64_t now_epoch, next_epoch, min_time, delay_time;
    uint64_t last_time_ns, old_last_time_ns;

    while (1) {