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

Code before:
        uint8_t h2 = b->hashes[pos];
        /* When shrinking, it's possible to avoid computing the hash. We can
         * just use idx has the hash. */
        uint64_t hash = ht->rehash_idx;
        /* Reinsert the entry into the new table using the derived hash. */
        rehashEntry(ht, entry, hash, h2);
    }
}

/* Processes one bucket chain during incremental table shrinkage. */
static void rehashStepShrink(hashtable *ht) {
    bucket *b;

    /* Find a non-empty bucket, skipping up to 10 empty buckets.
     *
     * In shrinking case, there is a case that the ht0 can be very empty, but the
     * table size is huge, when doing one step rehash, if there are a lot of empty
     * buckets, we can rehash more buckets to make the rehash faster. */
    int empty_visits = 10;
    while (true) {
        size_t idx = ht->rehash_idx;
        b = ht->tables[0] + idx;
        if (b->presence != 0 || b->chained) break; /* non-empty bucket */
        rehashStepFinalize(ht);
        if (!hashtableIsRehashing(ht)) return; /* rehashing completed */
        if (--empty_visits == 0) return; /* too many empty buckets */
    }

    /* Rehash all the entries in this bucket chain from the old to the new hash HT */
    while (b != NULL) {
        bucket *next = getChildBucket(b);
        rehashBucketShrink(ht, b);
        b = next;
    }

    rehashStepFinalize(ht);
}

/* Performs one step of incremental rehashing.
 *
 * Note that a rehashing step consists in moving a bucket and all its child buckets,
 * (that may have more than one key as we use bucket and bucket chaining) from the
 * old to the new hash table. */
static void rehashStep(hashtable *ht) {
    assert(hashtableIsRehashing(ht));
    if (ht->bucket_exp[1] < ht->bucket_exp[0]) {
        rehashStepShrink(ht);
        return;
    }
    rehashStepExpand(ht);
}

Review comment (suggestion):
```suggestion
        if (--empty_visits == 0) return;       /* too many empty buckets */
```

Code after:
        uint8_t h2 = b->hashes[pos];
        /* When shrinking, it's possible to avoid computing the hash. We can
         * just use idx has the hash. */
        uint64_t hash = ht->rehash_idx;
        /* Reinsert the entry into the new table using the derived hash. */
        rehashEntry(ht, entry, hash, h2);
    }
}

/* Processes one bucket chain during incremental table shrinkage. */
static void rehashStepShrink(hashtable *ht) {
    bucket *b;

    /* Find a non-empty bucket, skipping up to 10 empty buckets.
     *
     * In shrinking case, there is a case that the ht0 can be very empty, but the
     * table size is huge, when doing one step rehash, if there are a lot of empty
     * buckets, we can rehash more buckets to make the rehash faster. */
    int empty_visits = 10;
    while (true) {
        size_t idx = ht->rehash_idx;
        b = ht->tables[0] + idx;
        if (b->presence != 0 || b->chained) break; /* non-empty bucket */
        rehashStepFinalize(ht);
        if (!hashtableIsRehashing(ht)) return; /* rehashing completed */
        if (--empty_visits == 0) return;       /* too many empty buckets */
    }

    /* Rehash all the entries in this bucket chain from the old to the new hash HT */
    while (b != NULL) {
        bucket *next = getChildBucket(b);
        rehashBucketShrink(ht, b);
        b = next;
    }

    rehashStepFinalize(ht);
}

/* Performs one step of incremental rehashing.
 *
 * Note that a rehashing step consists in moving a bucket and all its child buckets,
 * (that may have more than one key as we use bucket and bucket chaining) from the
 * old to the new hash table. */
static void rehashStep(hashtable *ht) {
    assert(hashtableIsRehashing(ht));
    if (ht->bucket_exp[1] < ht->bucket_exp[0]) {
        rehashStepShrink(ht);
        return;
    }
    rehashStepExpand(ht);
}