value.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "value.h"
  3. inline NETDATA_DOUBLE rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all_values_are_null, NETDATA_DOUBLE *anomaly_rate) {
  4. QUERY_TARGET *qt = r->internal.qt;
  5. long c;
  6. const long used = qt->query.used;
  7. NETDATA_DOUBLE *cn = &r->v[ i * r->d ];
  8. RRDR_VALUE_FLAGS *co = &r->o[ i * r->d ];
  9. NETDATA_DOUBLE *ar = &r->ar[ i * r->d ];
  10. NETDATA_DOUBLE sum = 0, min = 0, max = 0, v;
  11. int all_null = 1, init = 1;
  12. NETDATA_DOUBLE total = 1;
  13. NETDATA_DOUBLE total_anomaly_rate = 0;
  14. int set_min_max = 0;
  15. if(unlikely(options & RRDR_OPTION_PERCENTAGE)) {
  16. total = 0;
  17. for (c = 0; c < used; c++) {
  18. if(unlikely(!(r->od[c] & RRDR_DIMENSION_QUERIED))) continue;
  19. NETDATA_DOUBLE n = cn[c];
  20. if(likely((options & RRDR_OPTION_ABSOLUTE) && n < 0))
  21. n = -n;
  22. total += n;
  23. }
  24. // prevent a division by zero
  25. if(total == 0) total = 1;
  26. set_min_max = 1;
  27. }
  28. // for each dimension
  29. for (c = 0; c < used; c++) {
  30. if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
  31. if(unlikely(!(r->od[c] & RRDR_DIMENSION_QUERIED))) continue;
  32. if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
  33. NETDATA_DOUBLE n = cn[c];
  34. if(likely((options & RRDR_OPTION_ABSOLUTE) && n < 0))
  35. n = -n;
  36. if(unlikely(options & RRDR_OPTION_PERCENTAGE)) {
  37. n = n * 100 / total;
  38. if(unlikely(set_min_max)) {
  39. r->min = r->max = n;
  40. set_min_max = 0;
  41. }
  42. if(n < r->min) r->min = n;
  43. if(n > r->max) r->max = n;
  44. }
  45. if(unlikely(init)) {
  46. if(n > 0) {
  47. min = 0;
  48. max = n;
  49. }
  50. else {
  51. min = n;
  52. max = 0;
  53. }
  54. init = 0;
  55. }
  56. if(likely(!(co[c] & RRDR_VALUE_EMPTY))) {
  57. all_null = 0;
  58. sum += n;
  59. }
  60. if(n < min) min = n;
  61. if(n > max) max = n;
  62. total_anomaly_rate += ar[c];
  63. }
  64. if(anomaly_rate) {
  65. if(!r->d) *anomaly_rate = 0;
  66. else *anomaly_rate = total_anomaly_rate / (NETDATA_DOUBLE)r->d;
  67. }
  68. if(unlikely(all_null)) {
  69. if(likely(all_values_are_null))
  70. *all_values_are_null = 1;
  71. return 0;
  72. }
  73. else {
  74. if(likely(all_values_are_null))
  75. *all_values_are_null = 0;
  76. }
  77. if(options & RRDR_OPTION_MIN2MAX)
  78. v = max - min;
  79. else
  80. v = sum;
  81. return v;
  82. }
  83. QUERY_VALUE rrdmetric2value(RRDHOST *host,
  84. struct rrdcontext_acquired *rca, struct rrdinstance_acquired *ria, struct rrdmetric_acquired *rma,
  85. time_t after, time_t before,
  86. RRDR_OPTIONS options, RRDR_GROUPING group_method, const char *group_options,
  87. size_t tier, time_t timeout, QUERY_SOURCE query_source, STORAGE_PRIORITY priority
  88. ) {
  89. QUERY_TARGET_REQUEST qtr = {
  90. .host = host,
  91. .rca = rca,
  92. .ria = ria,
  93. .rma = rma,
  94. .after = after,
  95. .before = before,
  96. .points = 1,
  97. .options = options,
  98. .group_method = group_method,
  99. .group_options = group_options,
  100. .tier = tier,
  101. .timeout = timeout,
  102. .query_source = query_source,
  103. .priority = priority,
  104. };
  105. ONEWAYALLOC *owa = onewayalloc_create(16 * 1024);
  106. RRDR *r = rrd2rrdr(owa, query_target_create(&qtr));
  107. QUERY_VALUE qv;
  108. if(!r || rrdr_rows(r) == 0) {
  109. qv = (QUERY_VALUE) {
  110. .value = NAN,
  111. .anomaly_rate = NAN,
  112. };
  113. }
  114. else {
  115. qv = (QUERY_VALUE) {
  116. .after = r->after,
  117. .before = r->before,
  118. .points_read = r->internal.db_points_read,
  119. .result_points = r->internal.result_points_generated,
  120. };
  121. for(size_t t = 0; t < storage_tiers ;t++)
  122. qv.storage_points_per_tier[t] = r->internal.tier_points_read[t];
  123. long i = (!(options & RRDR_OPTION_REVERSED))?(long)rrdr_rows(r) - 1:0;
  124. int all_values_are_null = 0;
  125. qv.value = rrdr2value(r, i, options, &all_values_are_null, &qv.anomaly_rate);
  126. if(all_values_are_null) {
  127. qv.value = NAN;
  128. qv.anomaly_rate = NAN;
  129. }
  130. }
  131. rrdr_free(owa, r);
  132. onewayalloc_destroy(owa);
  133. return qv;
  134. }