- free(rrd_values);
- return 0;
- }
- }
- }
-
- /* allocate queues, one for each data source */
- buffers = (FIFOqueue **) malloc(sizeof(FIFOqueue *)*row_length);
- for (i = 0; i < row_length; ++i)
- {
- queue_alloc(&(buffers[i]),2*offset + 1);
- }
- /* need working average initialized to 0 */
- working_average = (rrd_value_t *) calloc(row_length,sizeof(rrd_value_t));
-
- /* compute sums of the first 2*offset terms */
- for (i = 0; i < 2*offset; ++i)
- {
- k = MyMod(i - offset,row_count);
- for (j = 0; j < row_length; ++j)
- {
- queue_push(buffers[j],rrd_values[k*row_length + j]);
- working_average[j] += rrd_values[k*row_length + j];
- }
- }
-
- /* compute moving averages */
- for (i = offset; i < row_count + offset; ++i)
- {
- for (j = 0; j < row_length; ++j)
- {
- k = MyMod(i,row_count);
- /* add a term to the sum */
- working_average[j] += rrd_values[k*row_length + j];
- queue_push(buffers[j],rrd_values[k*row_length + j]);
-
- /* reset k to be the center of the window */
- k = MyMod(i - offset,row_count);
- /* overwrite rdd_values entry, the old value is already
- * saved in buffers */
- rrd_values[k*row_length + j] = working_average[j]/(2*offset + 1);
-
- /* remove a term from the sum */
- working_average[j] -= queue_pop(buffers[j]);
- }
- }
-
- for (i = 0; i < row_length; ++i)
- {
- queue_dealloc(buffers[i]);
- }
- free(buffers);
- free(working_average);
-
- /* flush updated values to disk */
- fflush(rrd_file);
- if (fseek(rrd_file,rra_start,SEEK_SET))
- {
- rrd_set_error("apply_smoother: seek to pos %d failed", rra_start);
- free(rrd_values);
- return -1;
- }
- /* write as a single block */
- if (fwrite(rrd_values,sizeof(rrd_value_t),row_length*row_count,rrd_file)
- != row_length*row_count)
- {
- rrd_set_error("apply_smoother: write failed to %lu",rra_start);
- free(rrd_values);
- return -1;
- }
-
- fflush(rrd_file);
- free(rrd_values);
- return 0;
+ free(rrd_values);
+ return 0;
+ }
+ }
+ }
+
+ /* allocate queues, one for each data source */
+ buffers = (FIFOqueue **) malloc(sizeof(FIFOqueue *) * row_length);
+ for (i = 0; i < row_length; ++i) {
+ queue_alloc(&(buffers[i]), 2 * offset + 1);
+ }
+ /* need working average initialized to 0 */
+ working_average = (rrd_value_t *) calloc(row_length, sizeof(rrd_value_t));
+ baseline = (rrd_value_t *) calloc(row_length, sizeof(rrd_value_t));
+
+ /* compute sums of the first 2*offset terms */
+ for (i = 0; i < 2 * offset; ++i) {
+ k = MyMod(i - offset, row_count);
+ for (j = 0; j < row_length; ++j) {
+ queue_push(buffers[j], rrd_values[k * row_length + j]);
+ working_average[j] += rrd_values[k * row_length + j];
+ }
+ }
+
+ /* compute moving averages */
+ for (i = offset; i < row_count + offset; ++i) {
+ for (j = 0; j < row_length; ++j) {
+ k = MyMod(i, row_count);
+ /* add a term to the sum */
+ working_average[j] += rrd_values[k * row_length + j];
+ queue_push(buffers[j], rrd_values[k * row_length + j]);
+
+ /* reset k to be the center of the window */
+ k = MyMod(i - offset, row_count);
+ /* overwrite rdd_values entry, the old value is already
+ * saved in buffers */
+ rrd_values[k * row_length + j] =
+ working_average[j] / (2 * offset + 1);
+ baseline[j] += rrd_values[k * row_length + j];
+
+ /* remove a term from the sum */
+ working_average[j] -= queue_pop(buffers[j]);
+ }
+ }
+
+ for (i = 0; i < row_length; ++i) {
+ queue_dealloc(buffers[i]);
+ baseline[i] /= row_count;
+ }
+ free(buffers);
+ free(working_average);
+
+ if (cf_conv(rrd->rra_def[rra_idx].cf_nam) == CF_SEASONAL) {
+ for (j = 0; j < row_length; ++j) {
+ for (i = 0; i < row_count; ++i) {
+ rrd_values[i * row_length + j] -= baseline[j];
+ }
+ /* update the baseline coefficient,
+ * first, compute the cdp_index. */
+ offset = (rrd->rra_def[rra_idx].par[RRA_dependent_rra_idx].u_cnt)
+ * row_length + j;
+ (rrd->cdp_prep[offset]).scratch[CDP_hw_intercept].u_val +=
+ baseline[j];
+ }
+ /* flush cdp to disk */
+ rrd_flush(rrd_file);
+ if (rrd_seek(rrd_file, 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), SEEK_SET)) {
+ rrd_set_error("apply_smoother: seek to cdp_prep failed");
+ free(rrd_values);
+ return -1;
+ }
+ if (rrd_write(rrd_file, rrd->cdp_prep,
+ sizeof(cdp_prep_t) *
+ (rrd->stat_head->rra_cnt) * rrd->stat_head->ds_cnt)
+ != (ssize_t) (sizeof(cdp_prep_t) * (rrd->stat_head->rra_cnt) *
+ (rrd->stat_head->ds_cnt))) {
+ rrd_set_error("apply_smoother: cdp_prep write failed");
+ free(rrd_values);
+ return -1;
+ }
+ }
+
+ /* endif CF_SEASONAL */
+ /* flush updated values to disk */
+ rrd_flush(rrd_file);
+ if (rrd_seek(rrd_file, rra_start, SEEK_SET)) {
+ rrd_set_error("apply_smoother: seek to pos %d failed", rra_start);
+ free(rrd_values);
+ return -1;
+ }
+ /* write as a single block */
+ if (rrd_write
+ (rrd_file, rrd_values, sizeof(rrd_value_t) * row_length * row_count)
+ != (ssize_t) (sizeof(rrd_value_t) * row_length * row_count)) {
+ rrd_set_error("apply_smoother: write failed to %lu", rra_start);
+ free(rrd_values);
+ return -1;
+ }
+
+ rrd_flush(rrd_file);
+ free(rrd_values);
+ free(baseline);
+ return 0;