userver: userver/utils/sliding_interval.hpp Source File
Loading...
Searching...
No Matches
sliding_interval.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utils/sliding_interval.hpp
4/// @brief @copybrief utils::SlidingInterval
5
6#include <numeric>
7
8#include <userver/utils/assert.hpp>
9#include <userver/utils/fixed_array.hpp>
10
11USERVER_NAMESPACE_BEGIN
12
13namespace utils {
14
15/// @ingroup userver_universal userver_containers
16///
17/// @brief Sliding interval of values that provides functions to compute
18/// average, min and max values from the last `window_size` values of interval.
19///
20/// It fits for small `window_size` values because has O(window_size) complexity
21/// on most operations.
22///
23/// @see utils::statistics::MinMaxAvg for a concurrent safe computation over
24/// a whole measurement interval.
25template <typename T>
26class SlidingInterval final {
27 public:
28 /// @brief Create a SlidingInterval of `window_size` values
29 explicit SlidingInterval(std::size_t window_size) : buckets_(window_size) {
30 UASSERT(this->buckets_.size() > 0);
31 }
32
33 /// @brief replaces the oldest value in interval with `value`, i.e slides the
34 /// interval.
35 void Update(T value) {
36 buckets_[idx_] = value;
37 ++idx_;
38 if (idx_ == buckets_.size()) {
39 idx_ = 0;
40 }
41 }
42
43 /// @returns Average value in the interval
44 ///
45 /// \b Complexity: O(window_size)
46 [[nodiscard]] T GetSmoothed() const {
47 return std::accumulate(buckets_.begin(), buckets_.end(),
48 static_cast<T>(0)) /
49 this->buckets_.size();
50 }
51
52 /// @returns Minimal value in the interval
53 ///
54 /// \b Complexity: O(window_size)
55 [[nodiscard]] T GetMinimal() const {
56 return *std::min_element(buckets_.begin(), buckets_.end());
57 }
58
59 /// @returns Maximum value in the interval
60 ///
61 /// \b Complexity: O(window_size)
62 [[nodiscard]] T GetMaximum() const {
63 return *std::max_element(buckets_.begin(), buckets_.end());
64 }
65
66 /// @returns Elements count in the interval, i.e. `window_size` passed to
67 /// constructor.
68 [[nodiscard]] std::size_t GetWindowSize() const { return buckets_.size(); }
69
70 private:
71 utils::FixedArray<T> buckets_;
72 std::size_t idx_{0};
73};
74
75} // namespace utils
76
77USERVER_NAMESPACE_END