Skip to content
Permalink
Browse files

Fix cps counting for the SBT algorithm

Credits shared with @razvancrainea for sorting out the issue and reworking the alg implementation.
  • Loading branch information
bogdan-iancu committed Mar 5, 2019
1 parent d722438 commit 732e3d6157f92f22ab8ad83d1e87d8beb4aa838e
Showing with 40 additions and 60 deletions.
  1. +40 −60 modules/ratelimit/ratelimit.c
@@ -493,79 +493,59 @@ static inline int hist_check(rl_pipe_t *pipe, int update)
#define U2MILI(__usec__) (__usec__/1000)
#define S2MILI(__sec__) (__sec__ *1000)
int i;
int first_good_index;
int now_index;
int rl_win_ms = rl_window_size * 1000;


unsigned long long now_total, start_total;
unsigned long long now_time, start_time;

struct timeval tv;

/* first get values from our beloved replicated friends
* current pipe counter will be calculated after this
* iteration; no need for the old one */
pipe->counter = 0;
pipe->counter = rl_get_all_counters(pipe);

gettimeofday(&tv, NULL);
if (pipe->rwin.start_time.tv_sec == 0) {
/* the lucky one to come first here */
now_time = S2MILI(tv.tv_sec) + U2MILI(tv.tv_usec);
now_index = (now_time%rl_win_ms) / rl_slot_period;

start_time = S2MILI(pipe->rwin.start_time.tv_sec)
+ U2MILI(pipe->rwin.start_time.tv_usec);

if ( (pipe->rwin.start_time.tv_sec == 0) || /* first run*/
(now_time - start_time >= rl_win_ms) ) { /* or more than one window */
LM_INFO("case 1 - start=%lld/%d, now=%lld/%d, diff=%lld\n",
start_time, pipe->rwin.start_index, now_time, now_index,
now_time-start_time);
memset(pipe->rwin.window, 0,
pipe->rwin.window_size * sizeof(long int));
pipe->rwin.start_time = tv;
pipe->rwin.start_index = 0;
pipe->rwin.start_index = now_index;
pipe->rwin.window[now_index] = update;

/* we know it starts from 0 because we did memset when created*/
pipe->rwin.window[pipe->rwin.start_index] += update;
} else {
start_total = S2MILI(pipe->rwin.start_time.tv_sec)
+ U2MILI(pipe->rwin.start_time.tv_usec);

now_total = S2MILI(tv.tv_sec) + U2MILI(tv.tv_usec);

/* didn't do any update to the window for "2*window_size" secs
* we can't use any elements from the vector
* the window is invalidated; very unlikely to happen*/
if (now_total - start_total >= 2*rl_win_ms) {
memset(pipe->rwin.window, 0,
pipe->rwin.window_size * sizeof(long int));

pipe->rwin.start_index = 0;
pipe->rwin.start_time = tv;
pipe->rwin.window[pipe->rwin.start_index] += update;
} else if (now_total - start_total >= rl_win_ms) {
/* current time in interval [window_size; 2*window_size)
* all the elements in [start_time; (ctime-window_size+1) are
* invalidated(set to 0)
* */
/* the first window index not to be set to 0
* number of slots from the start_index*/
first_good_index = ((((now_total - rl_win_ms) - start_total)
/rl_slot_period + 1) + pipe->rwin.start_index) %
pipe->rwin.window_size;

/* the new start time will be the start time of the first slot */
start_total = (now_total - rl_win_ms) -
(now_total - rl_win_ms)%rl_slot_period+ rl_slot_period;

pipe->rwin.start_time.tv_sec = start_total/1000;
pipe->rwin.start_time.tv_usec = (start_total%1000)*1000;


for (i=pipe->rwin.start_index; i != first_good_index;
i=(i+1)%pipe->rwin.window_size)
} else
if (now_time - start_time >= rl_slot_period) {
/* different slot */
LM_INFO("case 2 - start=%lld/%d, now=%lld/%d, diff=%lld\n",
start_time, pipe->rwin.start_index, now_time, now_index,
now_time-start_time);
/* zero the gap between old/start index and current/now index */
for ( i=(pipe->rwin.start_index+1)%pipe->rwin.window_size;
i != now_index;
i=(i+1)%pipe->rwin.window_size)
pipe->rwin.window[i] = 0;
/* update the time/index of the last counting */
pipe->rwin.start_time = tv;
pipe->rwin.start_index = now_index;

pipe->rwin.start_index = first_good_index;

/* count current call; it will be the last element in the window */
pipe->rwin.window[((pipe->rwin.start_index)
+ (pipe->rwin.window_size-1)) % pipe->rwin.window_size] += update;
/* count current call; it will be the last element in the window */
pipe->rwin.window[now_index] = update;

} else { /* now_total - start_total < rl_win_ms */
/* no need to modify the window, the value is inside it;
* we just need to increment the number of calls for
* the current slot*/
pipe->rwin.window[(now_total-start_total)/rl_slot_period] += update;
}
} else {
/* index the same slot */
/* we just need to increment the number of calls for
* the current slot*/
LM_INFO("case 3 - start=%lld/%d, now=%lld/%d, diff=%lld\n",
start_time, pipe->rwin.start_index, now_time, now_index,
now_time-start_time);
pipe->rwin.window[pipe->rwin.start_index] += update;
}

/* count the total number of calls in the window */

0 comments on commit 732e3d6

Please sign in to comment.
You can’t perform that action at this time.