Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
sliding_window_counter.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2024, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
11#pragma once
12
13#include <atomic>
14#include <chrono>
15#include <cstdint>
16#include <memory>
17#include <vector>
18
20
52public:
56 static constexpr std::size_t DEFAULT_BUCKETS_PER_SECOND = 10;
57
66 explicit SlidingWindowCounter(
67 std::chrono::seconds window_size,
68 std::size_t buckets_per_second = DEFAULT_BUCKETS_PER_SECOND);
69
75
81
88
95
100
108 void increment(std::size_t count = 1);
109
116 [[nodiscard]] double rate_per_second() const;
117
122 [[nodiscard]] std::uint64_t total_in_window() const;
123
128 [[nodiscard]] std::uint64_t all_time_total() const;
129
135 void reset();
136
141 [[nodiscard]] std::chrono::seconds window_size() const;
142
147 [[nodiscard]] std::size_t bucket_count() const;
148
149private:
156 struct Bucket {
157 std::atomic<std::uint64_t> count{0};
158 std::atomic<std::uint64_t> timestamp_ms{0}; // Bucket start time
159
160 Bucket() = default;
161
162 Bucket(const Bucket& other)
163 : count(other.count.load(std::memory_order_relaxed)),
164 timestamp_ms(other.timestamp_ms.load(std::memory_order_relaxed)) {}
165
166 Bucket(Bucket&& other) noexcept
167 : count(other.count.load(std::memory_order_relaxed)),
168 timestamp_ms(other.timestamp_ms.load(std::memory_order_relaxed)) {}
169
170 Bucket& operator=(const Bucket& other) {
171 if (this != &other) {
172 count.store(other.count.load(std::memory_order_relaxed),
173 std::memory_order_relaxed);
174 timestamp_ms.store(other.timestamp_ms.load(std::memory_order_relaxed),
175 std::memory_order_relaxed);
176 }
177 return *this;
178 }
179
180 Bucket& operator=(Bucket&& other) noexcept {
181 if (this != &other) {
182 count.store(other.count.load(std::memory_order_relaxed),
183 std::memory_order_relaxed);
184 timestamp_ms.store(other.timestamp_ms.load(std::memory_order_relaxed),
185 std::memory_order_relaxed);
186 }
187 return *this;
188 }
189 };
190
194 std::chrono::seconds window_size_;
195
199 std::chrono::milliseconds bucket_duration_;
200
204 std::vector<Bucket> buckets_;
205
209 std::atomic<std::uint64_t> all_time_total_{0};
210
215 [[nodiscard]] std::size_t current_bucket_index() const;
216
222 [[nodiscard]] std::size_t bucket_index_for_time(std::uint64_t timestamp_ms) const;
223
228 [[nodiscard]] static std::uint64_t current_time_ms();
229
236 [[nodiscard]] bool is_bucket_valid(
237 std::uint64_t bucket_timestamp_ms,
238 std::uint64_t current_ms) const;
239
245 void advance_bucket(std::size_t bucket_index, std::uint64_t current_ms);
246};
247
248} // namespace kcenon::thread::metrics
Sliding window counter for throughput measurement.
SlidingWindowCounter & operator=(const SlidingWindowCounter &other)
Copy assignment operator.
bool is_bucket_valid(std::uint64_t bucket_timestamp_ms, std::uint64_t current_ms) const
Check if a bucket is within the current window.
std::size_t bucket_count() const
Get the number of buckets.
std::chrono::seconds window_size_
The sliding window duration.
std::size_t current_bucket_index() const
Get the current bucket index based on current time.
std::chrono::seconds window_size() const
Get the window size.
void increment(std::size_t count=1)
Increment the counter.
SlidingWindowCounter(std::chrono::seconds window_size, std::size_t buckets_per_second=DEFAULT_BUCKETS_PER_SECOND)
Constructs a sliding window counter.
std::uint64_t all_time_total() const
Get the all-time total count.
std::uint64_t total_in_window() const
Get the total count within the current window.
std::vector< Bucket > buckets_
Circular buffer of time buckets.
std::size_t bucket_index_for_time(std::uint64_t timestamp_ms) const
Get the bucket index for a specific timestamp.
double rate_per_second() const
Get the current rate per second.
std::atomic< std::uint64_t > all_time_total_
All-time total count.
std::chrono::milliseconds bucket_duration_
Duration of each bucket.
void advance_bucket(std::size_t bucket_index, std::uint64_t current_ms)
Advance bucket to current time period if needed.
static constexpr std::size_t DEFAULT_BUCKETS_PER_SECOND
Default number of buckets per second.
static std::uint64_t current_time_ms()
Get current time in milliseconds since epoch.
STL namespace.