From 291474b96f01413bcf5f9ac1ff5bb09ae63101fd Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Wed, 16 Nov 2016 03:07:03 +0100 Subject: [PATCH] refs #806, minor adjustments of token bucket --- src/blackcore/tokenbucket.cpp | 28 ++++++++++++------ src/blackcore/tokenbucket.h | 53 +++++++++++++++-------------------- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/blackcore/tokenbucket.cpp b/src/blackcore/tokenbucket.cpp index e8a4769e1..767ec3e46 100644 --- a/src/blackcore/tokenbucket.cpp +++ b/src/blackcore/tokenbucket.cpp @@ -14,6 +14,9 @@ namespace BlackCore { + CTokenBucket::CTokenBucket(int capacity, BlackMisc::PhysicalQuantities::CTime interval, int numTokensToRefill) + : m_capacity(capacity), m_interval(interval), m_numTokensToRefill(numTokensToRefill) {} + bool CTokenBucket::tryConsume(int numTokens) { Q_ASSERT(numTokens > 0 && numTokens < m_capacity); @@ -33,15 +36,24 @@ namespace BlackCore return false; } - int CTokenBucket::getTokens() + void CTokenBucket::setNumberOfTokensToRefill(int noTokens) { - auto now = QDateTime::currentDateTime(); - auto deltaSeconds = m_lastReplenishmentTime.secsTo(now); - int numberOfTokens = static_cast( m_numTokensToRefill * deltaSeconds / m_interval.value(BlackMisc::PhysicalQuantities::CTimeUnit::s())); - - // Update the time only when replenishment actually took place. We will end up in a infinite loop otherwise. - if (numberOfTokens > 0 ) m_lastReplenishmentTime = now; - return numberOfTokens; + m_numTokensToRefill = noTokens; } + void CTokenBucket::setCapacity(int capacity) + { + m_capacity = capacity; + } + + int CTokenBucket::getTokens() + { + const auto now = QDateTime::currentDateTime(); + const auto deltaSeconds = m_lastReplenishmentTime.secsTo(now); + const int numberOfTokens = static_cast(m_numTokensToRefill * deltaSeconds / m_interval.value(BlackMisc::PhysicalQuantities::CTimeUnit::s())); + + // Update the time only when replenishment actually took place. We will end up in a infinite loop otherwise. + if (numberOfTokens > 0) { m_lastReplenishmentTime = now; } + return numberOfTokens; + } } // namespace diff --git a/src/blackcore/tokenbucket.h b/src/blackcore/tokenbucket.h index e378f346c..2ae0a15cc 100644 --- a/src/blackcore/tokenbucket.h +++ b/src/blackcore/tokenbucket.h @@ -12,52 +12,45 @@ #include "blackcore/blackcoreexport.h" #include "blackmisc/pq/time.h" - #include namespace BlackCore { /*! - * Token bucket algorithm - * - * This class implements the token bucket algorithm. Tokens as arbitrary unit are added to the bucket at a defined rate. - * Token can be consumsed as long as there are enough available. This class can be used to throttle traffic and packet - * generation. Each time a packet needs to be generated and sent a token is consumed. If no token is available, consumption - * will fail the the packet cannot be sent. + * \brief Token bucket algorithm + * \details This class implements the token bucket algorithm. Tokens as arbitrary unit are added to the bucket at a defined rate. + * Token can be consumsed as long as there are enough available. This class can be used to throttle traffic and packet + * generation. Each time a packet needs to be generated and sent a token is consumed. If no token is available, consumption + * will fail the the packet cannot be sent. */ class BLACKCORE_EXPORT CTokenBucket { - public: - - //! Constructor - //! \tparam Replenishment policy - CTokenBucket(int capacity, BlackMisc::PhysicalQuantities::CTime interval, int numTokensToRefill) - : m_capacity(capacity), m_interval(interval), m_numTokensToRefill(numTokensToRefill) {} - - //! Try to consume a token - bool tryConsume() - { - return tryConsume(1); - } + //! Constructor for given replenishment policy + CTokenBucket(int capacity, BlackMisc::PhysicalQuantities::CTime interval, int numTokensToRefill); //! Try to consume a number of tokens - bool tryConsume(int numTokens); + bool tryConsume(int numTokens = 1); + + //! Number of tokens to refill + void setNumberOfTokensToRefill(int noTokens); + + //! Set the capacity + void setCapacity(int capacity); private: - //! Get available tokens since last replenishment. - // Note that replenishment is implemented lazy. This means, tokens will not replenished - // on regular basis via a running timer, but they will be replenished while trying to consume - // them. + //! \note Note that replenishment is implemented lazy. + //! This means, tokens will not replenished on regular basis via a running timer, + //! but they will be replenished while trying to consume them. int getTokens(); - int m_capacity = 10; //!< Maximum capacity of tokens - int m_availableTokens = 10; //!< Currently available tokens. The initial value is 10 - BlackMisc::PhysicalQuantities::CTime m_interval; //!< 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 + int m_capacity = 10; //!< Maximum capacity of tokens + int m_availableTokens = 10; //!< Currently available tokens. The initial value is 10 + BlackMisc::PhysicalQuantities::CTime m_interval; //!< 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 }; -} +} // ns #endif