summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2019-11-18 17:47:19 +0100
committerantirez <antirez@gmail.com>2019-11-18 17:47:19 +0100
commite8ceba4e64d6ae7ce8baef90785b4f758e84f5e7 (patch)
tree518cf5b47701c15df33bcb5343ce1f1e6f8c5aac /src
parent2ab51a644d3d390df50dc1bc59958a15affeb341 (diff)
downloadredis-e8ceba4e64d6ae7ce8baef90785b4f758e84f5e7.tar.gz
Expire cycle: set a buckets limit as well.
Diffstat (limited to 'src')
-rw-r--r--src/expire.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/expire.c b/src/expire.c
index ea7e2b456..b4ab9ab18 100644
--- a/src/expire.c
+++ b/src/expire.c
@@ -237,8 +237,18 @@ void activeExpireCycle(int type) {
/* Here we access the low level representation of the hash table
* for speed concerns: this makes this code coupled with dict.c,
- * but it hardly changed in ten years. */
- while (sampled < num) {
+ * but it hardly changed in ten years.
+ *
+ * Note that certain places of the hash table may be empty,
+ * so we want also a stop condition about the number of
+ * buckets that we scanned. However scanning for free buckets
+ * is very fast: we are in the cache line scanning a sequential
+ * array of NULL pointers, so we can scan a lot more buckets
+ * than keys in the same time. */
+ long max_buckets = num*20;
+ long checked_buckets = 0;
+
+ while (sampled < num && checked_buckets < max_buckets) {
for (int table = 0; table < 2; table++) {
if (table == 1 && !dictIsRehashing(db->expires)) break;
@@ -248,6 +258,7 @@ void activeExpireCycle(int type) {
long long ttl;
/* Scan the current bucket of the current table. */
+ checked_buckets++;
while(de) {
/* Get the next entry now since this entry may get
* deleted. */