cleanup and optimize rrdeng_load_metric_next() (#12966)
* cleanup and optimize rrdeng_load_metric_next() * fixed typo
Costa Tsaousis committed
May 20, 2022 at 11:29 UTC
68283aa05792f99b35c86dfc55cfad44b5b91cb0
2 files changed
+77
-73
database/engine/rrdengine.h
+1
@@ -52,6 +52,7 @@ struct rrdeng_query_handle {
52
storage_number *page;
53
usec_t page_end_time;
54
uint32_t page_length;
55
+ usec_t dt;
56
};
57
58
typedef enum {
database/engine/rrdengineapi.c
+76
-73
@@ -554,98 +554,101 @@ void rrdeng_load_metric_init(RRDDIM *rd, struct rrddim_query_handle *rrdimm_hand
554
handle->next_page_time = INVALID_TIME;
555
}
556
557
-/* Returns the metric and sets its timestamp into current_time */
558
-storage_number rrdeng_load_metric_next(struct rrddim_query_handle *rrdimm_handle, time_t *current_time)
559
-{
557
+static int rrdeng_load_page_next(struct rrddim_query_handle *rrdimm_handle, unsigned *position_ptr) {
558
struct rrdeng_query_handle *handle = (struct rrdeng_query_handle *)rrdimm_handle->handle;
561
- struct rrdengine_instance *ctx;
562
- struct rrdeng_page_descr *descr;
563
- storage_number *page, ret;
564
- unsigned position, entries;
565
- usec_t next_page_time = 0, current_position_time, page_end_time = 0;
559
+
560
+ struct rrdengine_instance *ctx = handle->ctx;
561
+ struct rrdeng_page_descr *descr = handle->descr;
562
+
563
uint32_t page_length;
564
+ usec_t page_end_time;
565
+ unsigned position;
566
568
- if (unlikely(INVALID_TIME == handle->next_page_time)) {
569
- return SN_EMPTY_SLOT;
570
- }
571
- ctx = handle->ctx;
572
- if (unlikely(NULL == (descr = handle->descr))) {
573
- /* it's the first call */
574
- next_page_time = handle->next_page_time * USEC_PER_SEC;
575
- } else {
576
- // pg_cache_atomic_get_pg_info(descr, &page_end_time, &page_length);
577
- page_end_time = handle->page_end_time;
578
- page_length = handle->page_length;
579
- page = handle->page;
580
- }
581
- position = handle->position + 1;
567
+ if (likely(descr)) {
568
+ // Drop old page's reference
569
583
- if (unlikely(NULL == descr ||
584
- position >= (page_length / sizeof(storage_number)))) {
585
- /* We need to get a new page */
586
- if (descr) {
587
- /* Drop old page's reference */
570
#ifdef NETDATA_INTERNAL_CHECKS
589
- rrd_stat_atomic_add(&ctx->stats.metric_API_consumers, -1);
571
+ rrd_stat_atomic_add(&ctx->stats.metric_API_consumers, -1);
572
#endif
591
- pg_cache_put(ctx, descr);
592
- handle->descr = NULL;
593
- handle->next_page_time = (page_end_time / USEC_PER_SEC) + 1;
594
- if (unlikely(handle->next_page_time > rrdimm_handle->end_time)) {
595
- goto no_more_metrics;
596
- }
597
- next_page_time = handle->next_page_time * USEC_PER_SEC;
598
- }
573
600
- descr = pg_cache_lookup_next(ctx, handle->page_index, &handle->page_index->id,
601
- next_page_time, rrdimm_handle->end_time * USEC_PER_SEC);
602
- if (NULL == descr) {
574
+ pg_cache_put(ctx, descr);
575
+ handle->descr = NULL;
576
+ handle->next_page_time = (handle->page_end_time / USEC_PER_SEC) + 1;
577
+
578
+ if (unlikely(handle->next_page_time > rrdimm_handle->end_time))
579
goto no_more_metrics;
604
- }
580
+ }
581
+
582
+ usec_t next_page_time = handle->next_page_time * USEC_PER_SEC;
583
+ descr = pg_cache_lookup_next(ctx, handle->page_index, &handle->page_index->id, next_page_time, rrdimm_handle->end_time * USEC_PER_SEC);
584
+ if (NULL == descr)
585
+ goto no_more_metrics;
586
+
587
#ifdef NETDATA_INTERNAL_CHECKS
606
- rrd_stat_atomic_add(&ctx->stats.metric_API_consumers, 1);
588
+ rrd_stat_atomic_add(&ctx->stats.metric_API_consumers, 1);
589
#endif
608
- handle->descr = descr;
609
- pg_cache_atomic_get_pg_info(descr, &page_end_time, &page_length);
610
- if (unlikely(INVALID_TIME == descr->start_time ||
611
- INVALID_TIME == page_end_time)) {
612
- goto no_more_metrics;
613
- }
614
- if (unlikely(descr->start_time != page_end_time && next_page_time > descr->start_time)) {
615
- /* we're in the middle of the page somewhere */
616
- entries = page_length / sizeof(storage_number);
617
- position = ((uint64_t)(next_page_time - descr->start_time)) * (entries - 1) /
618
- (page_end_time - descr->start_time);
619
- } else {
620
- position = 0;
621
- }
590
623
- handle->page_end_time = page_end_time;
624
- handle->page_length = page_length;
625
- page = handle->page = descr->pg_cache_descr->page;
591
+ handle->descr = descr;
592
+ pg_cache_atomic_get_pg_info(descr, &page_end_time, &page_length);
593
+ if (unlikely(INVALID_TIME == descr->start_time || INVALID_TIME == page_end_time))
594
+ goto no_more_metrics;
595
+
596
+ if (unlikely(descr->start_time != page_end_time && next_page_time > descr->start_time)) {
597
+ // we're in the middle of the page somewhere
598
+ unsigned entries = page_length / sizeof(storage_number);
599
+ position = ((uint64_t)(next_page_time - descr->start_time)) * (entries - 1) /
600
+ (page_end_time - descr->start_time);
601
}
602
+ else
603
+ position = 0;
604
+
605
+ handle->page_end_time = page_end_time;
606
+ handle->page_length = page_length;
607
+ handle->page = descr->pg_cache_descr->page;
608
+ usec_t entries = page_length / sizeof(storage_number);
609
+ if (likely(entries > 1))
610
+ handle->dt = (page_end_time - descr->start_time) / (entries - 1);
611
+ else
612
+ handle->dt = 0;
613
628
- // page = descr->pg_cache_descr->page;
629
- ret = page[position];
630
- entries = page_length / sizeof(storage_number);
614
+ *position_ptr = position;
615
+ return 0;
616
632
- if (entries > 1) {
633
- usec_t dt;
617
+no_more_metrics:
618
+ return 1;
619
+}
620
635
- dt = (page_end_time - descr->start_time) / (entries - 1);
636
- current_position_time = descr->start_time + position * dt;
637
- } else {
638
- current_position_time = descr->start_time;
621
+/* Returns the metric and sets its timestamp into current_time */
622
+storage_number rrdeng_load_metric_next(struct rrddim_query_handle *rrdimm_handle, time_t *current_time) {
623
+ struct rrdeng_query_handle *handle = (struct rrdeng_query_handle *)rrdimm_handle->handle;
624
+
625
+ if (unlikely(INVALID_TIME == handle->next_page_time))
626
+ return SN_EMPTY_SLOT;
627
+
628
+ struct rrdeng_page_descr *descr = handle->descr;
629
+
630
+ storage_number *page = handle->page;
631
+ unsigned position = handle->position + 1;
632
+
633
+ if (unlikely(!descr || position >= (handle->page_length / sizeof(storage_number)))) {
634
+ // We need to get a new page
635
+ if(rrdeng_load_page_next(rrdimm_handle, &position))
636
+ goto no_more_metrics;
637
+
638
+ descr = handle->descr;
639
+ page = handle->page;
640
}
641
+
642
+ storage_number ret = page[position];
643
handle->position = position;
641
- handle->now = current_position_time / USEC_PER_SEC;
642
-/* fatal_assert(handle->now >= rrdimm_handle->start_time && handle->now <= rrdimm_handle->end_time);
643
- The above assertion is an approximation and needs to take update_every into account */
644
- if (unlikely(handle->now >= rrdimm_handle->end_time)) {
645
- /* next calls will not load any more metrics */
644
+ time_t now = handle->now = (descr->start_time + position * handle->dt) / USEC_PER_SEC;
645
+
646
+ if (unlikely(now >= rrdimm_handle->end_time)) {
647
+ // next calls will not load any more metrics
648
handle->next_page_time = INVALID_TIME;
649
}
648
- *current_time = handle->now;
650
+
651
+ *current_time = now;
652
return ret;
653
654
no_more_metrics: