12
struct rrdengine_datafile *datafile;
13
14
struct rrdeng_cmd *cmd;
15
+ bool head_to_datafile_extent_queries_pending_for_extent;
16
17
struct {
18
struct extent_page_details_list *prev;
60
},
61
};
62
62
-void pdc_cleanup(void) {
63
- netdata_spinlock_lock(&pdc_globals.protected.spinlock);
63
+void pdc_cleanup1(void) {
64
+ PDC *item = NULL;
65
+
66
+ if(!netdata_spinlock_trylock(&pdc_globals.protected.spinlock))
67
+ return;
68
65
- while(pdc_globals.protected.available_items && pdc_globals.protected.available > (size_t)libuv_worker_threads) {
66
- PDC *item = pdc_globals.protected.available_items;
69
+ if(pdc_globals.protected.available_items && pdc_globals.protected.available > (size_t)libuv_worker_threads) {
70
+ item = pdc_globals.protected.available_items;
71
DOUBLE_LINKED_LIST_REMOVE_UNSAFE(pdc_globals.protected.available_items, item, cache.prev, cache.next);
68
- freez(item);
72
pdc_globals.protected.available--;
70
- __atomic_sub_fetch(&pdc_globals.atomics.allocated, 1, __ATOMIC_RELAXED);
73
}
74
75
netdata_spinlock_unlock(&pdc_globals.protected.spinlock);
76
+
77
+ if(item) {
78
+ freez(item);
79
+ __atomic_sub_fetch(&pdc_globals.atomics.allocated, 1, __ATOMIC_RELAXED);
80
+ }
81
}
82
83
PDC *pdc_get(void) {
139
},
140
};
141
135
-void page_details_cleanup(void) {
136
- netdata_spinlock_lock(&page_details_globals.protected.spinlock);
142
+void page_details_cleanup1(void) {
143
+ struct page_details *item = NULL;
144
138
- while(page_details_globals.protected.available_items && page_details_globals.protected.available > (size_t)libuv_worker_threads * 2) {
139
- struct page_details *item = page_details_globals.protected.available_items;
145
+ if(!netdata_spinlock_trylock(&page_details_globals.protected.spinlock))
146
+ return;
147
+
148
+ if(page_details_globals.protected.available_items && page_details_globals.protected.available > (size_t)libuv_worker_threads * 2) {
149
+ item = page_details_globals.protected.available_items;
150
DOUBLE_LINKED_LIST_REMOVE_UNSAFE(page_details_globals.protected.available_items, item, cache.prev, cache.next);
141
- freez(item);
151
page_details_globals.protected.available--;
143
- __atomic_sub_fetch(&page_details_globals.atomics.allocated, 1, __ATOMIC_RELAXED);
152
}
153
154
netdata_spinlock_unlock(&page_details_globals.protected.spinlock);
155
+
156
+ if(item) {
157
+ freez(item);
158
+ __atomic_sub_fetch(&page_details_globals.atomics.allocated, 1, __ATOMIC_RELAXED);
159
+ }
160
}
161
162
struct page_details *page_details_get(void) {
218
},
219
};
220
208
-void epdl_cleanup(void) {
209
- netdata_spinlock_lock(&epdl_globals.protected.spinlock);
221
+void epdl_cleanup1(void) {
222
+ EPDL *item = NULL;
223
211
- while(epdl_globals.protected.available_items && epdl_globals.protected.available > 100) {
212
- EPDL *item = epdl_globals.protected.available_items;
224
+ if(!netdata_spinlock_trylock(&epdl_globals.protected.spinlock))
225
+ return;
226
+
227
+ if(epdl_globals.protected.available_items && epdl_globals.protected.available > 100) {
228
+ item = epdl_globals.protected.available_items;
229
DOUBLE_LINKED_LIST_REMOVE_UNSAFE(epdl_globals.protected.available_items, item, cache.prev, cache.next);
214
- freez(item);
230
epdl_globals.protected.available--;
216
- __atomic_sub_fetch(&epdl_globals.atomics.allocated, 1, __ATOMIC_RELAXED);
231
}
232
233
netdata_spinlock_unlock(&epdl_globals.protected.spinlock);
234
+
235
+ if(item) {
236
+ freez(item);
237
+ __atomic_sub_fetch(&epdl_globals.atomics.allocated, 1, __ATOMIC_RELAXED);
238
+ }
239
}
240
241
static EPDL *epdl_get(void) {
297
},
298
};
299
281
-void deol_cleanup(void) {
282
- netdata_spinlock_lock(&deol_globals.protected.spinlock);
300
+void deol_cleanup1(void) {
301
+ DEOL *item = NULL;
302
284
- while(deol_globals.protected.available_items && deol_globals.protected.available > 100) {
285
- DEOL *item = deol_globals.protected.available_items;
303
+ if(!netdata_spinlock_trylock(&deol_globals.protected.spinlock))
304
+ return;
305
+
306
+ if(deol_globals.protected.available_items && deol_globals.protected.available > 100) {
307
+ item = deol_globals.protected.available_items;
308
DOUBLE_LINKED_LIST_REMOVE_UNSAFE(deol_globals.protected.available_items, item, cache.prev, cache.next);
287
- freez(item);
309
deol_globals.protected.available--;
289
- __atomic_sub_fetch(&deol_globals.atomics.allocated, 1, __ATOMIC_RELAXED);
310
}
311
312
netdata_spinlock_unlock(&deol_globals.protected.spinlock);
313
+
314
+ if(item) {
315
+ freez(item);
316
+ __atomic_sub_fetch(&deol_globals.atomics.allocated, 1, __ATOMIC_RELAXED);
317
+ }
318
}
319
320
static DEOL *deol_get(void) {
391
extent_buffer_globals.max_size = max_size;
392
}
393
369
-void extent_buffer_cleanup(void) {
370
- netdata_spinlock_lock(&extent_buffer_globals.protected.spinlock);
394
+void extent_buffer_cleanup1(void) {
395
+ struct extent_buffer *item = NULL;
396
372
- while(extent_buffer_globals.protected.available_items && extent_buffer_globals.protected.available > 1) {
373
- struct extent_buffer *item = extent_buffer_globals.protected.available_items;
374
- size_t bytes = sizeof(struct extent_buffer) + item->bytes;
397
+ if(!netdata_spinlock_trylock(&extent_buffer_globals.protected.spinlock))
398
+ return;
399
+
400
+ if(extent_buffer_globals.protected.available_items && extent_buffer_globals.protected.available > 1) {
401
+ item = extent_buffer_globals.protected.available_items;
402
DOUBLE_LINKED_LIST_REMOVE_UNSAFE(extent_buffer_globals.protected.available_items, item, cache.prev, cache.next);
376
- freez(item);
403
extent_buffer_globals.protected.available--;
378
- __atomic_sub_fetch(&extent_buffer_globals.atomics.allocated, 1, __ATOMIC_RELAXED);
379
- __atomic_sub_fetch(&extent_buffer_globals.atomics.allocated_bytes, bytes, __ATOMIC_RELAXED);
404
}
405
406
netdata_spinlock_unlock(&extent_buffer_globals.protected.spinlock);
407
+
408
+ if(item) {
409
+ size_t bytes = sizeof(struct extent_buffer) + item->bytes;
410
+ freez(item);
411
+ __atomic_sub_fetch(&extent_buffer_globals.atomics.allocated, 1, __ATOMIC_RELAXED);
412
+ __atomic_sub_fetch(&extent_buffer_globals.atomics.allocated_bytes, bytes, __ATOMIC_RELAXED);
413
+ }
414
}
415
416
struct extent_buffer *extent_buffer_get(size_t size) {
493
while ((PValue = PDCJudyLFirstThenNext(*pd_by_start_time_s_JudyL, &start_time_index, &start_time_first))) {
494
struct page_details *pd = *PValue;
495
465
- if(!pd->page) {
496
+ if(!pd->page && !pdc_page_status_check(pd, PDC_PAGE_FAILED|PDC_PAGE_READY)) {
497
pdc_page_status_set(pd, PDC_PAGE_FAILED | tags);
498
pages_matched++;
499
}
553
struct page_details *pd;
554
Word_t time_index = 0;
555
bool first_then_next = true;
525
- size_t unroutable = 0;
556
+ size_t unroutable = 0, cancelled = 0;
557
while((PValue = PDCJudyLFirstThenNext(pdc->page_list_JudyL, &time_index, &first_then_next))) {
558
pd = *PValue;
559
567
568
internal_fatal(pd->datafile.ptr, "DBENGINE: page details has a datafile.ptr that is not released.");
569
539
- if(!pd->page && !(status & (PDC_PAGE_READY | PDC_PAGE_FAILED | PDC_PAGE_RELEASED | PDC_PAGE_SKIP | PDC_PAGE_INVALID))) {
570
+ if(!pd->page && !(status & (PDC_PAGE_READY | PDC_PAGE_FAILED | PDC_PAGE_RELEASED | PDC_PAGE_SKIP | PDC_PAGE_INVALID | PDC_PAGE_CANCELLED))) {
571
// pdc_page_status_set(pd, PDC_PAGE_FAILED);
572
unroutable++;
573
}
574
+ else if(!pd->page && (status & PDC_PAGE_CANCELLED))
575
+ cancelled++;
576
577
if(pd->page && !(status & PDC_PAGE_RELEASED)) {
578
pgc_page_release(main_cache, pd->page);
590
591
if(unroutable)
592
__atomic_add_fetch(&rrdeng_cache_efficiency_stats.pages_load_fail_unroutable, unroutable, __ATOMIC_RELAXED);
593
+
594
+ if(cancelled)
595
+ __atomic_add_fetch(&rrdeng_cache_efficiency_stats.pages_load_fail_cancelled, cancelled, __ATOMIC_RELAXED);
596
}
597
598
void pdc_acquire(PDC *pdc) {
655
656
EPDL *base = *PValue;
657
622
- if(!base)
658
+ if(!base) {
659
added_new = true;
660
+ epdl->head_to_datafile_extent_queries_pending_for_extent = true;
661
+ }
662
else {
663
added_new = false;
664
+ epdl->head_to_datafile_extent_queries_pending_for_extent = false;
665
__atomic_add_fetch(&rrdeng_cache_efficiency_stats.pages_load_extent_merged, 1, __ATOMIC_RELAXED);
666
667
if(base->pdc->priority > epdl->pdc->priority)
678
679
static void epdl_pending_del(EPDL *epdl) {
680
netdata_spinlock_lock(&epdl->datafile->extent_queries.spinlock);
642
- int rc = JudyLDel(&epdl->datafile->extent_queries.pending_epdl_by_extent_offset_judyL, epdl->extent_offset, PJE0);
643
- (void)rc;
644
- internal_fatal(!rc, "DBENGINE: epdl not found in pending list");
681
+ if(epdl->head_to_datafile_extent_queries_pending_for_extent) {
682
+ epdl->head_to_datafile_extent_queries_pending_for_extent = false;
683
+ int rc = JudyLDel(&epdl->datafile->extent_queries.pending_epdl_by_extent_offset_judyL, epdl->extent_offset, PJE0);
684
+ (void) rc;
685
+ internal_fatal(!rc, "DBENGINE: epdl not found in pending list");
686
+ }
687
netdata_spinlock_unlock(&epdl->datafile->extent_queries.spinlock);
688
}
689
900
return vd;
901
}
902
861
-static struct page_details *epdl_to_pd_load_list(EPDL *epdl, Word_t metric_id, time_t start_time_s) {
903
+static inline struct page_details *epdl_get_pd_load_link_list_from_metric_start_time(EPDL *epdl, Word_t metric_id, time_t start_time_s) {
904
+
905
+ if(unlikely(epdl->head_to_datafile_extent_queries_pending_for_extent))
906
+ // stop appending more pages to this epdl
907
+ epdl_pending_del(epdl);
908
+
909
struct page_details *pd_list = NULL;
910
911
for(EPDL *ep = epdl; ep ;ep = ep->query.next) {
912
Pvoid_t *pd_by_start_time_s_judyL = PDCJudyLGet(ep->page_details_by_metric_id_JudyL, metric_id, PJE0);
913
internal_fatal(pd_by_start_time_s_judyL == PJERR, "DBENGINE: corrupted extent metrics JudyL");
914
868
- if (pd_by_start_time_s_judyL && *pd_by_start_time_s_judyL) {
915
+ if (unlikely(pd_by_start_time_s_judyL && *pd_by_start_time_s_judyL)) {
916
Pvoid_t *pd_pptr = PDCJudyLGet(*pd_by_start_time_s_judyL, start_time_s, PJE0);
917
internal_fatal(pd_pptr == PJERR, "DBENGINE: corrupted metric page details JudyHS");
918
872
- if (pd_pptr && *pd_pptr) {
919
+ if(likely(pd_pptr && *pd_pptr)) {
920
struct page_details *pd = *pd_pptr;
921
internal_fatal(metric_id != pd->metric_id, "DBENGINE: metric ids do not match");
922
876
- DOUBLE_LINKED_LIST_APPEND_UNSAFE(pd_list, pd, load.prev, load.next);
923
+ if(likely(!pd->page)) {
924
+ if (unlikely(__atomic_load_n(&ep->pdc->workers_should_stop, __ATOMIC_RELAXED)))
925
+ pdc_page_status_set(pd, PDC_PAGE_FAILED | PDC_PAGE_CANCELLED);
926
+ else
927
+ DOUBLE_LINKED_LIST_APPEND_UNSAFE(pd_list, pd, load.prev, load.next);
928
+ }
929
}
930
}
931
}
956
bool can_use_data = true;
957
if(data_length < sizeof(*header) + sizeof(header->descr[0]) + sizeof(*trailer)) {
958
can_use_data = false;
959
+
960
+ // added to satisfy the requirements of older compilers (prevent warnings)
961
+ payload_length = 0;
962
+ payload_offset = 0;
963
+ trailer_offset = 0;
964
+ count = 0;
965
+ header = NULL;
966
+ trailer = NULL;
967
}
968
else {
969
header = data;
1066
}
1067
mrg_metric_release(main_mrg, metric);
1068
1009
- struct page_details *pd_list = epdl_to_pd_load_list(epdl, metric_id, start_time_s);
1069
+ struct page_details *pd_list = epdl_get_pd_load_link_list_from_metric_start_time(epdl, metric_id, start_time_s);
1070
if(likely(!pd_list))
1071
continue;
1072
1174
}
1175
1176
void epdl_find_extent_and_populate_pages(struct rrdengine_instance *ctx, EPDL *epdl, bool worker) {
1117
- epdl_pending_del(epdl);
1177
+ size_t *statistics_counter = NULL;
1178
+ PDC_PAGE_STATUS not_loaded_pages_tag = 0, loaded_pages_tag = 0;
1179
1180
bool should_stop = __atomic_load_n(&epdl->pdc->workers_should_stop, __ATOMIC_RELAXED);
1181
for(EPDL *ep = epdl->query.next; ep ;ep = ep->query.next) {
1184
internal_fatal(ep->extent_size != epdl->extent_size, "DBENGINE: extent sizes do not match");
1185
internal_fatal(ep->file != epdl->file, "DBENGINE: files do not match");
1186
1126
- PDC *pdc = ep->pdc;
1127
- if(!__atomic_load_n(&pdc->workers_should_stop, __ATOMIC_RELAXED)) {
1187
+ if(!__atomic_load_n(&ep->pdc->workers_should_stop, __ATOMIC_RELAXED)) {
1188
should_stop = false;
1189
break;
1190
}
1191
}
1192
1133
- if(should_stop)
1193
+ if(unlikely(should_stop)) {
1194
+ statistics_counter = &rrdeng_cache_efficiency_stats.pages_load_fail_cancelled;
1195
+ not_loaded_pages_tag = PDC_PAGE_CANCELLED;
1196
goto cleanup;
1197
+ }
1198
1199
if(worker)
1200
worker_is_busy(UV_EVENT_EXTENT_CACHE);
1201
1139
- PDC_PAGE_STATUS not_loaded_pages_tag = 0, loaded_pages_tag = 0;
1202
bool extent_found_in_cache = false;
1203
1204
void *extent_compressed_data = NULL;
1212
internal_fatal(epdl->extent_size != pgc_page_data_size(extent_cache, extent_cache_page),
1213
"DBENGINE: cache size does not match the expected size");
1214
1153
- loaded_pages_tag |= PDC_PAGE_LOADED_FROM_EXTENT_CACHE;
1154
- not_loaded_pages_tag |= PDC_PAGE_LOADED_FROM_EXTENT_CACHE;
1215
+ loaded_pages_tag |= PDC_PAGE_EXTENT_FROM_CACHE;
1216
+ not_loaded_pages_tag |= PDC_PAGE_EXTENT_FROM_CACHE;
1217
extent_found_in_cache = true;
1218
}
1219
else {
1256
1257
extent_compressed_data = pgc_page_data(extent_cache_page);
1258
1197
- loaded_pages_tag |= PDC_PAGE_LOADED_FROM_DISK;
1198
- not_loaded_pages_tag |= PDC_PAGE_LOADED_FROM_DISK;
1259
+ loaded_pages_tag |= PDC_PAGE_EXTENT_FROM_DISK;
1260
+ not_loaded_pages_tag |= PDC_PAGE_EXTENT_FROM_DISK;
1261
}
1262
}
1263
1270
if(extent_used) {
1271
// since the extent was used, all the pages that are not
1272
// loaded from this extent, were not found in the extent
1211
- not_loaded_pages_tag |= PDC_PAGE_FAILED_UUID_NOT_IN_EXTENT;
1273
+ not_loaded_pages_tag |= PDC_PAGE_FAILED_NOT_IN_EXTENT;
1274
+ statistics_counter = &rrdeng_cache_efficiency_stats.pages_load_fail_not_found;
1275
}
1213
- else
1276
+ else {
1277
not_loaded_pages_tag |= PDC_PAGE_FAILED_INVALID_EXTENT;
1278
+ statistics_counter = &rrdeng_cache_efficiency_stats.pages_load_fail_invalid_extent;
1279
+ }
1280
}
1216
- else
1281
+ else {
1282
not_loaded_pages_tag |= PDC_PAGE_FAILED_TO_MAP_EXTENT;
1218
-
1283
+ statistics_counter = &rrdeng_cache_efficiency_stats.pages_load_fail_cant_mmap_extent;
1284
+ }
1285
1286
if(extent_cache_page)
1287
pgc_page_release(extent_cache, extent_cache_page);
1288
1289
+cleanup:
1290
+ // remove it from the datafile extent_queries
1291
+ // this can be called multiple times safely
1292
+ epdl_pending_del(epdl);
1293
+
1294
// mark all pending pages as failed
1295
for(EPDL *ep = epdl; ep ;ep = ep->query.next) {
1296
epdl_mark_all_not_loaded_pages_as_failed(
1226
- ep, not_loaded_pages_tag,
1227
- &rrdeng_cache_efficiency_stats.pages_load_fail_cant_mmap_extent);
1297
+ ep, not_loaded_pages_tag, statistics_counter);
1298
}
1299
1230
-cleanup:
1300
for(EPDL *ep = epdl, *next = NULL; ep ; ep = next) {
1301
next = ep->query.next;
1302