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
39RateWindow::~RateWindow() = default;
40
41// Copy.
42RateWindow::RateWindow(const RateWindow&) = default;
43RateWindow& RateWindow::operator=(const RateWindow&) = default;
44
45// Move.
47RateWindow& RateWindow::operator=(RateWindow&&) noexcept = default;
48
49void RateWindow::add(MonoTime time, size_t count) noexcept
50{
51 const auto t = duration_cast<Decis>(time.time_since_epoch());
52 auto& bucket = at(t.count());
53 // The fast path and simplest case is where the time falls within the same time bucket as the
54 // previous tick.
55 if (t == last_time_) {
56 count_ += count;
57 bucket += count;
58 return;
59 }
60 // Clock is assumed to be monotonic, so if the time is not the same, then it must be greater.
61 assert(t > last_time_);
62 // If the time has advanced by less than one complete cycle of the buffers.
63 if ((t - last_time_).count() < int64_t(buckets_.size())) {
64 // Advance past any interleaving buckets.
65 while (t != ++last_time_) {
66 auto& skipped = at(last_time_.count());
67 count_ -= skipped;
68 skipped = 0;
69 }
70 // And then adjust the count on the target bucket.
71 count_ = count_ + count - bucket;
72 } else {
73 // Zero the entire buffer.
74 fill(buckets_.begin(), buckets_.end(), 0);
75 count_ = count;
76 }
77 last_time_ = t;
78 bucket = count;
79}
80
81} // namespace net
82} // namespace toolbox
RateWindow maintains a sliding window of second time buckets for the specified interval.
Definition RateLimit.hpp:68
RateWindow & operator=(const RateWindow &)
RateWindow(intervalT interval)
Definition RateLimit.hpp:71
STL namespace.
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, string_view delim) noexcept
Definition String.cpp:52
constexpr auto bind() noexcept
Definition Slot.hpp:92