From 1fbc58e3458e0852bfab2d337fae75a6a2c52288 Mon Sep 17 00:00:00 2001 From: Melanie Plageman Date: Fri, 8 Dec 2023 14:39:17 -0500 Subject: [PATCH v2 04/10] Add accumulator to calculate normal dist online Add PgStat_Accumulator which tracks the information required to calculate a mean and standard deviation online. This is useful for storing stats whose values are normally distributed. --- src/include/pgstat.h | 62 ++++++++++++++++++++++++++++++++ src/tools/pgindent/typedefs.list | 1 + 2 files changed, 63 insertions(+) diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 69cea6c48b..8eef9398f2 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -141,6 +141,68 @@ typedef struct PgStat_BackendSubEntry PgStat_Counter sync_error_count; } PgStat_BackendSubEntry; +/* + * Used both in backend local and shared memory, this accumulator keeps track of + * the counters needed to calculate a mean and standard deviation online. + */ +typedef struct PgStat_Accumulator +{ + /* Number of values in this accumulator */ + uint64 n; + + /* Sum of values */ + double s; + + /* Sum of squared values */ + double q; +} PgStat_Accumulator; + +static inline void +accumulator_insert(PgStat_Accumulator *accumulator, double v) +{ + accumulator->n++; + accumulator->s += v; + accumulator->q += pow(v, 2); +} + +static inline double +accumulator_remove(PgStat_Accumulator *accumulator) +{ + double result; + + Assert(accumulator->n > 0); + + result = accumulator->s / accumulator->n; + + accumulator->n--; + accumulator->s -= result; + accumulator->q -= pow(result, 2); + + return result; +} + +static inline void +accumulator_absorb(PgStat_Accumulator *target, PgStat_Accumulator *source) +{ + target->n += source->n; + target->s += source->s; + target->q += source->q; +} + +static inline void +accumulator_calculate(PgStat_Accumulator *accumulator, double *mean, + double *stddev) +{ + *mean = NAN; + *stddev = INFINITY; + + if (accumulator->n == 0) + return; + + *mean = accumulator->s / accumulator->n; + *stddev = sqrt((accumulator->q - pow(accumulator->s, 2) / accumulator->n) / accumulator->n); +} + /* ---------- * PgStat_TableCounts The actual per-table counts kept by a backend * diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 3a69023dd8..b3eefb4d60 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -2054,6 +2054,7 @@ PgStatShared_ReplSlot PgStatShared_SLRU PgStatShared_Subscription PgStatShared_Wal +PgStat_Accumulator PgStat_ArchiverStats PgStat_BackendSubEntry PgStat_BgWriterStats -- 2.37.2