Ref T275, adjusted token bucket to work (better) with ms (milli seconds) intervals

This commit is contained in:
Klaus Basan
2018-06-05 18:36:28 +02:00
parent 00a897f29c
commit 0849359722
2 changed files with 15 additions and 8 deletions

View File

@@ -17,14 +17,19 @@ using namespace BlackMisc::PhysicalQuantities;
namespace BlackMisc
{
CTokenBucket::CTokenBucket(int capacity, const CTime &interval, int numTokensToRefill)
: m_capacity(capacity), m_intervalSecs(interval.value(CTimeUnit::s())), m_numTokensToRefill(numTokensToRefill) {}
: m_capacity(capacity), m_numTokensToRefill(numTokensToRefill), m_intervalMs(interval.value(CTimeUnit::ms()))
{}
CTokenBucket::CTokenBucket(int capacity, qint64 intervalMs, int numTokensToRefill)
: m_capacity(capacity), m_numTokensToRefill(numTokensToRefill), m_intervalMs(intervalMs)
{}
bool CTokenBucket::tryConsume(int numTokens)
{
Q_ASSERT(numTokens > 0 && numTokens < m_capacity);
// Replenish maximal up to capacity
int replenishedTokens = qMin(m_capacity, getTokens());
int replenishedTokens = qMin(m_capacity, this->getTokens());
// Take care of overflows
m_availableTokens = qMin(m_availableTokens + replenishedTokens, m_capacity);
@@ -34,7 +39,6 @@ namespace BlackMisc
m_availableTokens -= numTokens;
return true;
}
return false;
}
@@ -50,9 +54,9 @@ namespace BlackMisc
int CTokenBucket::getTokens()
{
const auto now = QDateTime::currentDateTime();
const auto deltaSeconds = m_lastReplenishmentTime.secsTo(now);
const int numberOfTokens = static_cast<int>(m_numTokensToRefill * deltaSeconds / m_intervalSecs);
const qint64 now = QDateTime::currentMSecsSinceEpoch();
const qint64 deltaMs = now - m_lastReplenishmentTime;
const int numberOfTokens = static_cast<int>(m_numTokensToRefill * deltaMs / m_intervalMs);
// Update the time only when replenishment actually took place. We will end up in a infinite loop otherwise.
if (numberOfTokens > 0) { m_lastReplenishmentTime = now; }

View File

@@ -29,6 +29,9 @@ namespace BlackMisc
//! Constructor for given replenishment policy
CTokenBucket(int capacity, const PhysicalQuantities::CTime &interval, int numTokensToRefill);
//! Constructor for given replenishment policy
CTokenBucket(int capacity, qint64 intervalMs, int numTokensToRefill);
//! Try to consume a number of tokens
bool tryConsume(int numTokens = 1);
@@ -47,9 +50,9 @@ namespace BlackMisc
int m_capacity = 10; //!< Maximum capacity of tokens
int m_availableTokens = 10; //!< Currently available tokens. The initial value is 10
double m_intervalSecs = 5; //!< Refill interval, e.g. every 5 secs
int m_numTokensToRefill; //!< Number of tokens to be refilled each interval
QDateTime m_lastReplenishmentTime = QDateTime::currentDateTime(); //!< Last time
qint64 m_intervalMs = 5000; //!< Refill interval, e.g. every 5 secs
qint64 m_lastReplenishmentTime = QDateTime::currentMSecsSinceEpoch(); //!< Last time
};
} // ns