aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/monlib/metrics/histogram_collector_linear.cpp
blob: b893b16a8330952f316171effe4a8621eb914817 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include "histogram_collector.h"
#include "atomics_array.h"

#include <util/generic/algorithm.h>
#include <util/generic/vector.h>
#include <util/generic/yexception.h>
#include <util/generic/ylimits.h>

#include <cmath>

namespace NMonitoring {
    ///////////////////////////////////////////////////////////////////////////
    // TLinearHistogramCollector
    ///////////////////////////////////////////////////////////////////////////
    class TLinearHistogramCollector: public IHistogramCollector {
    public:
        TLinearHistogramCollector(
                ui32 bucketsCount, TBucketBound startValue, TBucketBound bucketWidth)
            : Values_(bucketsCount)
            , StartValue_(startValue)
            , BucketWidth_(bucketWidth)
            , MaxValue_(startValue + bucketWidth * (bucketsCount - 2))
        {
        }

        void Collect(double value, ui64 count) noexcept override {
            ui32 index = Max<ui32>();
            if (value <= StartValue_) {
                index = 0;
            } else if (value > MaxValue_) {
                index = Values_.Size() - 1;
            } else {
                double buckets = (value - StartValue_) / BucketWidth_;
                index = static_cast<ui32>(std::ceil(buckets));
            }
            Values_.Add(index, count);
        }

        void Reset() noexcept override {
            Values_.Reset();
        }

        IHistogramSnapshotPtr Snapshot() const override {
            return new TLinearHistogramSnapshot(
                    StartValue_, BucketWidth_, Values_.Copy());
        }

    private:
        TAtomicsArray Values_;
        TBucketBound StartValue_;
        double BucketWidth_;
        TBucketBound MaxValue_;
    };

    IHistogramCollectorPtr LinearHistogram(
        ui32 bucketsCount, TBucketBound startValue, TBucketBound bucketWidth)
    {
        Y_ENSURE(bucketsCount >= 2,
                 "linear histogram must contain at least two buckets");
        Y_ENSURE(bucketsCount <= HISTOGRAM_MAX_BUCKETS_COUNT,
                 "buckets count must be <=" << HISTOGRAM_MAX_BUCKETS_COUNT
                                            << ", but got: " << bucketsCount);
        Y_ENSURE(bucketWidth >= 1, "bucketWidth must be >= 1, got: " << bucketWidth);

        return MakeHolder<TLinearHistogramCollector>(bucketsCount, startValue, bucketWidth);
    }
}