MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / activeDefragCycle

Function activeDefragCycle

src/defrag.cpp:1098–1216  ·  view source on GitHub ↗

Perform incremental defragmentation work from the serverCron. * This works in a similar way to activeExpireCycle, in the sense that * we do incremental work across calls. */

Source from the content-addressed store, hash-verified

1096 * This works in a similar way to activeExpireCycle, in the sense that
1097 * we do incremental work across calls. */
1098void activeDefragCycle(void) {
1099 static int current_db = -1;
1100 static unsigned long cursor = 0;
1101 static redisDb *db = NULL;
1102 static long long start_scan, start_stat;
1103 unsigned int iterations = 0;
1104 unsigned long long prev_defragged = g_pserver->stat_active_defrag_hits;
1105 unsigned long long prev_scanned = g_pserver->stat_active_defrag_scanned;
1106 long long start, timelimit, endtime;
1107 mstime_t latency;
1108 int quit = 0;
1109
1110 if (!cserver.active_defrag_enabled) {
1111 if (g_pserver->active_defrag_running) {
1112 /* if active defrag was disabled mid-run, start from fresh next time. */
1113 g_pserver->active_defrag_running = 0;
1114 if (db)
1115 listEmpty(db->defrag_later);
1116 defrag_later_current_key = NULL;
1117 defrag_later_cursor = 0;
1118 current_db = -1;
1119 cursor = 0;
1120 db = NULL;
1121 }
1122 return;
1123 }
1124
1125 if (hasActiveChildProcess())
1126 return; /* Defragging memory while there's a fork will just do damage. */
1127
1128 /* Once a second, check if the fragmentation justfies starting a scan
1129 * or making it more aggressive. */
1130 run_with_period(1000) {
1131 computeDefragCycles();
1132 }
1133 if (!g_pserver->active_defrag_running)
1134 return;
1135
1136 /* See activeExpireCycle for how timelimit is handled. */
1137 start = ustime();
1138 timelimit = 1000000*g_pserver->active_defrag_running/g_pserver->hz/100;
1139 if (timelimit <= 0) timelimit = 1;
1140 endtime = start + timelimit;
1141 latencyStartMonitor(latency);
1142
1143 do {
1144 /* if we're not continuing a scan from the last call or loop, start a new one */
1145 if (!cursor) {
1146 /* finish any leftovers from previous db before moving to the next one */
1147 if (db && defragLaterStep(db, endtime)) {
1148 quit = 1; /* time is up, we didn't finish all the work */
1149 break; /* this will exit the function and we'll continue on the next cycle */
1150 }
1151
1152 /* Move on to next database, and stop if we reached the last one. */
1153 if (++current_db >= cserver.dbnum) {
1154 /* defrag other items not part of the db / keys */
1155 defragOtherGlobals();

Callers 2

databasesCronFunction · 0.85
whileBlockedCronFunction · 0.85

Calls 10

listEmptyFunction · 0.85
hasActiveChildProcessFunction · 0.85
computeDefragCyclesFunction · 0.85
defragLaterStepFunction · 0.85
defragOtherGlobalsFunction · 0.85
serverLogFunction · 0.85
dictScanFunction · 0.85
dictUnsafeKeyOnlyMethod · 0.80
ustimeFunction · 0.70

Tested by

no test coverage detected