This function handles 'background' operations we are required to do * incrementally in Redis databases, such as active key expiring, resizing, * rehashing. */
| 2072 | * incrementally in Redis databases, such as active key expiring, resizing, |
| 2073 | * rehashing. */ |
| 2074 | void databasesCron(bool fMainThread) { |
| 2075 | serverAssert(GlobalLocksAcquired()); |
| 2076 | |
| 2077 | if (fMainThread) { |
| 2078 | /* Expire keys by random sampling. Not required for slaves |
| 2079 | * as master will synthesize DELs for us. */ |
| 2080 | if (g_pserver->active_expire_enabled) { |
| 2081 | if (expireOwnKeys()) { |
| 2082 | activeExpireCycle(ACTIVE_EXPIRE_CYCLE_SLOW); |
| 2083 | } else { |
| 2084 | expireSlaveKeys(); |
| 2085 | } |
| 2086 | } |
| 2087 | |
| 2088 | /* Defrag keys gradually. */ |
| 2089 | activeDefragCycle(); |
| 2090 | } |
| 2091 | |
| 2092 | /* Perform hash tables rehashing if needed, but only if there are no |
| 2093 | * other processes saving the DB on disk. Otherwise rehashing is bad |
| 2094 | * as will cause a lot of copy-on-write of memory pages. */ |
| 2095 | if (!hasActiveChildProcess()) { |
| 2096 | /* We use global counters so if we stop the computation at a given |
| 2097 | * DB we'll be able to start from the successive in the next |
| 2098 | * cron loop iteration. */ |
| 2099 | static unsigned int resize_db = 0; |
| 2100 | static unsigned int rehash_db = 0; |
| 2101 | static int rehashes_per_ms; |
| 2102 | static int async_rehashes; |
| 2103 | int dbs_per_call = CRON_DBS_PER_CALL; |
| 2104 | int j; |
| 2105 | |
| 2106 | /* Don't test more DBs than we have. */ |
| 2107 | if (dbs_per_call > cserver.dbnum) dbs_per_call = cserver.dbnum; |
| 2108 | |
| 2109 | if (fMainThread) { |
| 2110 | /* Resize */ |
| 2111 | for (j = 0; j < dbs_per_call; j++) { |
| 2112 | tryResizeHashTables(resize_db % cserver.dbnum); |
| 2113 | resize_db++; |
| 2114 | } |
| 2115 | } |
| 2116 | |
| 2117 | /* Rehash */ |
| 2118 | if (g_pserver->activerehashing) { |
| 2119 | for (j = 0; j < dbs_per_call; j++) { |
| 2120 | if (serverTL->rehashCtl != nullptr) { |
| 2121 | if (!serverTL->rehashCtl->done.load(std::memory_order_relaxed)) { |
| 2122 | aeReleaseLock(); |
| 2123 | if (dictRehashSomeAsync(serverTL->rehashCtl, rehashes_per_ms)) { |
| 2124 | aeAcquireLock(); |
| 2125 | break; |
| 2126 | } |
| 2127 | aeAcquireLock(); |
| 2128 | } |
| 2129 | |
| 2130 | if (serverTL->rehashCtl->done.load(std::memory_order_relaxed)) { |
| 2131 | dictCompleteRehashAsync(serverTL->rehashCtl, true /*fFree*/); |
no test coverage detected