+/* Reset aberrant behavior model coefficients, including intercept, slope,
+ * seasonal, and seasonal deviation for the specified data source. */
+void
+reset_aberrant_coefficients(rrd_t *rrd, FILE *rrd_file, unsigned long ds_idx)
+{
+ unsigned long cdp_idx, rra_idx, i;
+ unsigned long cdp_start, rra_start;
+ rrd_value_t nan_buffer = DNAN;
+
+ /* compute the offset for the cdp area */
+ cdp_start = sizeof(stat_head_t) +
+ rrd->stat_head->ds_cnt * sizeof(ds_def_t) +
+ rrd->stat_head->rra_cnt * sizeof(rra_def_t) +
+ sizeof(live_head_t) +
+ rrd->stat_head->ds_cnt * sizeof(pdp_prep_t);
+ /* compute the offset for the first rra */
+ rra_start = cdp_start +
+ (rrd->stat_head->ds_cnt) * (rrd->stat_head->rra_cnt) * sizeof(cdp_prep_t) +
+ rrd->stat_head->rra_cnt * sizeof(rra_ptr_t);
+
+ /* loop over the RRAs */
+ for (rra_idx = 0; rra_idx < rrd -> stat_head -> rra_cnt; rra_idx++)
+ {
+ cdp_idx = rra_idx * (rrd-> stat_head-> ds_cnt) + ds_idx;
+ switch (cf_conv(rrd -> rra_def[rra_idx].cf_nam))
+ {
+ case CF_HWPREDICT:
+ init_hwpredict_cdp(&(rrd -> cdp_prep[cdp_idx]));
+ break;
+ case CF_SEASONAL:
+ case CF_DEVSEASONAL:
+ /* don't use init_seasonal because it will reset burn-in, which
+ * means different data sources will be calling for the smoother
+ * at different times. */
+ rrd->cdp_prep[cdp_idx].scratch[CDP_hw_seasonal].u_val = DNAN;
+ rrd->cdp_prep[cdp_idx].scratch[CDP_hw_last_seasonal].u_val = DNAN;
+ /* move to first entry of data source for this rra */
+ fseek(rrd_file,rra_start + ds_idx * sizeof(rrd_value_t),SEEK_SET);
+ /* entries for the same data source are not contiguous,
+ * temporal entries are contiguous */
+ for (i = 0; i < rrd->rra_def[rra_idx].row_cnt; ++i)
+ {
+ if (fwrite(&nan_buffer,sizeof(rrd_value_t),1,rrd_file) != 1)
+ {
+ rrd_set_error(
+ "reset_aberrant_coefficients: write failed data source %lu rra %s",
+ ds_idx,rrd->rra_def[rra_idx].cf_nam);
+ return;
+ }
+ fseek(rrd_file,(rrd->stat_head->ds_cnt - 1) *
+ sizeof(rrd_value_t),SEEK_CUR);
+ }
+ break;
+ case CF_FAILURES:
+ erase_violations(rrd,cdp_idx,rra_idx);
+ break;
+ default:
+ break;
+ }
+ /* move offset to the next rra */
+ rra_start += rrd->rra_def[rra_idx].row_cnt * rrd->stat_head->ds_cnt *
+ sizeof(rrd_value_t);
+ }
+ fseek(rrd_file,cdp_start,SEEK_SET);
+ if (fwrite( rrd -> cdp_prep,
+ sizeof(cdp_prep_t),
+ (rrd->stat_head->rra_cnt) * rrd->stat_head->ds_cnt, rrd_file)
+ != (rrd->stat_head->rra_cnt) * (rrd->stat_head->ds_cnt) )
+ {
+ rrd_set_error("reset_aberrant_coefficients: cdp_prep write failed");
+ return;
+ }
+}
+
+void init_hwpredict_cdp(cdp_prep_t *cdp)
+{
+ cdp->scratch[CDP_hw_intercept].u_val = DNAN;
+ cdp->scratch[CDP_hw_last_intercept].u_val = DNAN;
+ cdp->scratch[CDP_hw_slope].u_val = DNAN;
+ cdp->scratch[CDP_hw_last_slope].u_val = DNAN;
+ cdp->scratch[CDP_null_count].u_cnt = 1;
+ cdp->scratch[CDP_last_null_count].u_cnt = 1;
+}
+
+void init_seasonal_cdp(cdp_prep_t *cdp)
+{
+ cdp->scratch[CDP_hw_seasonal].u_val = DNAN;
+ cdp->scratch[CDP_hw_last_seasonal].u_val = DNAN;
+ cdp->scratch[CDP_init_seasonal].u_cnt = 1;
+}
+