Merge branch 'dev' of /var/lib/git/libucore into dev
This commit is contained in:
+39
-38
@@ -1,18 +1,18 @@
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include "ucore/rate_limit.h"
|
||||
|
||||
void uc_ratelimit_init(struct RateLimit *r, long tickets, long period, long current_ts)
|
||||
void uc_ratelimit_init(struct RateLimit *r, long tickets, long period)
|
||||
{
|
||||
r->tickets = tickets;
|
||||
|
||||
r->period = period;
|
||||
r->funds = r->period * tickets;
|
||||
r->last_ts = current_ts;
|
||||
r->funds = 0; //we fill it on first _allow call
|
||||
r->last_ts = -period; //-period ensures the first tick can start
|
||||
//at >= 0 and still refill the bicket
|
||||
|
||||
assert(tickets > 0);
|
||||
assert(period > 0);
|
||||
assert(r->period > 0);
|
||||
assert(r->funds > 0);
|
||||
}
|
||||
|
||||
void uc_ratelimit_reset(struct RateLimit *r, long current_ts)
|
||||
@@ -29,43 +29,44 @@ int uc_ratelimit_allow(struct RateLimit *r, long current_ts)
|
||||
int allowed;
|
||||
long diff_period;
|
||||
|
||||
//Find elapsed time
|
||||
diff_period = current_ts - r->last_ts;
|
||||
|
||||
if (diff_period > r->period + 1) {
|
||||
//help prevent overflow when calculating available_tickets below
|
||||
diff_period = r->period + 1;
|
||||
} else if (diff_period < 0) {
|
||||
//If time went backwards, we halt the time for this round
|
||||
diff_period = 0;
|
||||
}
|
||||
|
||||
//Calculate the cost of tickets that became available since
|
||||
//the last time.
|
||||
r->funds += diff_period * r->tickets;
|
||||
|
||||
//the below is the real algorithm, with period =
|
||||
//tickets * period.
|
||||
//we have optimized this to the expression used above
|
||||
//r->funds += diff_period *
|
||||
// ((r->tickets * r->period) / r->period);
|
||||
|
||||
//throttle handing out tickets
|
||||
if (r->funds > r->period * r->tickets) {
|
||||
r->funds = r->period * r->tickets;
|
||||
}
|
||||
|
||||
//If we have enough to buy atleast one ticket, we can allow
|
||||
if (r->funds >= r->period) {
|
||||
if (r->funds >= r->period) {
|
||||
//we have enough
|
||||
r->funds -= r->period;
|
||||
allowed = 1;
|
||||
} else {
|
||||
//not enough to buy a ticket
|
||||
allowed = 0;
|
||||
} else { //refill
|
||||
//Find elapsed time
|
||||
diff_period = current_ts - r->last_ts;
|
||||
|
||||
if (diff_period > r->period + 1) {
|
||||
//help prevent overflow when calculating available_tickets below
|
||||
diff_period = r->period + 1;
|
||||
} else if (diff_period < 0) {
|
||||
//time went backwards, skip this round
|
||||
diff_period = 0;
|
||||
}
|
||||
|
||||
//Calculate the cost of tickets that became available
|
||||
r->funds += diff_period * r->tickets;
|
||||
|
||||
|
||||
//throttle handing out tickets
|
||||
if (r->funds > r->period * r->tickets) {
|
||||
r->funds = r->period * r->tickets;
|
||||
}
|
||||
|
||||
//If we have enough to buy atleast one ticket, we can allow
|
||||
if (r->funds >= r->period) {
|
||||
r->funds -= r->period;
|
||||
allowed = 1;
|
||||
} else {
|
||||
//not enough to buy a ticket
|
||||
allowed = 0;
|
||||
}
|
||||
|
||||
//save this period.
|
||||
r->last_ts = current_ts;
|
||||
}
|
||||
|
||||
//save this period.
|
||||
r->last_ts = current_ts;
|
||||
|
||||
return allowed;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user