Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
RateLimit.cpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2021 Reactive Markets Limited
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16#include "RateLimit.hpp"
17
19
20namespace toolbox {
21inline namespace net {
22using namespace std;
23
25{
26 const auto [limit, interval] = split_pair(s, '/');
27 return RateLimit{ston<size_t>(limit), Seconds{ston<int>(interval)}};
28}
29
30istream& operator>>(istream& is, RateLimit& rl)
31{
32 string s;
33 if (is >> s) {
35 }
36 return is;
37}
38
39ostream& operator<<(ostream& os, RateLimit rl)
40{
41 return os << rl.limit() << '/' << rl.interval().count();
42}
43
44RateWindow::~RateWindow() = default;
45
46// Copy.
47RateWindow::RateWindow(const RateWindow&) = default;
48RateWindow& RateWindow::operator=(const RateWindow&) = default;
49
50// Move.
52RateWindow& RateWindow::operator=(RateWindow&&) noexcept = default;
53
54void RateWindow::add(MonoTime time, size_t count) noexcept
55{
56 const auto t = duration_cast<Decis>(time.time_since_epoch());
57 auto& bucket = at(t.count());
58 // The fast path and simplest case is where the time falls within the same time bucket as the
59 // previous tick.
60 if (t == last_time_) {
61 count_ += count;
62 bucket += count;
63 return;
64 }
65 // Clock is assumed to be monotonic, so if the time is not the same, then it must be greater.
66 assert(t > last_time_);
67 // If the time has advanced by less than one complete cycle of the buffers.
68 if ((t - last_time_).count() < int64_t(buckets_.size())) {
69 // Advance past any interleaving buckets.
70 while (t != ++last_time_) {
71 auto& skipped = at(last_time_.count());
72 count_ -= skipped;
73 skipped = 0;
74 }
75 // And then adjust the count on the target bucket.
76 count_ = count_ + count - bucket;
77 } else {
78 // Zero the entire buffer.
79 fill(buckets_.begin(), buckets_.end(), 0);
80 count_ = count;
81 }
82 last_time_ = t;
83 bucket = count;
84}
85
86} // namespace net
87} // namespace toolbox
RateWindow maintains a sliding window of second time buckets for the specified interval.
Definition RateLimit.hpp:60
RateWindow & operator=(const RateWindow &)
RateWindow(intervalT interval)
Definition RateLimit.hpp:63
STL namespace.
ostream & operator<<(ostream &os, const pair< T, U > &p)
Definition Parser.ut.cpp:29
istream & operator>>(istream &is, DgramEndpoint &ep)
Definition Endpoint.cpp:100
RateLimit parse_rate_limit(const string &s)
Definition RateLimit.cpp:24
MonoClock::time_point MonoTime
Definition Time.hpp:110
std::chrono::seconds Seconds
Definition Time.hpp:33
pair< string_view, string_view > split_pair(string_view s, char delim) noexcept
Definition String.cpp:51
constexpr auto bind() noexcept
Definition Slot.hpp:92