F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
TokenBucket.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title TokenBucket.cpp
3 // \author vwong
4 // \brief cpp file for a rate limiter utility class
5 //
6 // \copyright
7 //
8 // Copyright (C) 2009-2020 California Institute of Technology.
9 //
10 // ALL RIGHTS RESERVED. United States Government Sponsorship
11 // acknowledged.
12 // ======================================================================
13 
14 #include <Utils/TokenBucket.hpp>
15 #include <algorithm>
16 
17 namespace Utils {
18 
19 TokenBucket ::TokenBucket(U32 replenishInterval, U32 maxTokens, U32 replenishRate, U32 startTokens, Fw::Time startTime)
20  : m_replenishInterval(replenishInterval),
21  m_maxTokens(maxTokens),
22  m_replenishRate(replenishRate),
23  m_tokens(startTokens),
24  m_time(startTime) {}
25 
26 TokenBucket ::TokenBucket(U32 replenishInterval, U32 maxTokens)
27  : m_replenishInterval(replenishInterval),
28  m_maxTokens(maxTokens),
29  m_replenishRate(1),
30  m_tokens(maxTokens),
31  m_time(0, 0) {
32  FW_ASSERT(this->m_maxTokens <= MAX_TOKEN_BUCKET_TOKENS, static_cast<FwAssertArgType>(this->m_maxTokens));
33 }
34 
35 void TokenBucket ::setReplenishInterval(U32 replenishInterval) {
36  this->m_replenishInterval = replenishInterval;
37 }
38 
39 void TokenBucket ::setMaxTokens(U32 maxTokens) {
40  this->m_maxTokens = maxTokens;
41 }
42 
43 void TokenBucket ::setReplenishRate(U32 replenishRate) {
44  this->m_replenishRate = replenishRate;
45 }
46 
48  if (this->m_tokens < this->m_maxTokens) {
49  this->m_tokens = this->m_maxTokens;
50  }
51 }
52 
54  return this->m_replenishInterval;
55 }
56 
58  return this->m_maxTokens;
59 }
60 
62  return this->m_replenishRate;
63 }
64 
66  return this->m_tokens;
67 }
68 
69 bool TokenBucket ::trigger(const Fw::Time time) {
70  // attempt replenishing
71  if (this->m_replenishRate > 0) {
72  // A stored time in another base (e.g. TB_NONE from the short constructor) is incomparable
73  // with the caller's time, so elapsed time is unknown: restart replenishment from this time
74  if (this->m_time.getTimeBase() != time.getTimeBase()) {
75  this->m_time = time;
76  }
77  const U32 intervalSeconds = this->m_replenishInterval / 1000000;
78  const U32 intervalUSeconds = this->m_replenishInterval % 1000000;
79  // Member add keeps the time base/context of m_time so nextTime stays comparable with time
80  Fw::Time nextTime = this->m_time;
81  nextTime.add(intervalSeconds, intervalUSeconds);
82  while (this->m_tokens < this->m_maxTokens && nextTime <= time) {
83  // replenish by replenish rate, or up to maxTokens
84  this->m_tokens += std::min(this->m_replenishRate, this->m_maxTokens - this->m_tokens);
85  this->m_time = nextTime;
86  nextTime.add(intervalSeconds, intervalUSeconds);
87  }
88  if (this->m_tokens >= this->m_maxTokens && this->m_time < time) {
89  this->m_time = time;
90  }
91  }
92 
93  // attempt consuming token
94  if (this->m_tokens > 0) {
95  this->m_tokens--;
96  return true;
97 
98  } else {
99  return false;
100  }
101 }
102 
103 } // end namespace Utils
void setReplenishInterval(U32 replenishInterval)
Definition: TokenBucket.cpp:35
U32 getReplenishRate() const
Definition: TokenBucket.cpp:61
#define MAX_TOKEN_BUCKET_TOKENS
Definition: TokenBucket.hpp:20
U32 getReplenishInterval() const
Definition: TokenBucket.cpp:53
TokenBucket(U32 replenishInterval, U32 maxTokens, U32 replenishRate, U32 startTokens, Fw::Time startTime)
Definition: TokenBucket.cpp:19
bool trigger(const Fw::Time time)
Definition: TokenBucket.cpp:69
TimeBase getTimeBase() const
Definition: Time.cpp:136
U32 getMaxTokens() const
Definition: TokenBucket.cpp:57
void setReplenishRate(U32 replenishRate)
Definition: TokenBucket.cpp:43
void setMaxTokens(U32 maxTokens)
Definition: TokenBucket.cpp:39
U32 getTokens() const
Definition: TokenBucket.cpp:65
static U32 min(const U32 a, const U32 b)
Definition: Checksum.cpp:16
static Time add(const Time &a, const Time &b)
Definition: Time.cpp:174
#define FW_ASSERT(...)
Definition: Assert.hpp:14