@cryptotaxi247 / netdata-1 / commits / 68283aa05

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: