aboutsummaryrefslogtreecommitdiff
path: root/zencore/include
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2021-09-29 22:26:02 +0200
committerStefan Boberg <[email protected]>2021-09-29 22:26:02 +0200
commit60dcdd0a7c1c8184f60444d92bae39ea3273ec8f (patch)
tree0a137d5b7fa9b28b866253a86994d0a9f8c85583 /zencore/include
parentfilesystem: Fixed issue with FindClose potentially closing an invalid handle (diff)
downloadzen-60dcdd0a7c1c8184f60444d92bae39ea3273ec8f.tar.xz
zen-60dcdd0a7c1c8184f60444d92bae39ea3273ec8f.zip
stats: added Histogram, UniformSample and SampleSnapshot
Diffstat (limited to 'zencore/include')
-rw-r--r--zencore/include/zencore/stats.h88
1 files changed, 85 insertions, 3 deletions
diff --git a/zencore/include/zencore/stats.h b/zencore/include/zencore/stats.h
index 0554f620d..7665d0cf5 100644
--- a/zencore/include/zencore/stats.h
+++ b/zencore/include/zencore/stats.h
@@ -2,11 +2,12 @@
#pragma once
-#include <atomic>
-#include <type_traits>
#include "zencore.h"
-namespace zen {
+#include <atomic>
+#include <random>
+
+namespace zen::metrics {
template<typename T>
class Gauge
@@ -97,6 +98,87 @@ private:
void Tick();
};
+/** Moment-in-time snapshot of a distribution
+ */
+class SampleSnapshot
+{
+public:
+ SampleSnapshot(std::vector<double>&& Values);
+ ~SampleSnapshot();
+
+ uint32_t Size() const { return (uint32_t)m_Values.size(); }
+ double GetQuantileValue(double Quantile);
+ double GetMedian() { return GetQuantileValue(0.5); }
+ double Get75Percentile() { return GetQuantileValue(0.75); }
+ double Get95Percentile() { return GetQuantileValue(0.95); }
+ double Get98Percentile() { return GetQuantileValue(0.98); }
+ double Get99Percentile() { return GetQuantileValue(0.99); }
+ double Get999Percentile() { return GetQuantileValue(0.999); }
+ const std::vector<double>& GetValues() const;
+
+private:
+ std::vector<double> m_Values;
+};
+
+/** Randomly selects samples from a stream. Uses Vitter's
+ Algorithm R to produce a statistically representative sample.
+
+ http://www.cs.umd.edu/~samir/498/vitter.pdf - Random Sampling with a Reservoir
+ */
+
+class UniformSample
+{
+public:
+ UniformSample(uint32_t ReservoirSize);
+ ~UniformSample();
+
+ void Clear();
+ uint32_t Size() const;
+ void Update(int64_t Value);
+ SampleSnapshot Snapshot() const;
+
+ template<std::invocable<int64_t> T>
+ void IterateValues(T Callback) const
+ {
+ for (const auto& Value : m_Values)
+ {
+ Callback(Value);
+ }
+ }
+
+private:
+ std::atomic<uint64_t> m_SampleCounter{0};
+ std::vector<std::atomic<int64_t>> m_Values;
+};
+
+/** Track (probabilistic) sample distribution along with min/max
+ */
+class Histogram
+{
+public:
+ Histogram(int32_t SampleCount = 1028);
+ ~Histogram();
+
+ void Clear();
+ void Update(int64_t Value);
+ int64_t Max() const;
+ int64_t Min() const;
+ double Mean() const;
+ uint64_t Count() const;
+ SampleSnapshot Snapshot() const { return m_Sample.Snapshot(); }
+
+private:
+ UniformSample m_Sample;
+ std::atomic<int64_t> m_Min{0};
+ std::atomic<int64_t> m_Max{0};
+ std::atomic<int64_t> m_Sum{0};
+ std::atomic<int64_t> m_Count{0};
+};
+
+} // namespace zen::metrics
+
+namespace zen {
+
extern void stats_forcelink();
} // namespace zen