From 7b0d500fc41eeb51e5dc394ef8d607a6b0e489ce Mon Sep 17 00:00:00 2001 From: Tobias Oetiker Date: Wed, 29 Oct 2014 14:33:08 +0100 Subject: [PATCH] Working average has value at position k added. MyMod ensures k wraps around to beginning when in excess of row_count. But when wrapping around the first (#=offset) entries are already updated so you are smoothing later values using pre-smoothed values. This is effectively double weighting some values and diluting the last (#=offset) values smoothed since they are getting some effect from outside their expected smoothing window. This patch fixes the problem by first makeing a copy of the rrd_values. --- src/rrd_hw.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/rrd_hw.c b/src/rrd_hw.c index 1eba57e8..3014de1d 100644 --- a/src/rrd_hw.c +++ b/src/rrd_hw.c @@ -139,6 +139,7 @@ int apply_smoother( unsigned long offset; FIFOqueue **buffers; rrd_value_t *working_average; + rrd_value_t *rrd_values_cpy; rrd_value_t *baseline; if (atoi(rrd->stat_head->version) >= 4) { @@ -209,13 +210,19 @@ int apply_smoother( } } - /* compute moving averages */ + /* as we are working through the value, we have to make sure to not double + apply the smoothing after wrapping around. so best is to copy the rrd_values first */ + + rrd_values_cpy = (rrd_value_t *) calloc(row_length, sizeof(rrd_value_t)); + memcpy(rrd_values_cpy,rrd_values,sizeof(rrd_value_t)*row_length); + + /* 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]); + working_average[j] += rrd_values_cpy[k * row_length + j]; + queue_push(buffers[j], rrd_values_cpy[k * row_length + j]); /* reset k to be the center of the window */ k = MyMod(i - offset, row_count); @@ -234,6 +241,7 @@ int apply_smoother( queue_dealloc(buffers[i]); baseline[i] /= row_count; } + free(rrd_values_cpy); free(buffers); free(working_average); -- 2.47.2