#define __THROTTLE_H__
#include <vlib/vlib.h>
+#include <vppinfra/xxhash.h>
/**
* @brief A throttle
* Used in the data plane to decide if a given hash should be throttled,
- * i.e. that the hash has been seen alreay 'recently'. Recent is the time
+ * i.e. that the hash has been seen already 'recently'. Recent is the time
* given in the throttle's initialisation.
*/
typedef struct throttle_t_
{
f64 time;
uword **bitmaps;
- u32 *seeds;
+ u64 *seeds;
f64 *last_seed_change_time;
+ u32 buckets;
} throttle_t;
#define THROTTLE_BITS (512)
-extern void throttle_init (throttle_t * t, u32 n_threads, f64 time);
+extern void throttle_init (throttle_t *t, u32 n_threads, u32 buckets,
+ f64 time);
-always_inline u32
+always_inline u64
throttle_seed (throttle_t * t, u32 thread_index, f64 time_now)
{
if (time_now - t->last_seed_change_time[thread_index] > t->time)
{
- (void) random_u32 (&t->seeds[thread_index]);
- memset (t->bitmaps[thread_index], 0, THROTTLE_BITS / BITS (u8));
+ (void) random_u64 (&t->seeds[thread_index]);
+ clib_bitmap_zero (t->bitmaps[thread_index]);
t->last_seed_change_time[thread_index] = time_now;
}
}
always_inline int
-throttle_check (throttle_t * t, u32 thread_index, u32 hash, u32 seed)
+throttle_check (throttle_t * t, u32 thread_index, u64 hash, u64 seed)
{
- int drop;
- uword m;
- u32 w;
+ ASSERT (is_pow2 (t->buckets));
- hash ^= seed;
- /* Select bit number */
- hash &= THROTTLE_BITS - 1;
- w = hash / BITS (uword);
- m = (uword) 1 << (hash % BITS (uword));
+ hash = clib_xxhash (hash ^ seed);
- drop = (t->bitmaps[thread_index][w] & m) != 0;
- t->bitmaps[thread_index][w] |= m;
+ /* Select bit number */
+ hash &= t->buckets - 1;
- return (drop);
+ return clib_bitmap_set_no_check (t->bitmaps[thread_index], hash, 1);
}
#endif