mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
0c2488505c
Co-authored-by: Leon Richardt <leon.richardt@gmail.com>
61 lines
1.4 KiB
C++
61 lines
1.4 KiB
C++
#pragma once
|
|
|
|
#include <algorithm>
|
|
#include <chrono>
|
|
|
|
namespace chatterino {
|
|
|
|
// Yes, you can't specify the base 😎 deal with it
|
|
template <unsigned maxSteps>
|
|
class ExponentialBackoff
|
|
{
|
|
public:
|
|
/**
|
|
* Creates an object helping you make exponentially (with base 2) backed off times.
|
|
*
|
|
* @param start The start time in milliseconds
|
|
* @param maxSteps The max number of progressions we will take before stopping
|
|
*
|
|
* For example, ExponentialBackoff(10ms, 3) would have the next() function return 10ms, 20ms, 40ms, 40ms, ..., 40ms
|
|
**/
|
|
ExponentialBackoff(const std::chrono::milliseconds &start)
|
|
: start_(start)
|
|
, step_{1}
|
|
{
|
|
static_assert(maxSteps > 1, "maxSteps must be higher than 1");
|
|
}
|
|
|
|
/**
|
|
* Return the current number in the progression and increment the step until the next one (assuming we're not at the cap)
|
|
*
|
|
* @returns current step in milliseconds
|
|
**/
|
|
[[nodiscard]] std::chrono::milliseconds next()
|
|
{
|
|
auto next = this->start_ * (1 << (this->step_ - 1));
|
|
|
|
this->step_ += 1;
|
|
|
|
if (this->step_ >= maxSteps)
|
|
{
|
|
this->step_ = maxSteps;
|
|
}
|
|
|
|
return next;
|
|
}
|
|
|
|
/**
|
|
* Reset the progression back to its initial state
|
|
**/
|
|
void reset()
|
|
{
|
|
this->step_ = 1;
|
|
}
|
|
|
|
private:
|
|
const std::chrono::milliseconds start_;
|
|
unsigned step_;
|
|
};
|
|
|
|
} // namespace chatterino
|