mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-08 12:18:42 +00:00
Lib: Extend MPLS label allocator bitmap
Add function lmap_last_one_in_range() for finding the last active label in a label range.
This commit is contained in:
parent
bcff3ae79a
commit
e338c4b63c
75
lib/bitmap.c
75
lib/bitmap.c
@ -398,6 +398,81 @@ lmap_first_zero_in_range(struct lmap *b, uint lo, uint hi)
|
|||||||
return hi;
|
return hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
b1024_last_one(u32 *p)
|
||||||
|
{
|
||||||
|
for (int i = 31; i >= 0; i--)
|
||||||
|
if (p[i])
|
||||||
|
return 32*i + (31 - u32_clz(p[i]));
|
||||||
|
|
||||||
|
return 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint
|
||||||
|
b1024_last_one_in_range(u32 *p, uint lo, uint hi)
|
||||||
|
{
|
||||||
|
uint lo0 = lo >> 5;
|
||||||
|
uint lo1 = lo & 0x1f;
|
||||||
|
uint hi0 = hi >> 5;
|
||||||
|
uint hi1 = hi & 0x1f;
|
||||||
|
u32 mask = (1u << hi1) - 1;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
for (int i = hi0; i > (int) lo0; i--)
|
||||||
|
{
|
||||||
|
val = p[i] & mask;
|
||||||
|
mask = ~0;
|
||||||
|
|
||||||
|
if (val)
|
||||||
|
return 32*i + (31 - u32_clz(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
mask &= ~((1u << lo1) - 1);
|
||||||
|
val = p[lo0] & mask;
|
||||||
|
|
||||||
|
if (val)
|
||||||
|
return 32*lo0 + (31 - u32_clz(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
return hi;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint
|
||||||
|
lmap_last_one_in_range(struct lmap *b, uint lo, uint hi)
|
||||||
|
{
|
||||||
|
uint lo0 = lo >> 10;
|
||||||
|
uint lo1 = lo & 0x3ff;
|
||||||
|
uint hi0 = hi >> 10;
|
||||||
|
uint hi1 = hi & 0x3ff;
|
||||||
|
|
||||||
|
if (hi1 && (hi0 < b->size) && b->data[hi0])
|
||||||
|
{
|
||||||
|
uint min = (lo0 == hi0) ? lo1 : 0;
|
||||||
|
uint n0 = hi0;
|
||||||
|
uint n1 = b1024_last_one_in_range(b->data[n0], min, hi1);
|
||||||
|
|
||||||
|
if (n1 < hi1)
|
||||||
|
return (n0 << 10) + n1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = (int)MIN(hi0, b->size) - 1; i >= (int) lo0; i--)
|
||||||
|
{
|
||||||
|
if (! b->data[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint n0 = i;
|
||||||
|
uint n1 = b1024_last_one(b->data[n0]);
|
||||||
|
|
||||||
|
if ((n0 == lo0) && (n1 < lo1))
|
||||||
|
return hi;
|
||||||
|
|
||||||
|
return (n0 << 10) + n1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hi;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
lmap_check(struct lmap *b)
|
lmap_check(struct lmap *b)
|
||||||
{
|
{
|
||||||
|
@ -79,6 +79,7 @@ void lmap_set(struct lmap *b, uint n);
|
|||||||
void lmap_clear(struct lmap *b, uint n);
|
void lmap_clear(struct lmap *b, uint n);
|
||||||
uint lmap_first_zero(struct lmap *b);
|
uint lmap_first_zero(struct lmap *b);
|
||||||
uint lmap_first_zero_in_range(struct lmap *b, uint lo, uint hi);
|
uint lmap_first_zero_in_range(struct lmap *b, uint lo, uint hi);
|
||||||
|
uint lmap_last_one_in_range(struct lmap *b, uint lo, uint hi);
|
||||||
void lmap_check(struct lmap *b);
|
void lmap_check(struct lmap *b);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -216,6 +216,18 @@ t_lmap_set_clear_fill(void)
|
|||||||
lmap_clear(&b, n);
|
lmap_clear(&b, n);
|
||||||
expected[n] = 0;
|
expected[n] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
n = lmap_last_one_in_range(&b, lo, hi);
|
||||||
|
bt_assert(n >= lo);
|
||||||
|
bt_assert(n <= hi);
|
||||||
|
|
||||||
|
for (last = n + 1; last < hi; last++)
|
||||||
|
bt_assert(!expected[last]);
|
||||||
|
|
||||||
|
if (n < hi)
|
||||||
|
bt_assert(expected[n]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint cnt = 0;
|
uint cnt = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user