#include <stdlib.h>
#include <time.h>
#include <locale.h>
+#include <math.h>
#include "rrd_tool.h"
#include "rrd_rpncalc.h"
unsigned long FnvHash(
const char *str);
-int create_hw_contingent_rras(
- rrd_t *rrd,
- unsigned short period,
- unsigned long hashed_name);
void parseGENERIC_DS(
const char *def,
ds_def_t *ds_def);
}
+static int parseRRA(const char *def,
+ rra_def_t *rra_def,
+ unsigned long hash) {
+ char *argvcopy;
+ char *tokptr = "";
+ unsigned short token_idx, error_flag, period = 0;
+ int cf_id = -1;
+ int token_min = 4;
+ int row_cnt;
+
+ memset(rra_def, 0, sizeof(rra_def_t));
+
+ argvcopy = strdup(def);
+ char *token = strtok_r(&argvcopy[4], ":", &tokptr);
+ token_idx = error_flag = 0;
+
+ while (token != NULL) {
+ switch (token_idx) {
+ case 0:
+ if (sscanf(token, CF_NAM_FMT, rra_def->cf_nam) != 1)
+ rrd_set_error("Failed to parse CF name");
+ cf_id = cf_conv(rra_def->cf_nam);
+ switch (cf_id) {
+ case CF_MHWPREDICT:
+ // FIXME strcpy(rrd.stat_head->version, RRD_VERSION); /* MHWPREDICT causes Version 4 */
+ case CF_HWPREDICT:
+ token_min = 5;
+ /* initialize some parameters */
+ rra_def->par[RRA_hw_alpha].
+ u_val = 0.1;
+ rra_def->par[RRA_hw_beta].
+ u_val = 1.0 / 288;
+ rra_def->par[RRA_dependent_rra_idx].u_cnt = INT_MAX;
+ break;
+ case CF_DEVSEASONAL:
+ token_min = 3;
+ case CF_SEASONAL:
+ if (cf_id == CF_SEASONAL){
+ token_min = 4;
+ }
+ /* initialize some parameters */
+ rra_def->par[RRA_seasonal_gamma].u_val = 0.1;
+ rra_def->par[RRA_seasonal_smoothing_window].u_val = 0.05;
+ /* fall through */
+ case CF_DEVPREDICT:
+ if (cf_id == CF_DEVPREDICT){
+ token_min = 3;
+ }
+ rra_def->par[RRA_dependent_rra_idx].u_cnt = -1;
+ break;
+ case CF_FAILURES:
+ token_min = 5;
+ rra_def->par[RRA_delta_pos].u_val = 2.0;
+ rra_def->par[RRA_delta_neg].u_val = 2.0;
+ rra_def->par[RRA_window_len].u_cnt = 3;
+ rra_def->par[RRA_failure_threshold].u_cnt = 2;
+ rra_def->par[RRA_dependent_rra_idx].u_cnt = -1;
+ break;
+ /* invalid consolidation function */
+ case -1:
+ rrd_set_error
+ ("Unrecognized consolidation function %s",
+ rra_def->cf_nam);
+ default:
+ break;
+ }
+ /* default: 1 pdp per cdp */
+ rra_def->pdp_cnt = 1;
+ break;
+ case 1:
+ switch (cf_conv
+ (rra_def->cf_nam)) {
+ case CF_HWPREDICT:
+ case CF_MHWPREDICT:
+ case CF_DEVSEASONAL:
+ case CF_SEASONAL:
+ case CF_DEVPREDICT:
+ case CF_FAILURES:
+ row_cnt = atoi(token);
+ if (row_cnt <= 0)
+ rrd_set_error("Invalid row count: %i", row_cnt);
+ rra_def->row_cnt = row_cnt;
+ break;
+ default:
+ rra_def->par[RRA_cdp_xff_val].u_val = atof(token);
+ if (rra_def->par[RRA_cdp_xff_val].u_val < 0.0
+ || rra_def->par[RRA_cdp_xff_val].u_val >= 1.0)
+ rrd_set_error
+ ("Invalid xff: must be between 0 and 1");
+ break;
+ }
+ break;
+ case 2:
+ switch (cf_conv
+ (rra_def->cf_nam)) {
+ case CF_HWPREDICT:
+ case CF_MHWPREDICT:
+ rra_def->par[RRA_hw_alpha].
+ u_val = atof(token);
+ if (atof(token) <= 0.0 || atof(token) >= 1.0)
+ rrd_set_error
+ ("Invalid alpha: must be between 0 and 1");
+ break;
+ case CF_DEVSEASONAL:
+ case CF_SEASONAL:
+ rra_def->par[RRA_seasonal_gamma].u_val = atof(token);
+ if (atof(token) <= 0.0 || atof(token) >= 1.0)
+ rrd_set_error
+ ("Invalid gamma: must be between 0 and 1");
+ rra_def->par[RRA_seasonal_smooth_idx].u_cnt =
+ hash % rra_def->row_cnt;
+ break;
+ case CF_FAILURES:
+ /* specifies the # of violations that constitutes the failure threshold */
+ rra_def->par[RRA_failure_threshold].u_cnt = atoi(token);
+ if (atoi(token) < 1
+ || atoi(token) > MAX_FAILURES_WINDOW_LEN)
+ rrd_set_error
+ ("Failure threshold is out of range %d, %d",
+ 1, MAX_FAILURES_WINDOW_LEN);
+ break;
+ case CF_DEVPREDICT:
+ /* specifies the index (1-based) of CF_DEVSEASONAL array
+ * associated with this CF_DEVPREDICT array. */
+ rra_def->par[RRA_dependent_rra_idx].u_cnt =
+ atoi(token) - 1;
+ break;
+ default:
+ rra_def->pdp_cnt = atoi(token);
+ if (atoi(token) < 1)
+ rrd_set_error("Invalid step: must be >= 1");
+ break;
+ }
+ break;
+ case 3:
+ switch (cf_conv(rra_def->cf_nam)) {
+ case CF_HWPREDICT:
+ case CF_MHWPREDICT:
+ rra_def->par[RRA_hw_beta].u_val = atof(token);
+ if (atof(token) < 0.0 || atof(token) > 1.0)
+ rrd_set_error
+ ("Invalid beta: must be between 0 and 1");
+ break;
+ case CF_DEVSEASONAL:
+ case CF_SEASONAL:
+ /* specifies the index (1-based) of CF_HWPREDICT array
+ * associated with this CF_DEVSEASONAL or CF_SEASONAL array.
+ * */
+ rra_def->par[RRA_dependent_rra_idx].u_cnt =
+ atoi(token) - 1;
+ break;
+ case CF_FAILURES:
+ /* specifies the window length */
+ rra_def->par[RRA_window_len].u_cnt = atoi(token);
+ if (atoi(token) < 1
+ || atoi(token) > MAX_FAILURES_WINDOW_LEN)
+ rrd_set_error
+ ("Window length is out of range %d, %d", 1,
+ MAX_FAILURES_WINDOW_LEN);
+ /* verify that window length exceeds the failure threshold */
+ if (rra_def->par[RRA_window_len].u_cnt <
+ rra_def->par[RRA_failure_threshold].u_cnt)
+ rrd_set_error
+ ("Window length is shorter than the failure threshold");
+ break;
+ case CF_DEVPREDICT:
+ /* shouldn't be any more arguments */
+ rrd_set_error
+ ("Unexpected extra argument for consolidation function DEVPREDICT");
+ break;
+ default:
+ row_cnt = atoi(token);
+ if (row_cnt <= 0)
+ rrd_set_error("Invalid row count: %i", row_cnt);
+#if SIZEOF_TIME_T == 4
+ if ((long long) pdp_step * rra_def->pdp_cnt * row_cnt > 4294967296LL){
+ /* database timespan > 2**32, would overflow time_t */
+ rrd_set_error("The time spanned by the database is too large: must be <= 4294967296 seconds");
+ }
+#endif
+ rra_def->row_cnt = row_cnt;
+ break;
+ }
+ break;
+ case 4:
+ switch (cf_conv(rra_def->cf_nam)) {
+ case CF_FAILURES:
+ /* specifies the index (1-based) of CF_DEVSEASONAL array
+ * associated with this CF_DEVFAILURES array. */
+ rra_def->par[RRA_dependent_rra_idx].u_cnt =
+ atoi(token) - 1;
+ break;
+ case CF_DEVSEASONAL:
+ case CF_SEASONAL:
+ /* optional smoothing window */
+ if (sscanf(token, "smoothing-window=%lf",
+ &(rra_def->par[RRA_seasonal_smoothing_window].
+ u_val))) {
+ // FIXME strcpy(rrd.stat_head->version, RRD_VERSION); /* smoothing-window causes Version 4 */
+ if (rra_def->par[RRA_seasonal_smoothing_window].u_val < 0.0
+ || rra_def->par[RRA_seasonal_smoothing_window].u_val >
+ 1.0) {
+ rrd_set_error
+ ("Invalid smoothing-window %f: must be between 0 and 1",
+ rra_def->par[RRA_seasonal_smoothing_window].
+ u_val);
+ }
+ } else {
+ rrd_set_error("Invalid option %s", token);
+ }
+ break;
+ case CF_HWPREDICT:
+ case CF_MHWPREDICT:
+ /* length of the associated CF_SEASONAL and CF_DEVSEASONAL arrays. */
+ period = atoi(token);
+ if (period >
+ rra_def->row_cnt)
+ rrd_set_error
+ ("Length of seasonal cycle exceeds length of HW prediction array");
+ rra_def->par[RRA_period].u_val = period;
+
+ break;
+ default:
+ /* shouldn't be any more arguments */
+ rrd_set_error
+ ("Unexpected extra argument for consolidation function %s",
+ rra_def->cf_nam);
+ break;
+ }
+ break;
+ case 5:
+ /* If we are here, this must be a CF_HWPREDICT RRA.
+ * Specifies the index (1-based) of CF_SEASONAL array
+ * associated with this CF_HWPREDICT array. If this argument
+ * is missing, then the CF_SEASONAL, CF_DEVSEASONAL, CF_DEVPREDICT,
+ * CF_FAILURES.
+ * arrays are created automatically. */
+ rra_def->par[RRA_dependent_rra_idx].u_cnt = atoi(token) - 1;
+ break;
+ default:
+ /* should never get here */
+ rrd_set_error("Unknown error");
+ break;
+ } /* end switch */
+ if (rrd_test_error()) {
+ /* all errors are unrecoverable */
+ free(argvcopy);
+ return (-1);
+ }
+ token = strtok_r(NULL, ":", &tokptr);
+ token_idx++;
+ } /* end while */
+ free(argvcopy);
+ if (token_idx < token_min){
+ rrd_set_error("Expected at least %i arguments for RRA but got %i",token_min,token_idx);
+ return(-1);
+ }
+#ifdef DEBUG
+ fprintf(stderr,
+ "Creating RRA CF: %s, dep idx %lu\n",
+ rra_def->cf_nam,
+ rra_def->par[RRA_dependent_rra_idx].u_cnt);
+#endif
+
+ return 0;
+}
+/*
+ this function checks THE LAST rra_def in the rra_def_array (that is,
+ the one with index rra_cnt-1 to check if more RRAs have to be
+ created
+ */
+static rra_def_t *handle_dependent_rras(rra_def_t *rra_def_array,
+ long unsigned int *rra_cnt,
+ unsigned long hash) {
+ rra_def_t *rra_def = rra_def_array + (*rra_cnt-1);
+
+ /* should we create CF_SEASONAL, CF_DEVSEASONAL, and CF_DEVPREDICT? */
+ if ((cf_conv(rra_def->cf_nam) == CF_HWPREDICT
+ || cf_conv(rra_def->cf_nam) == CF_MHWPREDICT)
+ && rra_def->par[RRA_dependent_rra_idx].u_cnt == INT_MAX) {
+ rra_def->par[RRA_dependent_rra_idx].u_cnt = *rra_cnt-1;
+#ifdef DEBUG
+ fprintf(stderr, "Creating HW contingent RRAs\n");
+#endif
+
+ rra_def_array = create_hw_contingent_rras(rra_def_array,
+ rra_cnt,
+ rra_def->par[RRA_period].u_val,
+ hash);
+ if (rra_def_array == NULL) {
+ rrd_set_error("creating contingent RRA");
+ return NULL;
+ }
+ }
+
+ return rra_def_array;
+}
+
/* #define DEBUG */
/* For backwards compatibility with previous API. Use rrd_create_r2 if you
{
rrd_t rrd;
long i;
- char *token;
- unsigned short token_idx, error_flag, period = 0;
unsigned long hashed_name;
/* clear any previous errors */
}
} else if (strncmp(argv[i], "RRA:", 4) == 0) {
- char *argvcopy;
- char *tokptr = "";
- int cf_id = -1;
size_t old_size = sizeof(rra_def_t) * (rrd.stat_head->rra_cnt);
- int row_cnt;
- int token_min = 4;
if ((rrd.rra_def = (rra_def_t*)rrd_realloc(rrd.rra_def,
old_size + sizeof(rra_def_t))) ==
NULL) {
rrd_free2(&rrd);
return (-1);
}
- memset(&rrd.rra_def[rrd.stat_head->rra_cnt], 0,
- sizeof(rra_def_t));
- argvcopy = strdup(argv[i]);
- token = strtok_r(&argvcopy[4], ":", &tokptr);
- token_idx = error_flag = 0;
-
- while (token != NULL) {
- switch (token_idx) {
- case 0:
- if (sscanf(token, CF_NAM_FMT,
- rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam) !=
- 1)
- rrd_set_error("Failed to parse CF name");
- cf_id = cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam);
- switch (cf_id) {
- case CF_MHWPREDICT:
- strcpy(rrd.stat_head->version, RRD_VERSION); /* MHWPREDICT causes Version 4 */
- case CF_HWPREDICT:
- token_min = 5;
- /* initialize some parameters */
- rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_alpha].
- u_val = 0.1;
- rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_beta].
- u_val = 1.0 / 288;
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_dependent_rra_idx].u_cnt =
- rrd.stat_head->rra_cnt;
- break;
- case CF_DEVSEASONAL:
- token_min = 3;
- case CF_SEASONAL:
- if (cf_id == CF_SEASONAL){
- token_min = 4;
- }
- /* initialize some parameters */
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_seasonal_gamma].u_val = 0.1;
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_seasonal_smoothing_window].u_val = 0.05;
- /* fall through */
- case CF_DEVPREDICT:
- if (cf_id == CF_DEVPREDICT){
- token_min = 3;
- }
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_dependent_rra_idx].u_cnt = -1;
- break;
- case CF_FAILURES:
- token_min = 5;
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_delta_pos].u_val = 2.0;
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_delta_neg].u_val = 2.0;
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_window_len].u_cnt = 3;
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_failure_threshold].u_cnt = 2;
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_dependent_rra_idx].u_cnt = -1;
- break;
- /* invalid consolidation function */
- case -1:
- rrd_set_error
- ("Unrecognized consolidation function %s",
- rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam);
- default:
- break;
- }
- /* default: 1 pdp per cdp */
- rrd.rra_def[rrd.stat_head->rra_cnt].pdp_cnt = 1;
- break;
- case 1:
- switch (cf_conv
- (rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam)) {
- case CF_HWPREDICT:
- case CF_MHWPREDICT:
- case CF_DEVSEASONAL:
- case CF_SEASONAL:
- case CF_DEVPREDICT:
- case CF_FAILURES:
- row_cnt = atoi(token);
- if (row_cnt <= 0)
- rrd_set_error("Invalid row count: %i", row_cnt);
- rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt = row_cnt;
- break;
- default:
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_cdp_xff_val].u_val = atof(token);
- if (rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_cdp_xff_val].u_val < 0.0
- || rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_cdp_xff_val].u_val >= 1.0)
- rrd_set_error
- ("Invalid xff: must be between 0 and 1");
- break;
- }
- break;
- case 2:
- switch (cf_conv
- (rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam)) {
- case CF_HWPREDICT:
- case CF_MHWPREDICT:
- rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_alpha].
- u_val = atof(token);
- if (atof(token) <= 0.0 || atof(token) >= 1.0)
- rrd_set_error
- ("Invalid alpha: must be between 0 and 1");
- break;
- case CF_DEVSEASONAL:
- case CF_SEASONAL:
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_seasonal_gamma].u_val = atof(token);
- if (atof(token) <= 0.0 || atof(token) >= 1.0)
- rrd_set_error
- ("Invalid gamma: must be between 0 and 1");
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_seasonal_smooth_idx].u_cnt =
- hashed_name %
- rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt;
- break;
- case CF_FAILURES:
- /* specifies the # of violations that constitutes the failure threshold */
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_failure_threshold].u_cnt = atoi(token);
- if (atoi(token) < 1
- || atoi(token) > MAX_FAILURES_WINDOW_LEN)
- rrd_set_error
- ("Failure threshold is out of range %d, %d",
- 1, MAX_FAILURES_WINDOW_LEN);
- break;
- case CF_DEVPREDICT:
- /* specifies the index (1-based) of CF_DEVSEASONAL array
- * associated with this CF_DEVPREDICT array. */
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_dependent_rra_idx].u_cnt =
- atoi(token) - 1;
- break;
- default:
- rrd.rra_def[rrd.stat_head->rra_cnt].pdp_cnt =
- atoi(token);
- if (atoi(token) < 1)
- rrd_set_error("Invalid step: must be >= 1");
- break;
- }
- break;
- case 3:
- switch (cf_conv
- (rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam)) {
- case CF_HWPREDICT:
- case CF_MHWPREDICT:
- rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_beta].
- u_val = atof(token);
- if (atof(token) < 0.0 || atof(token) > 1.0)
- rrd_set_error
- ("Invalid beta: must be between 0 and 1");
- break;
- case CF_DEVSEASONAL:
- case CF_SEASONAL:
- /* specifies the index (1-based) of CF_HWPREDICT array
- * associated with this CF_DEVSEASONAL or CF_SEASONAL array.
- * */
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_dependent_rra_idx].u_cnt =
- atoi(token) - 1;
- break;
- case CF_FAILURES:
- /* specifies the window length */
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_window_len].u_cnt = atoi(token);
- if (atoi(token) < 1
- || atoi(token) > MAX_FAILURES_WINDOW_LEN)
- rrd_set_error
- ("Window length is out of range %d, %d", 1,
- MAX_FAILURES_WINDOW_LEN);
- /* verify that window length exceeds the failure threshold */
- if (rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_window_len].u_cnt <
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_failure_threshold].u_cnt)
- rrd_set_error
- ("Window length is shorter than the failure threshold");
- break;
- case CF_DEVPREDICT:
- /* shouldn't be any more arguments */
- rrd_set_error
- ("Unexpected extra argument for consolidation function DEVPREDICT");
- break;
- default:
- row_cnt = atoi(token);
- if (row_cnt <= 0)
- rrd_set_error("Invalid row count: %i", row_cnt);
-#if SIZEOF_TIME_T == 4
- if ((long long) pdp_step * rrd.rra_def[rrd.stat_head->rra_cnt].pdp_cnt * row_cnt > 4294967296LL){
- /* database timespan > 2**32, would overflow time_t */
- rrd_set_error("The time spanned by the database is too large: must be <= 4294967296 seconds");
- }
-#endif
- rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt = row_cnt;
- break;
- }
- break;
- case 4:
- switch (cf_conv
- (rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam)) {
- case CF_FAILURES:
- /* specifies the index (1-based) of CF_DEVSEASONAL array
- * associated with this CF_DEVFAILURES array. */
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_dependent_rra_idx].u_cnt =
- atoi(token) - 1;
- break;
- case CF_DEVSEASONAL:
- case CF_SEASONAL:
- /* optional smoothing window */
- if (sscanf(token, "smoothing-window=%lf",
- &(rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_seasonal_smoothing_window].
- u_val))) {
- strcpy(rrd.stat_head->version, RRD_VERSION); /* smoothing-window causes Version 4 */
- if (rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_seasonal_smoothing_window].u_val < 0.0
- || rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_seasonal_smoothing_window].u_val >
- 1.0) {
- rrd_set_error
- ("Invalid smoothing-window %f: must be between 0 and 1",
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_seasonal_smoothing_window].
- u_val);
- }
- } else {
- rrd_set_error("Invalid option %s", token);
- }
- break;
- case CF_HWPREDICT:
- case CF_MHWPREDICT:
- /* length of the associated CF_SEASONAL and CF_DEVSEASONAL arrays. */
- period = atoi(token);
- if (period >
- rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt)
- rrd_set_error
- ("Length of seasonal cycle exceeds length of HW prediction array");
- break;
- default:
- /* shouldn't be any more arguments */
- rrd_set_error
- ("Unexpected extra argument for consolidation function %s",
- rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam);
- break;
- }
- break;
- case 5:
- /* If we are here, this must be a CF_HWPREDICT RRA.
- * Specifies the index (1-based) of CF_SEASONAL array
- * associated with this CF_HWPREDICT array. If this argument
- * is missing, then the CF_SEASONAL, CF_DEVSEASONAL, CF_DEVPREDICT,
- * CF_FAILURES.
- * arrays are created automatically. */
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_dependent_rra_idx].u_cnt = atoi(token) - 1;
- break;
- default:
- /* should never get here */
- rrd_set_error("Unknown error");
- break;
- } /* end switch */
- if (rrd_test_error()) {
- /* all errors are unrecoverable */
- free(argvcopy);
- rrd_free2(&rrd);
- return (-1);
- }
- token = strtok_r(NULL, ":", &tokptr);
- token_idx++;
- } /* end while */
- free(argvcopy);
- if (token_idx < token_min){
- rrd_set_error("Expected at least %i arguments for RRA but got %i",token_min,token_idx);
+ parseRRA(argv[i], rrd.rra_def + rrd.stat_head->rra_cnt,
+ hashed_name);
+
+ if (rrd_test_error()) {
rrd_free2(&rrd);
- return(-1);
- }
-#ifdef DEBUG
- fprintf(stderr,
- "Creating RRA CF: %s, dep idx %lu, current idx %lu\n",
- rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam,
- rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_dependent_rra_idx].u_cnt, rrd.stat_head->rra_cnt);
-#endif
- /* should we create CF_SEASONAL, CF_DEVSEASONAL, and CF_DEVPREDICT? */
- if ((cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam) ==
- CF_HWPREDICT
- || cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam) ==
- CF_MHWPREDICT)
- && rrd.rra_def[rrd.stat_head->rra_cnt].
- par[RRA_dependent_rra_idx].u_cnt == rrd.stat_head->rra_cnt) {
-#ifdef DEBUG
- fprintf(stderr, "Creating HW contingent RRAs\n");
-#endif
- if (create_hw_contingent_rras(&rrd, period, hashed_name) ==
- -1) {
- rrd_set_error("creating contingent RRA");
- rrd_free2(&rrd);
- return -1;
- }
+ return -1;
}
- rrd.stat_head->rra_cnt++;
+
+ rrd.stat_head->rra_cnt++;
+
+ rrd.rra_def = handle_dependent_rras(rrd.rra_def, &(rrd.stat_head->rra_cnt),
+ hashed_name);
+ if (rrd.rra_def == NULL) {
+ rrd_free2(&rrd);
+ return -1;
+ }
} else {
rrd_set_error("can't parse argument '%s'", argv[i]);
rrd_free2(&rrd);
/* Create the CF_DEVPREDICT, CF_DEVSEASONAL, CF_SEASONAL, and CF_FAILURES RRAs
* associated with a CF_HWPREDICT RRA. */
-int create_hw_contingent_rras(
- rrd_t *rrd,
- unsigned short period,
- unsigned long hashed_name)
+rra_def_t * create_hw_contingent_rras(rra_def_t *rra_defs,
+ long unsigned int *rra_cnt,
+ unsigned short period,
+ unsigned long hash)
{
size_t old_size;
rra_def_t *current_rra;
/* save index to CF_HWPREDICT */
- unsigned long hw_index = rrd->stat_head->rra_cnt;
+ unsigned long hw_index = *rra_cnt - 1;
- /* advance the pointer */
- (rrd->stat_head->rra_cnt)++;
/* allocate the memory for the 4 contingent RRAs */
- old_size = sizeof(rra_def_t) * (rrd->stat_head->rra_cnt);
- if ((rrd->rra_def = (rra_def_t*)rrd_realloc(rrd->rra_def,
- old_size + 4 * sizeof(rra_def_t))) ==
+ old_size = sizeof(rra_def_t) * (*rra_cnt);
+ if ((rra_defs = (rra_def_t*)rrd_realloc(rra_defs,
+ old_size + 4 * sizeof(rra_def_t))) ==
NULL) {
- rrd_free2(rrd);
- rrd_set_error("allocating rrd.rra_def");
- return (-1);
+ rrd_set_error("allocating rra_def");
+ return NULL;
}
+
+
/* clear memory */
- memset(&(rrd->rra_def[rrd->stat_head->rra_cnt]), 0,
+ memset(&(rra_defs[*rra_cnt]), 0,
4 * sizeof(rra_def_t));
+ rra_def_t *hw_rra = rra_defs + hw_index;
+
/* create the CF_SEASONAL RRA */
- current_rra = &(rrd->rra_def[rrd->stat_head->rra_cnt]);
+ current_rra = rra_defs + *rra_cnt;
+
strcpy(current_rra->cf_nam, "SEASONAL");
current_rra->row_cnt = period;
- current_rra->par[RRA_seasonal_smooth_idx].u_cnt = hashed_name % period;
+ current_rra->par[RRA_seasonal_smooth_idx].u_cnt = hash % period;
current_rra->pdp_cnt = 1;
- current_rra->par[RRA_seasonal_gamma].u_val =
- rrd->rra_def[hw_index].par[RRA_hw_alpha].u_val;
+ current_rra->par[RRA_seasonal_gamma].u_val =
+ hw_rra->par[RRA_hw_alpha].u_val;
current_rra->par[RRA_dependent_rra_idx].u_cnt = hw_index;
- rrd->rra_def[hw_index].par[RRA_dependent_rra_idx].u_cnt =
- rrd->stat_head->rra_cnt;
+
+ hw_rra->par[RRA_dependent_rra_idx].u_cnt = *rra_cnt;
+
+ (*rra_cnt)++;
/* create the CF_DEVSEASONAL RRA */
- (rrd->stat_head->rra_cnt)++;
- current_rra = &(rrd->rra_def[rrd->stat_head->rra_cnt]);
+ current_rra = rra_defs + *rra_cnt;
+
strcpy(current_rra->cf_nam, "DEVSEASONAL");
current_rra->row_cnt = period;
- current_rra->par[RRA_seasonal_smooth_idx].u_cnt = hashed_name % period;
+ current_rra->par[RRA_seasonal_smooth_idx].u_cnt = hash % period;
current_rra->pdp_cnt = 1;
current_rra->par[RRA_seasonal_gamma].u_val =
- rrd->rra_def[hw_index].par[RRA_hw_alpha].u_val;
+ hw_rra->par[RRA_hw_alpha].u_val;
current_rra->par[RRA_dependent_rra_idx].u_cnt = hw_index;
+ (*rra_cnt)++;
+
/* create the CF_DEVPREDICT RRA */
- (rrd->stat_head->rra_cnt)++;
- current_rra = &(rrd->rra_def[rrd->stat_head->rra_cnt]);
+ current_rra = rra_defs + *rra_cnt;
+
strcpy(current_rra->cf_nam, "DEVPREDICT");
- current_rra->row_cnt = (rrd->rra_def[hw_index]).row_cnt;
+ current_rra->row_cnt = hw_rra->row_cnt;
current_rra->pdp_cnt = 1;
current_rra->par[RRA_dependent_rra_idx].u_cnt = hw_index + 2; /* DEVSEASONAL */
+ (*rra_cnt)++;
+
/* create the CF_FAILURES RRA */
- (rrd->stat_head->rra_cnt)++;
- current_rra = &(rrd->rra_def[rrd->stat_head->rra_cnt]);
+ current_rra = rra_defs + *rra_cnt;
+
strcpy(current_rra->cf_nam, "FAILURES");
current_rra->row_cnt = period;
current_rra->pdp_cnt = 1;
current_rra->par[RRA_failure_threshold].u_cnt = 7;
current_rra->par[RRA_window_len].u_cnt = 9;
current_rra->par[RRA_dependent_rra_idx].u_cnt = hw_index + 2; /* DEVSEASONAL */
- return 0;
+ (*rra_cnt)++;
+
+ return rra_defs;
}
/* create and empty rrd file according to the specs given */