summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2022-11-09 11:51:52 -0500
committerDavid Goulet <dgoulet@torproject.org>2022-11-09 11:51:52 -0500
commitbd055a258a71e7683e205b5f9df299053b137d32 (patch)
treeaf551b5e0528e8a4e088cbed887054e74ad0c358 /src/lib
parent1ff78f3751a63b96c7257b33e9ada4d70174b166 (diff)
parent4db03ac360213901d45beb8d54918f1a6417ccba (diff)
downloadtor-bd055a258a71e7683e205b5f9df299053b137d32.tar.gz
tor-bd055a258a71e7683e205b5f9df299053b137d32.zip
Merge branch 'maint-0.4.7'
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/math/stats.h30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/lib/math/stats.h b/src/lib/math/stats.h
index 328d61a9d6..14315a2506 100644
--- a/src/lib/math/stats.h
+++ b/src/lib/math/stats.h
@@ -10,13 +10,33 @@
#ifndef TOR_STATS_H
#define TOR_STATS_H
-/** Update an average making it a "running average". The "avg" is the current
- * value that will be updated to the new one. The "value" is the new value to
- * add to the average and "n" is the new count as in including the "value". */
+/**
+ * Compute an N-count EWMA, aka N-EWMA. N-EWMA is defined as:
+ * EWMA = alpha*value + (1-alpha)*EWMA_prev
+ * with alpha = 2/(N+1).
+ *
+ * This works out to:
+ * EWMA = value*2/(N+1) + EMA_prev*(N-1)/(N+1)
+ * = (value*2 + EWMA_prev*(N-1))/(N+1)
+ */
static inline double
-stats_update_running_avg(double avg, double value, double n)
+n_count_ewma_double(double avg, double value, uint64_t N)
{
- return ((avg * (n - 1)) + value) / n;
+ /* If the average was not previously computed, return value.
+ * The less than is because we have stupid C warning flags that
+ * prevent exact comparison to 0.0, so we can't do an exact
+ * check for unitialized double values. Yay pedantry!
+ * Love it when it introduces surprising edge case bugs like
+ * this will. */
+ if (avg < 0.0000002)
+ return value;
+ else
+ return (2*value + (N-1)*avg)/(N+1);
}
+/* For most stats, an N_EWMA of 100 is sufficient */
+#define DEFAULT_STATS_N_EWMA_COUNT 100
+#define stats_update_running_avg(avg, value) \
+ n_count_ewma_double(avg, value, DEFAULT_STATS_N_EWMA_COUNT)
+
#endif /* !defined(TOR_STATS_H) */