summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2015-02-05 11:28:45 +0100
committerantirez <antirez@gmail.com>2015-02-08 23:08:21 +0100
commitb98c33db80662ee198e699bf080c983b581f96c1 (patch)
tree1c58b3b102ad50944cfd498f814409e809d0a64a
parente004ac8fe857c92af54d1859265fe9cbbe799ea8 (diff)
downloadredis-b98c33db80662ee198e699bf080c983b581f96c1.tar.gz
dict.c: dictGetRandomKeys() optimization for big->small table case.
Related to issue #2306.
-rw-r--r--src/dict.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/dict.c b/src/dict.c
index fbcdd35f8..e197266e8 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -704,7 +704,14 @@ unsigned int dictGetRandomKeys(dict *d, dictEntry **des, unsigned int count) {
/* Invariant of the dict.c rehashing: up to the indexes already
* visited in ht[0] during the rehashing, there are no populated
* buckets, so we can skip ht[0] for indexes between 0 and idx-1. */
- if (j == 0 && i < d->rehashidx) continue;
+ if (tables == 2 && j == 0 && i < d->rehashidx) {
+ /* Moreover, if we are currently out of range in the second
+ * table, there will be no elements in both tables up to
+ * the current rehashing index, so we jump if possible.
+ * (this happens when going from big to small table). */
+ if (i >= d->ht[1].size) i = d->rehashidx;
+ continue;
+ }
if (i >= d->ht[j].size) continue; /* Out of range for this table. */
dictEntry *he = d->ht[j].table[i];
while (he) {