"\t\t\t\"name\": \"%s\",\n"
"\t\t\t\"type\": \"%s\",\n"
"\t\t\t\"family\": \"%s\",\n"
+ "\t\t\t\"context\": \"%s\",\n"
"\t\t\t\"title\": \"%s\",\n"
"\t\t\t\"priority\": %ld,\n"
"\t\t\t\"enabled\": %s,\n"
, st->name
, st->type
, st->family
+ , st->context
, st->title
, st->priority
, st->enabled?"true":"false"
"\t\t\t\"name\": \"%s\",\n"
"\t\t\t\"type\": \"%s\",\n"
"\t\t\t\"family\": \"%s\",\n"
+ "\t\t\t\"context\": \"%s\",\n"
"\t\t\t\"title\": \"%s\",\n"
"\t\t\t\"priority\": %ld,\n"
"\t\t\t\"enabled\": %d,\n"
, st->name
, st->type
, st->family
+ , st->context
, st->title
, st->priority
, st->enabled
// ----------------------------------------------------------------------------
-// RRDR options
+// RRDR dimension options
#define RRDR_EMPTY 0x01 // the dimension contains / the value is empty (null)
#define RRDR_RESET 0x02 // the dimension contains / the value is reset
#define RRDR_HIDDEN 0x04 // the dimension contains / the value is hidden
#define RRDR_NONZERO 0x08 // the dimension contains / the value is non-zero
+// RRDR result options
+#define RRDR_RESULT_OPTION_ABSOLUTE 0x00000001
+#define RRDR_RESULT_OPTION_RELATIVE 0x00000002
typedef struct rrdresult {
RRDSET *st; // the chart this result refers to
+ uint32_t result_options; // RRDR_RESULT_OPTION_*
+
int d; // the number of dimensions
long n; // the number of values in the arrays
long rows; // the number of rows used
for(c = 0, d = r->st->dimensions; d ;c++, d = d->next) {
if(!strcmp(d->name, tok)) {
r->od[c] &= ~RRDR_HIDDEN;
+
+ // since the user needs this dimension
+ // make it appear as NONZERO, to return it
+ // even if the dimension has only zeros
+ r->od[c] |= RRDR_NONZERO;
}
}
}
}
}
-uint32_t rrdr_check_options(RRDR *r, uint32_t options)
+uint32_t rrdr_check_options(RRDR *r, uint32_t options, const char *dims)
{
if(options & RRDR_OPTION_NONZERO) {
- long c, i;
- RRDDIM *rd;
-
- // find how many dimensions are not zero
- for(c = 0, i = 0, rd = r->st->dimensions; rd && c < r->d ; c++, rd = rd->next) {
- if(unlikely(r->od[c] & RRDR_HIDDEN)) continue;
- if(unlikely(!(r->od[c] & RRDR_NONZERO))) continue;
- i++;
+ long i;
+
+ if(dims && *dims) {
+ // the caller wants specific dimensions
+ // disable NONZERO option
+ // to make sure we don't accidentally prevent
+ // the specific dimensions from being returned
+ i = 0;
+ }
+ else {
+ // find how many dimensions are not zero
+ long c;
+ RRDDIM *rd;
+ for(c = 0, i = 0, rd = r->st->dimensions; rd && c < r->d ; c++, rd = rd->next) {
+ if(unlikely(r->od[c] & RRDR_HIDDEN)) continue;
+ if(unlikely(!(r->od[c] & RRDR_NONZERO))) continue;
+ i++;
+ }
}
- // if with nonzero we get i = 0
- // but c != 0, then disable nonzero
- // to show all dimensions
+ // if with nonzero we get i = 0 (no dimensions will be returned)
+ // disable nonzero to show all dimensions
if(!i) options &= ~RRDR_OPTION_NONZERO;
}
}
// for each line in the array
+ calculated_number total = 1;
for(i = start; i != end ;i += step) {
calculated_number *cn = &r->v[ i * r->d ];
uint8_t *co = &r->o[ i * r->d ];
buffer_strcat(wb, post_date);
}
+ if(unlikely(options & RRDR_OPTION_PERCENTAGE)) {
+ total = 0;
+ for(c = 0, rd = r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
+ calculated_number n = cn[c];
+
+ if(likely((options & RRDR_OPTION_ABSOLUTE) && n < 0))
+ n = -n;
+
+ total += n;
+ }
+ // prevent a division by zero
+ if(total == 0) total = 1;
+ }
+
// for each dimension
for(c = 0, rd = r->st->dimensions; rd && c < r->d ;c++, rd = rd->next) {
if(unlikely(r->od[c] & RRDR_HIDDEN)) continue;
else
buffer_strcat(wb, "null");
}
- else if((options & RRDR_OPTION_ABSOLUTE))
- buffer_rrd_value(wb, (n<0)?-n:n);
- else
+ else {
+ if(unlikely((options & RRDR_OPTION_ABSOLUTE) && n < 0))
+ n = -n;
+
+ if(unlikely(options & RRDR_OPTION_PERCENTAGE))
+ n = n * 100 / total;
+
buffer_rrd_value(wb, n);
+ }
buffer_strcat(wb, post_value);
}
}
// for each line in the array
+ calculated_number total = 1;
for(i = start; i != end ;i += step) {
calculated_number *cn = &r->v[ i * r->d ];
uint8_t *co = &r->o[ i * r->d ];
buffer_date(wb, tm->tm_year + 1900, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
}
+ if(unlikely(options & RRDR_OPTION_PERCENTAGE)) {
+ total = 0;
+ for(c = 0, d = r->st->dimensions; d && c < r->d ;c++, d = d->next) {
+ calculated_number n = cn[c];
+
+ if(likely((options & RRDR_OPTION_ABSOLUTE) && n < 0))
+ n = -n;
+
+ total += n;
+ }
+ // prevent a division by zero
+ if(total == 0) total = 1;
+ }
+
// for each dimension
for(c = 0, d = r->st->dimensions; d && c < r->d ;c++, d = d->next) {
if(unlikely(r->od[c] & RRDR_HIDDEN)) continue;
else
buffer_strcat(wb, "null");
}
- else if((options & RRDR_OPTION_ABSOLUTE))
- buffer_rrd_value(wb, (n<0)?-n:n);
- else
+ else {
+ if(unlikely((options & RRDR_OPTION_ABSOLUTE) && n < 0))
+ n = -n;
+
+ if(unlikely(options & RRDR_OPTION_PERCENTAGE))
+ n = n * 100 / total;
+
buffer_rrd_value(wb, n);
+ }
}
buffer_strcat(wb, endline);
}
// for each line in the array
+ calculated_number total = 1;
for(i = start; i != end ;i += step) {
calculated_number *cn = &r->v[ i * r->d ];
calculated_number sum = 0, min = 0, max = 0, v;
int all_null = 1, init = 1;
+ if(unlikely(options & RRDR_OPTION_PERCENTAGE)) {
+ total = 0;
+ for(c = 0, d = r->st->dimensions; d && c < r->d ;c++, d = d->next) {
+ calculated_number n = cn[c];
+
+ if(likely((options & RRDR_OPTION_ABSOLUTE) && n < 0))
+ n = -n;
+
+ total += n;
+ }
+ // prevent a division by zero
+ if(total == 0) total = 1;
+ }
+
// for each dimension
for(c = 0, d = r->st->dimensions; d && c < r->d ;c++, d = d->next) {
if(unlikely(r->od[c] & RRDR_HIDDEN)) continue;
calculated_number n = cn[c];
+ if(likely((options & RRDR_OPTION_ABSOLUTE) && n < 0))
+ n = -n;
+
+ if(unlikely(options & RRDR_OPTION_PERCENTAGE))
+ n = n * 100 / total;
+
if(unlikely(init)) {
if(n > 0) {
min = 0;
if(likely(!(co[c] & RRDR_EMPTY))) {
all_null = 0;
- if((options & RRDR_OPTION_ABSOLUTE) && n < 0) n = -n;
sum += n;
}
RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int group_method)
{
int debug = st->debug;
+ int absolute_period_requested = -1;
time_t first_entry_t = rrdset_first_entry_t(st);
time_t last_entry_t = rrdset_last_entry_t(st);
if(before == 0 && after == 0) {
before = last_entry_t;
after = first_entry_t;
+ absolute_period_requested = 0;
}
// allow relative for before and after
- if(before <= st->update_every * st->entries)
+ if(before <= st->update_every * st->entries) {
before = last_entry_t + before;
+ absolute_period_requested = 0;
+ }
- if(after <= st->update_every * st->entries)
+ if(after <= st->update_every * st->entries) {
after = last_entry_t + after;
+ absolute_period_requested = 0;
+ }
+
+ if(absolute_period_requested == -1)
+ absolute_period_requested = 1;
// make sure they are within our timeframe
if(before > last_entry_t) before = last_entry_t;
return r;
}
+ if(absolute_period_requested == 1)
+ r->result_options |= RRDR_RESULT_OPTION_ABSOLUTE;
+ else
+ r->result_options |= RRDR_RESULT_OPTION_RELATIVE;
+
// find how many dimensions we have
long dimensions = r->d;
return 500;
}
- options = rrdr_check_options(r, options);
+ if(r->result_options & RRDR_RESULT_OPTION_RELATIVE)
+ wb->options |= WB_CONTENT_NO_CACHEABLE;
+ else if(r->result_options & RRDR_RESULT_OPTION_ABSOLUTE)
+ wb->options |= WB_CONTENT_CACHEABLE;
+
+ options = rrdr_check_options(r, options, (dimensions)?buffer_tostring(dimensions):NULL);
if(dimensions)
rrdr_disable_not_selected_dimensions(r, buffer_tostring(dimensions));