38 #ifndef included_clib_bitmap_h 39 #define included_clib_bitmap_h 53 for (i = 0; i <
vec_len (ai); i++)
66 for (i = 0; i <
vec_len (a); i++)
73 #define clib_bitmap_dup(v) vec_dup(v) 76 #define clib_bitmap_free(v) vec_free(v) 79 #define clib_bitmap_bytes(v) vec_bytes(v) 82 #define clib_bitmap_zero(v) vec_zero(v) 85 #define clib_bitmap_alloc(v,n_bits) \ 86 v = vec_new (uword, ((n_bits) + BITS (uword) - 1) / BITS (uword)) 88 #define clib_bitmap_vec_validate(v,i) vec_validate_aligned((v),(i),sizeof(uword)) 91 #define clib_bitmap_validate(v,n_bits) \ 92 clib_bitmap_vec_validate ((v), ((n_bits) - 1) / BITS (uword)) 96 _clib_bitmap_remove_trailing_zeros (
uword *
a)
101 for (i = _vec_len (a) - 1; i >= 0; i--)
104 _vec_len (a) = i + 1;
123 old_value = (ai & bit) != 0;
125 ai |= ((
uword) (new_value != 0)) << i1;
139 if (value == 0 && i0 >=
vec_len (ai))
145 a &= ~((
uword) 1 << i1);
146 a |= ((
uword) (value != 0)) << i1;
151 ai = _clib_bitmap_remove_trailing_zeros (ai);
162 return i0 < vec_len (ai) && 0 != ((ai[i0] >> i1) & 1);
174 return 0 != ((ai[i0] >> i1) & 1);
187 return 0 != ((ai[i0] >> i1) &
pow2_mask (n_bits));
194 uword i0, i1, result;
197 ASSERT (n_bits >= 0 && n_bits <=
BITS (result));
199 i0 = i /
BITS (bitmap[0]);
200 i1 = i %
BITS (bitmap[0]);
206 result |= (bitmap[i0] >> i1);
207 if (n_bits <
BITS (bitmap[0]))
208 result &= (((
uword) 1 << n_bits) - 1);
213 if (i1 + n_bits >
BITS (bitmap[0]) && i0 < l)
215 n_bits -=
BITS (bitmap[0]) - i1;
216 result |= (bitmap[i0] & (((
uword) 1 << n_bits) - 1)) << (
BITS (bitmap[0]) - i1);
228 uword i0, i1, l, t, m;
230 ASSERT (n_bits >= 0 && n_bits <=
BITS (value));
232 i0 = i /
BITS (bitmap[0]);
233 i1 = i %
BITS (bitmap[0]);
240 if (n_bits <
BITS (value))
241 m = (((
uword) 1 << n_bits) - 1);
252 if (i1 + n_bits >
BITS (bitmap[0]) && i0 < l)
254 t =
BITS (bitmap[0]) - i1;
258 m = ((
uword) 1 << n_bits) - 1;
274 a0 = i /
BITS (bitmap[0]);
275 a1 = i %
BITS (bitmap[0]);
278 b0 = i_end /
BITS (bitmap[0]);
291 for (a0++; a0 < b0; a0++)
292 bitmap[a0] = value ? ~0 : 0;
296 word n_bits_left = n_bits - (
BITS (bitmap[0]) - a1);
308 #define clib_bitmap_foreach(i,ai,body) \ 310 uword __bitmap_i, __bitmap_ai, __bitmap_len, __bitmap_first_set; \ 311 __bitmap_len = vec_len ((ai)); \ 312 for (__bitmap_i = 0; __bitmap_i < __bitmap_len; __bitmap_i++) \ 314 __bitmap_ai = (ai)[__bitmap_i]; \ 315 while (__bitmap_ai != 0) \ 317 __bitmap_first_set = first_set (__bitmap_ai); \ 318 (i) = (__bitmap_i * BITS ((ai)[0]) \ 319 + min_log2 (__bitmap_first_set)); \ 320 do { body; } while (0); \ 321 __bitmap_ai ^= __bitmap_first_set; \ 332 for (i = 0; i <
vec_len (ai); i++)
346 for (i = 0; i <
vec_len (ai); i++)
352 return i *
BITS (ai[0]);
361 for (i = 0; i <
vec_len (ai); i++)
367 #define _(name, body, check_zero) \ 368 always_inline uword * \ 369 clib_bitmap_##name (uword * ai, uword * bi) \ 371 uword i, a, b, bi_len, n_trailing_zeros; \ 373 n_trailing_zeros = 0; \ 374 bi_len = vec_len (bi); \ 376 clib_bitmap_vec_validate (ai, bi_len - 1); \ 377 for (i = 0; i < vec_len (ai); i++) \ 380 b = i < bi_len ? bi[i] : 0; \ 381 do { body; } while (0); \ 384 n_trailing_zeros = a ? 0 : (n_trailing_zeros + 1); \ 387 _vec_len (ai) -= n_trailing_zeros; \ 392 _ (and,
a =
a & b, 1)
393 _ (andnot,
a =
a &~ b, 1)
395 _ (xor,
a =
a ^ b, 1)
401 always_inline uword * \ 402 clib_bitmap_dup_##name (uword * ai, uword * bi) \ 403 { return clib_bitmap_##name (clib_bitmap_dup (ai), bi); } 413 #define _(name, body, check_zero) \ 414 always_inline uword * \ 415 clib_bitmap_##name (uword * ai, uword i) \ 417 uword i0 = i / BITS (ai[0]); \ 418 uword i1 = i % BITS (ai[0]); \ 420 clib_bitmap_vec_validate (ai, i0); \ 422 b = (uword) 1 << i1; \ 423 do { body; } while (0); \ 425 if (check_zero && a == 0) \ 426 ai = _clib_bitmap_remove_trailing_zeros (ai); \ 431 _ (andi,
a =
a & b, 1)
432 _ (andnoti,
a =
a &~ b, 1)
433 _ (ori,
a =
a | b, 0)
434 _ (xori,
a =
a ^ b, 1)
452 i0 = i /
BITS (ai[0]);
453 i1 = i %
BITS (ai[0]);
456 for (i = 0; i <= i0; i++)
459 for (n = 0; n <
BITS (ai[i]); n += log2_rand_max)
462 if (i1 + 1 <
BITS (ai[0]))
463 ai[i0] &= (((
uword) 1 << (i1 + 1)) - 1);
478 t = (ai[i0] >> i1) << i1;
482 for (i0++; i0 <
vec_len (ai); i0++)
503 t = (~ai[i0] >> i1) << i1;
507 for (i0++; i0 <
vec_len (ai); i0++)
521 uword ** bitmap_return = va_arg (* va,
uword **);
529 if (
unformat (input,
"%u-%u,", &a, &b))
531 else if (
unformat (input,
"%u,", &a))
533 else if (
unformat (input,
"%u-%u", &a, &b))
535 else if (
unformat (input,
"%u", &a))
548 for (i = a; i <= b; i++)
551 *bitmap_return = bitmap;
562 int i, is_trailing_zero = 1;
573 if (x && is_trailing_zero)
574 is_trailing_zero = 0;
576 if (x || !is_trailing_zero)
always_inline uword log2_first_set(uword x)
static u8 * format_bitmap_hex(u8 *s, va_list *args)
sll srl srl sll sra u16x4 i
always_inline uword clib_bitmap_count_set_bits(uword *ai)
always_inline uword clib_bitmap_get_multiple_no_check(uword *ai, uword i, uword n_bits)
#define vec_bytes(v)
Number of data bytes in vector.
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
always_inline uword clib_bitmap_is_equal(uword *a, uword *b)
always_inline uword clib_bitmap_next_clear(uword *ai, uword i)
always_inline uword clib_bitmap_first_set(uword *ai)
always_inline u32 random_u32(u32 *seed)
32-bit random number generator
always_inline uword count_set_bits(uword x)
always_inline uword clib_bitmap_set_no_check(uword *a, uword i, uword new_value)
always_inline uword clib_bitmap_first_clear(uword *ai)
always_inline uword * clib_bitmap_set(uword *ai, uword i, uword value)
always_inline uword clib_bitmap_get(uword *ai, uword i)
always_inline u32 random_u32_max(void)
Maximum value returned by random_u32()
#define clib_bitmap_vec_validate(v, i)
always_inline uword * clib_bitmap_set_multiple(uword *bitmap, uword i, uword value, uword n_bits)
always_inline uword * clib_bitmap_random(uword *ai, uword n_bits, u32 *seed)
#define clib_bitmap_free(v)
always_inline uword * clib_bitmap_set_region(uword *bitmap, uword i, uword value, uword n_bits)
always_inline uword clib_bitmap_is_zero(uword *ai)
always_inline uword clib_bitmap_get_no_check(uword *ai, uword i)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static uword unformat_bitmap_list(unformat_input_t *input, va_list *va)
Linear Congruential Random Number Generator.
always_inline uword clib_bitmap_get_multiple(uword *bitmap, uword i, uword n_bits)
always_inline uword min_log2(uword x)
always_inline uword pow2_mask(uword x)
always_inline uword clib_bitmap_next_set(uword *ai, uword i)
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".