diff options
Diffstat (limited to 'web/api/queries/query.c')
-rw-r--r-- | web/api/queries/query.c | 102 |
1 files changed, 15 insertions, 87 deletions
diff --git a/web/api/queries/query.c b/web/api/queries/query.c index 74a925bc..6f3cbd5f 100644 --- a/web/api/queries/query.c +++ b/web/api/queries/query.c @@ -17,6 +17,7 @@ #include "percentile/percentile.h" #include "trimmed_mean/trimmed_mean.h" +#define QUERY_PLAN_MIN_POINTS 10 #define POINTS_TO_EXPAND_QUERY 5 // ---------------------------------------------------------------------------- @@ -996,6 +997,10 @@ static size_t query_metric_best_tier_for_timeframe(QUERY_METRIC *qm, time_t afte if(unlikely(after_wanted == before_wanted || points_wanted <= 0)) return query_metric_first_working_tier(qm); + if(points_wanted < QUERY_PLAN_MIN_POINTS) + // when selecting tiers, aim for a resolution of at least QUERY_PLAN_MIN_POINTS points + points_wanted = (before_wanted - after_wanted) > QUERY_PLAN_MIN_POINTS ? QUERY_PLAN_MIN_POINTS : before_wanted - after_wanted; + time_t min_first_time_s = 0; time_t max_last_time_s = 0; @@ -2070,88 +2075,6 @@ static void rrd2rrdr_log_request_response_metadata(RRDR *r } #endif // NETDATA_INTERNAL_CHECKS -// Returns 1 if an absolute period was requested or 0 if it was a relative period -bool rrdr_relative_window_to_absolute(time_t *after, time_t *before, time_t *now_ptr) { - time_t now = now_realtime_sec() - 1; - - if(now_ptr) - *now_ptr = now; - - int absolute_period_requested = -1; - long long after_requested, before_requested; - - before_requested = *before; - after_requested = *after; - - // allow relative for before (smaller than API_RELATIVE_TIME_MAX) - if(ABS(before_requested) <= API_RELATIVE_TIME_MAX) { - // if the user asked for a positive relative time, - // flip it to a negative - if(before_requested > 0) - before_requested = -before_requested; - - before_requested = now + before_requested; - absolute_period_requested = 0; - } - - // allow relative for after (smaller than API_RELATIVE_TIME_MAX) - if(ABS(after_requested) <= API_RELATIVE_TIME_MAX) { - if(after_requested > 0) - after_requested = -after_requested; - - // if the user didn't give an after, use the number of points - // to give a sane default - if(after_requested == 0) - after_requested = -600; - - // since the query engine now returns inclusive timestamps - // it is awkward to return 6 points when after=-5 is given - // so for relative queries we add 1 second, to give - // more predictable results to users. - after_requested = before_requested + after_requested + 1; - absolute_period_requested = 0; - } - - if(absolute_period_requested == -1) - absolute_period_requested = 1; - - // check if the parameters are flipped - if(after_requested > before_requested) { - long long t = before_requested; - before_requested = after_requested; - after_requested = t; - } - - // if the query requests future data - // shift the query back to be in the present time - // (this may also happen because of the rules above) - if(before_requested > now) { - long long delta = before_requested - now; - before_requested -= delta; - after_requested -= delta; - } - - time_t absolute_minimum_time = now - (10 * 365 * 86400); - time_t absolute_maximum_time = now + (1 * 365 * 86400); - - if (after_requested < absolute_minimum_time && !unittest_running) - after_requested = absolute_minimum_time; - - if (after_requested > absolute_maximum_time && !unittest_running) - after_requested = absolute_maximum_time; - - if (before_requested < absolute_minimum_time && !unittest_running) - before_requested = absolute_minimum_time; - - if (before_requested > absolute_maximum_time && !unittest_running) - before_requested = absolute_maximum_time; - - *before = before_requested; - *after = after_requested; - - return (absolute_period_requested != 1); -} - // #define DEBUG_QUERY_LOGIC 1 #ifdef DEBUG_QUERY_LOGIC @@ -2278,7 +2201,7 @@ bool query_target_calculate_window(QUERY_TARGET *qt) { } // convert our before_wanted and after_wanted to absolute - rrdr_relative_window_to_absolute(&after_wanted, &before_wanted, NULL); + rrdr_relative_window_to_absolute(&after_wanted, &before_wanted, NULL, unittest_running); query_debug_log(":relative2absolute after %ld, before %ld", after_wanted, before_wanted); if (natural_points && (options & RRDR_OPTION_SELECTED_TIER) && tier > 0 && storage_tiers > 1) { @@ -2983,11 +2906,11 @@ static RRDR *rrd2rrdr_group_by_initialize(ONEWAYALLOC *owa, QUERY_TARGET *qt) { } // initialize partial trimming - r->partial_data_trimming.max_update_every = update_every_max; + r->partial_data_trimming.max_update_every = update_every_max * 2; r->partial_data_trimming.expected_after = (!query_target_aggregatable(qt) && - qt->window.before >= qt->window.now - update_every_max) ? - qt->window.before - update_every_max : + qt->window.before >= qt->window.now - r->partial_data_trimming.max_update_every) ? + qt->window.before - r->partial_data_trimming.max_update_every : qt->window.before; r->partial_data_trimming.trimmed_after = qt->window.before; @@ -3139,6 +3062,8 @@ static void rrdr2rrdr_group_by_partial_trimming(RRDR *r) { if(unlikely(i < 0)) return; + // internal_error(true, "Found trimmable index %zd (from 0 to %zu)", i, r->n - 1); + size_t last_row_gbc = 0; for (; i < (ssize_t)r->n; i++) { size_t row_gbc = 0; @@ -3149,8 +3074,11 @@ static void rrdr2rrdr_group_by_partial_trimming(RRDR *r) { row_gbc += r->gbc[ i * r->d + d ]; } - if (unlikely(r->t[i] >= trimmable_after && row_gbc < last_row_gbc)) { + // internal_error(true, "GBC of index %zd is %zu", i, row_gbc); + + if (unlikely(r->t[i] >= trimmable_after && (row_gbc < last_row_gbc || !row_gbc))) { // discard the rest of the points + // internal_error(true, "Discarding points %zd to %zu", i, r->n - 1); r->partial_data_trimming.trimmed_after = r->t[i]; r->rows = i; break; |