1 /*
2    Copyright 2013-2014 EditShare, 2013-2015 Skytechnology sp. z o.o.
3 
4    This file is part of LizardFS.
5 
6    LizardFS is free software: you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation, version 3.
9 
10    LizardFS is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with LizardFS. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #pragma once
20 
21 #include "common/platform.h"
22 
23 #include "common/time_utils.h"
24 
25 /**
26  * TokenBucket is a rate limiter. It distributes 'budget_' resources among clients.
27  * Every nanosecond the available limit grows by 'rate_/(10^9)' resources, but only
28  * up to 'budgetCeil_' limit.
29  *
30  * If a client tries to reserve more resources than are available, it will be assigned
31  * everything that is currently available.
32  */
33 class TokenBucket {
34 public:
TokenBucket(SteadyTimePoint now)35 	TokenBucket(SteadyTimePoint now) : rate_(0), budget_(0), budgetCeil_(0), prevTime_(now) {}
36 
37 	// set rate, ceil and (optionally) budget
38 	void reconfigure(SteadyTimePoint now, double rate, double budgetCeil);
39 	void reconfigure(SteadyTimePoint now, double rate, double budgetCeil, double budget);
40 
41 	// getters
42 	double rate() const;
43 	double budgetCeil() const;
44 
45 	// Try to satisfy the request. Return 'cost' or less, but not less than 0. Require cost > 0
46 	double attempt(SteadyTimePoint now, double cost);
47 
48 private:
49 	void updateBudget(SteadyTimePoint now);
50 	void verifyClockSteadiness(SteadyTimePoint now);
51 
52 	double rate_;
53 	double budget_;
54 	double budgetCeil_;
55 
56 	SteadyTimePoint prevTime_;
57 };
58