]> git.ipfire.org Git - thirdparty/rrdtool-1.x.git/commitdiff
Working average has value at position k added. MyMod ensures k wraps around 551/head
authorTobias Oetiker <tobi@oetiker.ch>
Wed, 29 Oct 2014 13:33:08 +0000 (14:33 +0100)
committerTobias Oetiker <tobi@oetiker.ch>
Wed, 29 Oct 2014 13:33:08 +0000 (14:33 +0100)
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

index 1eba57e88fa9ec71ec7f36123033e2e1353998cf..3014de1d595abc4d58a89f0518a5dc8e226af7ae 100644 (file)
@@ -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);