Marine Library  1.0
C++ library for Linux Networking Development
freq_control.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Zhao DAI <daidodo@gmail.com>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or any
7  * later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see accompanying file LICENSE.txt
16  * or <http://www.gnu.org/licenses/>.
17  */
18 
25 #ifndef DOZERG_FREQ_CONTROL_H_20120224
26 #define DOZERG_FREQ_CONTROL_H_20120224
27 
28 #include "tools/time.hh" //MonoTimeUs
29 
30 NS_SERVER_BEGIN
31 
43 {
49  : freq_(0)
50  , buckSz_(0)
51  , token_(0)
52  , delta_(0)
53  , time_(0)
54  {}
62  CFreqControl(size_t freq, size_t bucketSz)
63  : freq_(0)
64  , buckSz_(0)
65  , token_(0)
66  , delta_(0)
67  , time_(0)
68  {
69  init(freq, bucketSz);
70  }
71  void init(size_t freq, size_t bucketSz){
72  if(!freq_){
73  token_ = delta_ = 0;
74  time_ = tools::MonoTimeUs();
75  }
76  freq_ = freq;
77  buckSz_ = bucketSz;
78  }
84  void generate(uint64_t nowUs = 0){
85  if(!valid())
86  return;
87  if(nowUs < time_)
88  nowUs = tools::MonoTimeUs();
89  if(nowUs > time_){
90  delta_ += freq_ * (nowUs - time_);
91  if(delta_ < 0){
92  delta_ = 0; //overflow
93  token_ = buckSz_;
94  }else{
95  ssize_t tok = delta_ / 1000000 + token_;
96  delta_ %= 1000000;
97  if(tok < token_ || tok > ssize_t(buckSz_))
98  tok = buckSz_; //overflow
99  token_ = tok;
100  }
101  }
102  time_ = nowUs;
103  }
109  bool check(size_t need) const{return (token_ >= 0 && size_t(token_) >= need);}
118  ssize_t token() const{return token_;}
126  bool get(size_t need = 1){
127  if(token_ < 0 || size_t(token_) < need)
128  return false;
129  token_ -= need;
130  return true;
131  }
139  bool overdraw(size_t need){
140  if(!valid() || ssize_t(need) < 0)
141  return false;
142  token_ -= need;
143  return true;
144  }
145 private:
146  bool valid() const {return freq_ > 0;}
147  size_t freq_;
148  size_t buckSz_;
149  ssize_t token_;
150  ssize_t delta_;
151  uint64_t time_; //last generate() time
152 };
153 
170 {
177  explicit CWideFreqControl(double freq = 0){
178  init(freq);
179  }
180  void init(double freq){
181  time_ = tools::MonoTimeUs();
182  token_ = 0;
183  freq_ = std::max(0., freq);
184  }
192  bool get(){
193  if(getAux())
194  return true;
195  uint64_t now = tools::MonoTimeUs();
196  if(time_ < now)
197  token_ += freq_ * (now - time_) / 1000000;
198  if(token_ > freq_ + 1)
199  token_ = freq_ + 1;
200  time_ = now;
201  return getAux();
202  }
203 private:
204  bool getAux(){
205  if(token_ < 1)
206  return false;
207  --token_;
208  return true;
209  }
210  uint64_t time_;
211  double token_;
212  double freq_;
213 };
214 
215 NS_SERVER_END
216 
217 #endif
218 
void init(double freq)
Initialize this object.
Definition: freq_control.hh:180
Rate limiting for high frequency (>1Hz) jobs.
Definition: freq_control.hh:42
bool overdraw(size_t need)
Overdraw tokens.
Definition: freq_control.hh:139
bool check(size_t need) const
Check if there are enough tokens.
Definition: freq_control.hh:109
CFreqControl(size_t freq, size_t bucketSz)
Initialize this object.
Definition: freq_control.hh:62
void init(size_t freq, size_t bucketSz)
Initialize this object.
Definition: freq_control.hh:71
CFreqControl()
Default constructor.
Definition: freq_control.hh:48
CWideFreqControl(double freq=0)
Initialize this object.
Definition: freq_control.hh:177
Rate limiting for any frequency, including ones less than 1Hz.
Definition: freq_control.hh:169
ssize_t token() const
Get number of tokens in bucket.
Definition: freq_control.hh:118
void generate(uint64_t nowUs=0)
Generate tokens.
Definition: freq_control.hh:84