summaryrefslogtreecommitdiff
path: root/src/dict.c
diff options
context:
space:
mode:
authorViktor Söderqvist <viktor.soderqvist@est.tech>2022-11-26 02:35:18 +0100
committerGitHub <noreply@github.com>2022-11-25 17:35:18 -0800
commitabf70309eb42674982ea51ed41ff5b39b04fe701 (patch)
tree87cce2c658cf1c3f6cbf3fb67f97b19c7c3ad52a /src/dict.c
parentce4ebe6ba858bd6be7cabdc830f5ef30d6fcd37a (diff)
downloadredis-abf70309eb42674982ea51ed41ff5b39b04fe701.tar.gz
Shrink dict without rehashing (#11540)
When we're shrinking the hash table, we don't need to hash the keys. Since the table sizes are powers of two, we can simply mask the bucket index in the larger table to get the bucket index in the smaller table. We avoid loading the keys into memory and save CPU time.
Diffstat (limited to 'src/dict.c')
-rw-r--r--src/dict.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/dict.c b/src/dict.c
index 9975e7872..9ed461d62 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -229,7 +229,14 @@ int dictRehash(dict *d, int n) {
nextde = de->next;
/* Get the index in the new hash table */
- h = dictHashKey(d, de->key) & DICTHT_SIZE_MASK(d->ht_size_exp[1]);
+ if (d->ht_size_exp[1] > d->ht_size_exp[0]) {
+ h = dictHashKey(d, de->key) & DICTHT_SIZE_MASK(d->ht_size_exp[1]);
+ } else {
+ /* We're shrinking the table. The tables sizes are powers of
+ * two, so we simply mask the bucket index in the larger table
+ * to get the bucket index in the smaller table. */
+ h = d->rehashidx & DICTHT_SIZE_MASK(d->ht_size_exp[1]);
+ }
de->next = d->ht_table[1][h];
d->ht_table[1][h] = de;
d->ht_used[0]--;