| 111 | we do extra efforts. */ |
| 112 | |
| 113 | void activeExpireCycle(int type) { |
| 114 | /* Adjust the running parameters according to the configured expire |
| 115 | * effort. The default effort is 1, and the maximum configurable effort |
| 116 | * is 10. */ |
| 117 | unsigned long |
| 118 | effort = server.active_expire_effort-1, /* Rescale from 0 to 9. */ |
| 119 | config_keys_per_loop = ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP + |
| 120 | ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP/4*effort, |
| 121 | config_cycle_fast_duration = ACTIVE_EXPIRE_CYCLE_FAST_DURATION + |
| 122 | ACTIVE_EXPIRE_CYCLE_FAST_DURATION/4*effort, |
| 123 | config_cycle_slow_time_perc = ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC + |
| 124 | 2*effort, |
| 125 | config_cycle_acceptable_stale = ACTIVE_EXPIRE_CYCLE_ACCEPTABLE_STALE- |
| 126 | effort; |
| 127 | |
| 128 | /* This function has some global state in order to continue the work |
| 129 | * incrementally across calls. */ |
| 130 | static unsigned int current_db = 0; /* Next DB to test. */ |
| 131 | static int timelimit_exit = 0; /* Time limit hit in previous call? */ |
| 132 | static long long last_fast_cycle = 0; /* When last fast cycle ran. */ |
| 133 | |
| 134 | int j, iteration = 0; |
| 135 | int dbs_per_call = CRON_DBS_PER_CALL; |
| 136 | long long start = ustime(), timelimit, elapsed; |
| 137 | |
| 138 | /* When clients are paused the dataset should be static not just from the |
| 139 | * POV of clients not being able to write, but also from the POV of |
| 140 | * expires and evictions of keys not being performed. */ |
| 141 | if (checkClientPauseTimeoutAndReturnIfPaused()) return; |
| 142 | |
| 143 | if (type == ACTIVE_EXPIRE_CYCLE_FAST) { |
| 144 | /* Don't start a fast cycle if the previous cycle did not exit |
| 145 | * for time limit, unless the percentage of estimated stale keys is |
| 146 | * too high. Also never repeat a fast cycle for the same period |
| 147 | * as the fast cycle total duration itself. */ |
| 148 | if (!timelimit_exit && |
| 149 | server.stat_expired_stale_perc < config_cycle_acceptable_stale) |
| 150 | return; |
| 151 | |
| 152 | if (start < last_fast_cycle + (long long)config_cycle_fast_duration*2) |
| 153 | return; |
| 154 | |
| 155 | last_fast_cycle = start; |
| 156 | } |
| 157 | |
| 158 | /* We usually should test CRON_DBS_PER_CALL per iteration, with |
| 159 | * two exceptions: |
| 160 | * |
| 161 | * 1) Don't test more DBs than we have. |
| 162 | * 2) If last time we hit the time limit, we want to scan all DBs |
| 163 | * in this iteration, as there is work to do in some DB and we don't want |
| 164 | * expired keys to use memory for too much time. */ |
| 165 | if (dbs_per_call > server.dbnum || timelimit_exit) |
| 166 | dbs_per_call = server.dbnum; |
| 167 | |
| 168 | /* We can use at max 'config_cycle_slow_time_perc' percentage of CPU |
| 169 | * time per iteration. Since this function gets called with a frequency of |
| 170 | * server.hz times per second, the following is the max amount of |
no test coverage detected