X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/f7f2b2610e8181c13657c35e4f3cd06c94ba3ff9..dfa90b596960b64f9dd615154b084768dd11108a:/src/redis.c diff --git a/src/redis.c b/src/redis.c index 7505de48..e12d27cc 100644 --- a/src/redis.c +++ b/src/redis.c @@ -581,10 +581,16 @@ void incrementallyRehash(void) { int j; for (j = 0; j < server.dbnum; j++) { + /* Keys dictionary */ if (dictIsRehashing(server.db[j].dict)) { dictRehashMilliseconds(server.db[j].dict,1); break; /* already used our millisecond for this loop... */ } + /* Expires */ + if (dictIsRehashing(server.db[j].expires)) { + dictRehashMilliseconds(server.db[j].expires,1); + break; /* already used our millisecond for this loop... */ + } } } @@ -608,26 +614,35 @@ void updateDictResizePolicy(void) { * it will get more aggressive to avoid that too much memory is used by * keys that can be removed from the keyspace. */ void activeExpireCycle(void) { - int j; - long long start = mstime(), timelimit; + int j, iteration = 0; + long long start = ustime(), timelimit; /* We can use at max REDIS_EXPIRELOOKUPS_TIME_PERC percentage of CPU time * per iteration. Since this function gets called with a frequency of * REDIS_HZ times per second, the following is the max amount of - * milliseconds we can spend here: */ - timelimit = (1000/REDIS_HZ/100)*REDIS_EXPIRELOOKUPS_TIME_PERC; + * microseconds we can spend in this function. */ + timelimit = 1000000*REDIS_EXPIRELOOKUPS_TIME_PERC/REDIS_HZ/100; if (timelimit <= 0) timelimit = 1; for (j = 0; j < server.dbnum; j++) { - int expired, iteration = 0; + int expired; redisDb *db = server.db+j; /* Continue to expire if at the end of the cycle more than 25% * of the keys were expired. */ do { - long num = dictSize(db->expires); + unsigned long num = dictSize(db->expires); + unsigned long slots = dictSlots(db->expires); long long now = mstime(); + /* When there are less than 1% filled slots getting random + * keys is expensive, so stop here waiting for better times... + * The dictionary will be resized asap. */ + if (num && slots > DICT_HT_INITIAL_SIZE && + (num*100/slots < 1)) break; + + /* The main collection cycle. Sample random keys among keys + * with an expire set, checking for expired ones. */ expired = 0; if (num > REDIS_EXPIRELOOKUPS_PER_CRON) num = REDIS_EXPIRELOOKUPS_PER_CRON; @@ -652,8 +667,8 @@ void activeExpireCycle(void) { * expire. So after a given amount of milliseconds return to the * caller waiting for the other active expire cycle. */ iteration++; - if ((iteration & 0xff) == 0 && /* Check once every 255 iterations */ - (mstime()-start) > timelimit) return; + if ((iteration & 0xf) == 0 && /* check once every 16 cycles. */ + (ustime()-start) > timelimit) return; } while (expired > REDIS_EXPIRELOOKUPS_PER_CRON/4); } } @@ -856,7 +871,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { * a lot of memory movements in the parent will cause a lot of pages * copied. */ if (server.rdb_child_pid == -1 && server.aof_child_pid == -1) { - run_with_period(1000) tryResizeHashTables(); + tryResizeHashTables(); if (server.activerehashing) incrementallyRehash(); }