From e8ceba4e64d6ae7ce8baef90785b4f758e84f5e7 Mon Sep 17 00:00:00 2001 From: antirez Date: Mon, 18 Nov 2019 17:47:19 +0100 Subject: [PATCH] Expire cycle: set a buckets limit as well. --- src/expire.c | 15 +++++++++++++-- 1 file 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. */