Esempio n. 1
0
/*
 * same as hist_check() in ratelimit.c but this one
 * only counts, no updates on the window ==> faster
 */
static inline int ALLOW_UNUSED hist_count(rl_pipe_t *pipe)
{
	/* Window ELement*/
	#define U2MILI(__usec__) (__usec__/1000)
	#define S2MILI(__sec__)  (__sec__ *1000)
	int i;
	int first_good_index;
	int rl_win_ms = rl_window_size * 1000;

	int count=0;

	unsigned long long now_total, start_total;

	struct timeval tv;

	gettimeofday(&tv, NULL);
	if (pipe->rwin.start_time.tv_sec == 0) {
		return 0;
	} 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);

		if (now_total - start_total >= 2*rl_win_ms) {
			/* nothing here; window is expired */
		} else if (now_total - start_total >= rl_win_ms) {
			first_good_index = ((((now_total - rl_win_ms) - start_total)
						/rl_slot_period + 1) + pipe->rwin.start_index) %
						pipe->rwin.window_size;

			count = 0;
			for (i=first_good_index; i != pipe->rwin.start_index;
											i=(i+1)%pipe->rwin.window_size)
				count += pipe->rwin.window[i];

		} else {
			/* count all of them; valid window */
			for (i=0; i < pipe->rwin.window_size; i++)
				count += pipe->rwin.window[i];
		}
	}
	return count;

	#undef U2MILI
	#undef S2MILI
}
Esempio n. 2
0
/**
 * the algorithm keeps a circular window of requests in a fixed size buffer
 *
 * @param pipe   containing the window
 * @param update whether or not to inc call number
 * @return number of calls in the window
 */
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 rl_win_ms = rl_window_size * 1000;


	unsigned long long now_total, start_total;

	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 */
		pipe->rwin.start_time = tv;
		pipe->rwin.start_index = 0;

		/* 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)
				pipe->rwin.window[i] = 0;

			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;

		} 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;
		}
	}

	/* count the total number of calls in the window */
	for (i=0; i < pipe->rwin.window_size; i++)
		pipe->counter += pipe->rwin.window[i];

	return pipe->counter > pipe->limit ? -1 : 1;

	#undef U2MILI
	#undef S2MILI
}