diff options
author | antirez <antirez@gmail.com> | 2015-02-05 11:28:45 +0100 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2015-02-11 10:52:26 +0100 |
commit | 1bcf67a75f775b342653505465b5e8ee03974809 (patch) | |
tree | 4af637de3c6bbc9a4715e07b84df4e63b64ab150 /src/dict.c | |
parent | 88cd9ebc0964c9daf32d97631b5eeba5fd0e8b09 (diff) | |
download | redis-1bcf67a75f775b342653505465b5e8ee03974809.tar.gz |
dict.c: dictGetRandomKeys() optimization for big->small table case.
Related to issue #2306.
Diffstat (limited to 'src/dict.c')
-rw-r--r-- | src/dict.c | 9 |
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) { |