Greatly improve the rate limit algorithm, so it is correct for a low

ticket to period ratio.
This commit is contained in:
Nils O. Selåsdal
2013-10-15 15:03:27 +02:00
parent 41bb24bb61
commit 763032fb04
2 changed files with 19 additions and 27 deletions
+12 -16
View File
@@ -1,20 +1,17 @@
#include "ucore/rate_limit.h"
#define SCALE_FACTOR 1000
void uc_ratelimit_init(struct RateLimit *r, long tickets, long period, long current_ts)
{
r->tickets = tickets;
r->scaled_tickets = tickets * SCALE_FACTOR;
r->ticket_cost = tickets * period;
r->period = period;
r->available_tickets = r->scaled_tickets;
r->funds = r->ticket_cost * tickets;
r->last_ts = current_ts;
}
void uc_ratelimit_reset(struct RateLimit *r, long current_ts)
{
r->available_tickets = r->scaled_tickets;
r->funds = r->ticket_cost * r->tickets;
if (current_ts)
r->last_ts = current_ts;
@@ -36,22 +33,21 @@ int uc_ratelimit_allow(struct RateLimit *r, long current_ts)
diff_period = 0;
}
//Calculate the number of tickets that became available since
//Calculate the cost of tickets that became available since
//the last time.
r->available_tickets += diff_period *
(r->scaled_tickets / r->period);
r->funds += diff_period *
((r->tickets * r->ticket_cost) / r->period);
//throttle handing out tickets
//
if (r->available_tickets > r->scaled_tickets)
r->available_tickets = r->scaled_tickets;
if (r->funds > r->ticket_cost * r->tickets)
r->funds = r->ticket_cost * r->tickets;
//If we have at least one ticket, we can allow
if (r->available_tickets >= 1 * SCALE_FACTOR) {
r->available_tickets -= 1 * SCALE_FACTOR;
//If we have enough to buy atleast one ticket, we can allow
if (r->funds >= r->ticket_cost) {
r->funds -= r->ticket_cost;
allowed = 1;
} else {
//no more tickets.
//not enough to buy a ticket
allowed = 0;
}