aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/monlib/dynamic_counters/percentile/percentile.h
diff options
context:
space:
mode:
Diffstat (limited to 'library/cpp/monlib/dynamic_counters/percentile/percentile.h')
-rw-r--r--library/cpp/monlib/dynamic_counters/percentile/percentile.h59
1 files changed, 59 insertions, 0 deletions
diff --git a/library/cpp/monlib/dynamic_counters/percentile/percentile.h b/library/cpp/monlib/dynamic_counters/percentile/percentile.h
new file mode 100644
index 0000000000..73c482bce9
--- /dev/null
+++ b/library/cpp/monlib/dynamic_counters/percentile/percentile.h
@@ -0,0 +1,59 @@
+#pragma once
+
+#include "percentile_base.h"
+
+namespace NMonitoring {
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Percentile tracker for monitoring
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+template <size_t BUCKET_SIZE, size_t BUCKET_COUNT, size_t FRAME_COUNT>
+struct TPercentileTracker : public TPercentileBase {
+ TAtomic Items[BUCKET_COUNT];
+ TAtomicBase Frame[FRAME_COUNT][BUCKET_COUNT];
+ size_t CurrentFrame;
+
+ TPercentileTracker()
+ : CurrentFrame(0)
+ {
+ for (size_t i = 0; i < BUCKET_COUNT; ++i) {
+ AtomicSet(Items[i], 0);
+ }
+ for (size_t frame = 0; frame < FRAME_COUNT; ++frame) {
+ for (size_t bucket = 0; bucket < BUCKET_COUNT; ++bucket) {
+ Frame[frame][bucket] = 0;
+ }
+ }
+ }
+
+ void Increment(size_t value) {
+ AtomicIncrement(Items[Min((value + BUCKET_SIZE - 1) / BUCKET_SIZE, BUCKET_COUNT - 1)]);
+ }
+
+ // shift frame (call periodically)
+ void Update() {
+ TVector<TAtomicBase> totals(BUCKET_COUNT);
+ totals.resize(BUCKET_COUNT);
+ TAtomicBase total = 0;
+ for (size_t i = 0; i < BUCKET_COUNT; ++i) {
+ TAtomicBase item = AtomicGet(Items[i]);
+ TAtomicBase prevItem = Frame[CurrentFrame][i];
+ Frame[CurrentFrame][i] = item;
+ total += item - prevItem;
+ totals[i] = total;
+ }
+
+ for (size_t i = 0; i < Percentiles.size(); ++i) {
+ TPercentile &percentile = Percentiles[i];
+ auto threshold = (TAtomicBase)(percentile.first * (float)total);
+ threshold = Min(threshold, total);
+ auto it = LowerBound(totals.begin(), totals.end(), threshold);
+ size_t index = it - totals.begin();
+ (*percentile.second) = index * BUCKET_SIZE;
+ }
+ CurrentFrame = (CurrentFrame + 1) % FRAME_COUNT;
+ }
+};
+
+} // NMonitoring