swift
tokenbucket.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2014 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "misc/tokenbucket.h"
5 
6 #include <QtGlobal>
7 
8 namespace swift::misc
9 {
10  CTokenBucket::CTokenBucket(int capacity, qint64 intervalMs, int numTokensToRefill)
11  : m_capacity(capacity), m_numTokensToRefill(numTokensToRefill), m_intervalMs(intervalMs)
12  {}
13 
14  bool CTokenBucket::tryConsume(int numTokens, qint64 msSinceEpoch)
15  {
16  Q_ASSERT(numTokens > 0 && numTokens < m_capacity);
17 
18  // enough tokens in stock?
19  if (numTokens <= m_availableTokens)
20  {
21  m_availableTokens -= numTokens;
22  return true;
23  }
24 
25  // Replenish maximal up to capacity
26  const int tokens = this->getTokens(msSinceEpoch);
27  const int replenishedTokens = qMin(m_capacity, tokens);
28 
29  // Take care of overflows
30  m_availableTokens = qMin(m_availableTokens + replenishedTokens, m_capacity);
31 
32  // check again after replenishment
33  if (numTokens <= m_availableTokens)
34  {
35  m_availableTokens -= numTokens;
36  return true;
37  }
38  return false;
39  }
40 
41  void CTokenBucket::setNumberOfTokensToRefill(int numTokens) { m_numTokensToRefill = numTokens; }
42 
43  void CTokenBucket::setCapacity(int capacity) { m_capacity = capacity; }
44 
46  {
47  this->setCapacity(numTokens);
48  this->setNumberOfTokensToRefill(numTokens);
49  }
50 
52  {
53  if (m_intervalMs < 1) { return 0; }
54  return m_numTokensToRefill * 1000 / m_intervalMs;
55  }
56 
57  int CTokenBucket::getTokens(qint64 msSinceEpoch)
58  {
59  const qint64 now = msSinceEpoch > 0 ? msSinceEpoch : QDateTime::currentMSecsSinceEpoch();
60  const qint64 deltaMs = now - m_lastReplenishmentTime;
61  const int numberOfTokens = static_cast<int>(m_numTokensToRefill * deltaMs / m_intervalMs);
62 
63  // Update the time only when replenishment actually took place. We will end up in a infinite loop otherwise.
64  if (numberOfTokens > 0) { m_lastReplenishmentTime = now; }
65  return numberOfTokens;
66  }
67 } // namespace swift::misc
void setCapacityAndTokensToRefill(int numTokens)
Tokens/capacity if both are same.
Definition: tokenbucket.cpp:45
void setNumberOfTokensToRefill(int numTokens)
Number of tokens to refill.
Definition: tokenbucket.cpp:41
CTokenBucket(int capacity, qint64 intervalMs, int numTokensToRefill)
Constructor for given replenishment policy.
Definition: tokenbucket.cpp:10
bool tryConsume(int numTokens=1, qint64 msSinceEpoch=-1)
Try to consume a number of tokens.
Definition: tokenbucket.cpp:14
void setCapacity(int capacity)
Set the capacity.
Definition: tokenbucket.cpp:43
int getTokensPerSecond() const
Tokens per second.
Definition: tokenbucket.cpp:51
Free functions in swift::misc.