returns 0 if no more work needs to be been done, and 1 if time is up and more work is needed. */
| 997 | |
| 998 | /* returns 0 if no more work needs to be been done, and 1 if time is up and more work is needed. */ |
| 999 | int defragLaterStep(redisDb *db, long long endtime) { |
| 1000 | unsigned int iterations = 0; |
| 1001 | unsigned long long prev_defragged = g_pserver->stat_active_defrag_hits; |
| 1002 | unsigned long long prev_scanned = g_pserver->stat_active_defrag_scanned; |
| 1003 | long long key_defragged; |
| 1004 | |
| 1005 | do { |
| 1006 | /* if we're not continuing a scan from the last call or loop, start a new one */ |
| 1007 | if (!defrag_later_cursor) { |
| 1008 | listNode *head = listFirst(db->defrag_later); |
| 1009 | |
| 1010 | /* Move on to next key */ |
| 1011 | if (defrag_later_current_key) { |
| 1012 | serverAssert(defrag_later_current_key == head->value); |
| 1013 | listDelNode(db->defrag_later, head); |
| 1014 | defrag_later_cursor = 0; |
| 1015 | defrag_later_current_key = NULL; |
| 1016 | } |
| 1017 | |
| 1018 | /* stop if we reached the last one. */ |
| 1019 | head = listFirst(db->defrag_later); |
| 1020 | if (!head) |
| 1021 | return 0; |
| 1022 | |
| 1023 | /* start a new key */ |
| 1024 | defrag_later_current_key = (sds)head->value; |
| 1025 | defrag_later_cursor = 0; |
| 1026 | } |
| 1027 | |
| 1028 | /* each time we enter this function we need to fetch the key from the dict again (if it still exists) */ |
| 1029 | robj *o = db->find(defrag_later_current_key); |
| 1030 | key_defragged = g_pserver->stat_active_defrag_hits; |
| 1031 | do { |
| 1032 | int quit = 0; |
| 1033 | if (defragLaterItem(defrag_later_current_key, o, &defrag_later_cursor, endtime)) |
| 1034 | quit = 1; /* time is up, we didn't finish all the work */ |
| 1035 | |
| 1036 | /* Once in 16 scan iterations, 512 pointer reallocations, or 64 fields |
| 1037 | * (if we have a lot of pointers in one hash bucket, or rehashing), |
| 1038 | * check if we reached the time limit. */ |
| 1039 | if (quit || (++iterations > 16 || |
| 1040 | g_pserver->stat_active_defrag_hits - prev_defragged > 512 || |
| 1041 | g_pserver->stat_active_defrag_scanned - prev_scanned > 64)) { |
| 1042 | if (quit || ustime() > endtime) { |
| 1043 | if(key_defragged != g_pserver->stat_active_defrag_hits) |
| 1044 | g_pserver->stat_active_defrag_key_hits++; |
| 1045 | else |
| 1046 | g_pserver->stat_active_defrag_key_misses++; |
| 1047 | return 1; |
| 1048 | } |
| 1049 | iterations = 0; |
| 1050 | prev_defragged = g_pserver->stat_active_defrag_hits; |
| 1051 | prev_scanned = g_pserver->stat_active_defrag_scanned; |
| 1052 | } |
| 1053 | } while(defrag_later_cursor); |
| 1054 | if(key_defragged != g_pserver->stat_active_defrag_hits) |
| 1055 | g_pserver->stat_active_defrag_key_hits++; |
| 1056 | else |
no test coverage detected