mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 07:31:54 +00:00
Nest: Clist, EClist and LClist manipulation functions partially joined
The code was the same, just working with different amounts of data.
This commit is contained in:
parent
e830f3a6f3
commit
7365219609
254
nest/a-set.c
254
nest/a-set.c
@ -181,56 +181,19 @@ lc_set_format(struct adata *set, int from, byte *buf, uint bufsize)
|
||||
}
|
||||
|
||||
int
|
||||
int_set_contains(struct adata *list, u32 val)
|
||||
set_position(struct adata *list, u32 *val, int skip)
|
||||
{
|
||||
if (!list)
|
||||
return 0;
|
||||
|
||||
u32 *l = (u32 *) list->data;
|
||||
int len = int_set_get_size(list);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (*l++ == val)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ec_set_contains(struct adata *list, u64 val)
|
||||
{
|
||||
if (!list)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
u32 *l = int_set_get_data(list);
|
||||
int len = int_set_get_size(list);
|
||||
u32 eh = ec_hi(val);
|
||||
u32 el = ec_lo(val);
|
||||
int i;
|
||||
int len = list->length / (skip * 4);
|
||||
|
||||
for (i=0; i < len; i += 2)
|
||||
if (l[i] == eh && l[i+1] == el)
|
||||
return 1;
|
||||
for (int i = 0; i < len; i++)
|
||||
if (!memcmp(&(l[i*skip]), val, skip * 4))
|
||||
return i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
lc_set_contains(struct adata *list, lcomm val)
|
||||
{
|
||||
if (!list)
|
||||
return 0;
|
||||
|
||||
u32 *l = int_set_get_data(list);
|
||||
int len = int_set_get_size(list);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i += 3)
|
||||
if (lc_match(l, i, val))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct adata *
|
||||
@ -255,217 +218,68 @@ int_set_prepend(struct linpool *pool, struct adata *list, u32 val)
|
||||
}
|
||||
|
||||
struct adata *
|
||||
int_set_add(struct linpool *pool, struct adata *list, u32 val)
|
||||
set_add(struct linpool *pool, struct adata *list, u32 *val, int size)
|
||||
{
|
||||
struct adata *res;
|
||||
int len;
|
||||
|
||||
if (int_set_contains(list, val))
|
||||
if (set_contains(list, val, size))
|
||||
return list;
|
||||
|
||||
len = list ? list->length : 0;
|
||||
res = lp_alloc(pool, sizeof(struct adata) + len + 4);
|
||||
res->length = len + 4;
|
||||
res = lp_alloc(pool, sizeof(struct adata) + len + size * 4);
|
||||
res->length = len + size * 4;
|
||||
|
||||
if (list)
|
||||
memcpy(res->data, list->data, list->length);
|
||||
memcpy(res->data, list->data, len);
|
||||
|
||||
* (u32 *) (res->data + len) = val;
|
||||
memcpy(res->data + len, val, size * 4);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct adata *
|
||||
ec_set_add(struct linpool *pool, struct adata *list, u64 val)
|
||||
set_del(struct linpool *pool, struct adata *list, u32 *val, int size)
|
||||
{
|
||||
if (ec_set_contains(list, val))
|
||||
int pos = set_position(list, val, size);
|
||||
if (pos == -1)
|
||||
return list;
|
||||
|
||||
int olen = list ? list->length : 0;
|
||||
struct adata *res = lp_alloc(pool, sizeof(struct adata) + olen + 8);
|
||||
res->length = olen + 8;
|
||||
int len = list->length - 4*size;
|
||||
struct adata *res = lp_alloc(pool, sizeof(struct adata) + len);
|
||||
res->length = len;
|
||||
|
||||
if (list)
|
||||
memcpy(res->data, list->data, list->length);
|
||||
|
||||
u32 *l = (u32 *) (res->data + olen);
|
||||
l[0] = ec_hi(val);
|
||||
l[1] = ec_lo(val);
|
||||
u32 *dest = int_set_get_data(res);
|
||||
u32 *src = int_set_get_data(list);
|
||||
memcpy(dest, src, size * pos);
|
||||
memcpy(dest + size * pos, src + size * (pos + 1), size * (len - pos));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct adata *
|
||||
lc_set_add(struct linpool *pool, struct adata *list, lcomm val)
|
||||
{
|
||||
if (lc_set_contains(list, val))
|
||||
return list;
|
||||
|
||||
int olen = list ? list->length : 0;
|
||||
struct adata *res = lp_alloc(pool, sizeof(struct adata) + olen + LCOMM_LENGTH);
|
||||
res->length = olen + LCOMM_LENGTH;
|
||||
|
||||
if (list)
|
||||
memcpy(res->data, list->data, list->length);
|
||||
|
||||
lc_put((u32 *) (res->data + olen), val);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct adata *
|
||||
int_set_del(struct linpool *pool, struct adata *list, u32 val)
|
||||
{
|
||||
if (!int_set_contains(list, val))
|
||||
return list;
|
||||
|
||||
struct adata *res;
|
||||
res = lp_alloc(pool, sizeof(struct adata) + list->length - 4);
|
||||
res->length = list->length - 4;
|
||||
|
||||
u32 *l = int_set_get_data(list);
|
||||
u32 *k = int_set_get_data(res);
|
||||
int len = int_set_get_size(list);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (l[i] != val)
|
||||
*k++ = l[i];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct adata *
|
||||
ec_set_del(struct linpool *pool, struct adata *list, u64 val)
|
||||
{
|
||||
if (!ec_set_contains(list, val))
|
||||
return list;
|
||||
|
||||
struct adata *res;
|
||||
res = lp_alloc(pool, sizeof(struct adata) + list->length - 8);
|
||||
res->length = list->length - 8;
|
||||
|
||||
u32 *l = int_set_get_data(list);
|
||||
u32 *k = int_set_get_data(res);
|
||||
int len = int_set_get_size(list);
|
||||
u32 eh = ec_hi(val);
|
||||
u32 el = ec_lo(val);
|
||||
int i;
|
||||
|
||||
for (i=0; i < len; i += 2)
|
||||
if (! (l[i] == eh && l[i+1] == el))
|
||||
{
|
||||
*k++ = l[i];
|
||||
*k++ = l[i+1];
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct adata *
|
||||
lc_set_del(struct linpool *pool, struct adata *list, lcomm val)
|
||||
{
|
||||
if (!lc_set_contains(list, val))
|
||||
return list;
|
||||
|
||||
struct adata *res;
|
||||
res = lp_alloc(pool, sizeof(struct adata) + list->length - LCOMM_LENGTH);
|
||||
res->length = list->length - LCOMM_LENGTH;
|
||||
|
||||
u32 *l = int_set_get_data(list);
|
||||
u32 *k = int_set_get_data(res);
|
||||
int len = int_set_get_size(list);
|
||||
int i;
|
||||
|
||||
for (i=0; i < len; i += 3)
|
||||
if (! lc_match(l, i, val))
|
||||
k = lc_copy(k, l+i);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct adata *
|
||||
int_set_union(struct linpool *pool, struct adata *l1, struct adata *l2)
|
||||
set_union(struct linpool *pool, struct adata *l1, struct adata *l2, int size)
|
||||
{
|
||||
if (!l1)
|
||||
return l2;
|
||||
if (!l2)
|
||||
return l1;
|
||||
|
||||
/* Filter out duplicit data from l2 */
|
||||
struct adata *res;
|
||||
int len = int_set_get_size(l2);
|
||||
int len = l2->length / (size * 4);
|
||||
u32 *l = int_set_get_data(l2);
|
||||
u32 tmp[len];
|
||||
u32 tmp[len*size];
|
||||
u32 *k = tmp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (!int_set_contains(l1, l[i]))
|
||||
*k++ = l[i];
|
||||
|
||||
if (k == tmp)
|
||||
return l1;
|
||||
|
||||
len = (k - tmp) * 4;
|
||||
res = lp_alloc(pool, sizeof(struct adata) + l1->length + len);
|
||||
res->length = l1->length + len;
|
||||
memcpy(res->data, l1->data, l1->length);
|
||||
memcpy(res->data + l1->length, tmp, len);
|
||||
return res;
|
||||
}
|
||||
|
||||
struct adata *
|
||||
ec_set_union(struct linpool *pool, struct adata *l1, struct adata *l2)
|
||||
{
|
||||
if (!l1)
|
||||
return l2;
|
||||
if (!l2)
|
||||
return l1;
|
||||
|
||||
struct adata *res;
|
||||
int len = int_set_get_size(l2);
|
||||
u32 *l = int_set_get_data(l2);
|
||||
u32 tmp[len];
|
||||
u32 *k = tmp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i += 2)
|
||||
if (!ec_set_contains(l1, ec_get(l, i)))
|
||||
{
|
||||
*k++ = l[i];
|
||||
*k++ = l[i+1];
|
||||
}
|
||||
|
||||
if (k == tmp)
|
||||
return l1;
|
||||
|
||||
len = (k - tmp) * 4;
|
||||
res = lp_alloc(pool, sizeof(struct adata) + l1->length + len);
|
||||
res->length = l1->length + len;
|
||||
memcpy(res->data, l1->data, l1->length);
|
||||
memcpy(res->data + l1->length, tmp, len);
|
||||
return res;
|
||||
}
|
||||
|
||||
struct adata *
|
||||
lc_set_union(struct linpool *pool, struct adata *l1, struct adata *l2)
|
||||
{
|
||||
if (!l1)
|
||||
return l2;
|
||||
if (!l2)
|
||||
return l1;
|
||||
|
||||
struct adata *res;
|
||||
int len = int_set_get_size(l2);
|
||||
u32 *l = int_set_get_data(l2);
|
||||
u32 tmp[len];
|
||||
u32 *k = tmp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i += 3)
|
||||
if (!lc_set_contains(l1, lc_get(l, i)))
|
||||
k = lc_copy(k, l+i);
|
||||
for (int i = 0; i < len; i++)
|
||||
if (!set_contains(l1, l + i*size, size))
|
||||
{
|
||||
memcpy(k, l + i*size, size * 4);
|
||||
k += size;
|
||||
}
|
||||
|
||||
/* Nothing to add */
|
||||
if (k == tmp)
|
||||
return l1;
|
||||
|
||||
|
66
nest/attrs.h
66
nest/attrs.h
@ -172,25 +172,65 @@ static inline int lc_match(const u32 *l, int i, lcomm v)
|
||||
static inline u32 *lc_copy(u32 *dst, const u32 *src)
|
||||
{ memcpy(dst, src, LCOMM_LENGTH); return dst + 3; }
|
||||
|
||||
|
||||
int int_set_format(struct adata *set, int way, int from, byte *buf, uint size);
|
||||
int ec_format(byte *buf, u64 ec);
|
||||
int ec_set_format(struct adata *set, int from, byte *buf, uint size);
|
||||
int lc_format(byte *buf, lcomm lc);
|
||||
int lc_set_format(struct adata *set, int from, byte *buf, uint size);
|
||||
int int_set_contains(struct adata *list, u32 val);
|
||||
int ec_set_contains(struct adata *list, u64 val);
|
||||
int lc_set_contains(struct adata *list, lcomm val);
|
||||
|
||||
int set_position(struct adata *list, u32 *val, int skip);
|
||||
static inline int set_contains(struct adata *list, u32 *val, int skip)
|
||||
{ return set_position(list, val, skip) != -1; }
|
||||
static inline int int_set_contains(struct adata *list, u32 val)
|
||||
{ return set_contains(list, &val, 1); }
|
||||
static inline int ec_set_contains(struct adata *list, u64 val)
|
||||
{
|
||||
u32 ec[2] = { ec_hi(val), ec_lo(val) };
|
||||
return set_contains(list, ec, 2);
|
||||
}
|
||||
static inline int lc_set_contains(struct adata *list, lcomm val)
|
||||
{
|
||||
u32 lc[3] = { val.asn, val.ldp1, val.ldp2 };
|
||||
return set_contains(list, lc, 3);
|
||||
}
|
||||
|
||||
struct adata *int_set_prepend(struct linpool *pool, struct adata *list, u32 val);
|
||||
struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val);
|
||||
struct adata *ec_set_add(struct linpool *pool, struct adata *list, u64 val);
|
||||
struct adata *lc_set_add(struct linpool *pool, struct adata *list, lcomm val);
|
||||
struct adata *int_set_del(struct linpool *pool, struct adata *list, u32 val);
|
||||
struct adata *ec_set_del(struct linpool *pool, struct adata *list, u64 val);
|
||||
struct adata *lc_set_del(struct linpool *pool, struct adata *list, lcomm val);
|
||||
struct adata *int_set_union(struct linpool *pool, struct adata *l1, struct adata *l2);
|
||||
struct adata *ec_set_union(struct linpool *pool, struct adata *l1, struct adata *l2);
|
||||
struct adata *lc_set_union(struct linpool *pool, struct adata *l1, struct adata *l2);
|
||||
|
||||
struct adata *set_add(struct linpool *pool, struct adata *list, u32 *val, int size);
|
||||
static inline struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val)
|
||||
{ return set_add(pool, list, &val, 1); };
|
||||
static inline struct adata *ec_set_add(struct linpool *pool, struct adata *list, u64 val)
|
||||
{
|
||||
u32 ec[2] = { ec_hi(val), ec_lo(val) };
|
||||
return set_add(pool, list, ec, 2);
|
||||
}
|
||||
static inline struct adata *lc_set_add(struct linpool *pool, struct adata *list, lcomm val)
|
||||
{
|
||||
u32 lc[3] = { val.asn, val.ldp1, val.ldp2 };
|
||||
return set_add(pool, list, lc, 3);
|
||||
}
|
||||
|
||||
struct adata *set_del(struct linpool *pool, struct adata *list, u32 *val, int size);
|
||||
static inline struct adata *int_set_del(struct linpool *pool, struct adata *list, u32 val)
|
||||
{ return set_del(pool, list, &val, 1); }
|
||||
static inline struct adata *ec_set_del(struct linpool *pool, struct adata *list, u64 val)
|
||||
{
|
||||
u32 ec[2] = { ec_hi(val), ec_lo(val) };
|
||||
return set_del(pool, list, ec, 2);
|
||||
}
|
||||
static inline struct adata *lc_set_del(struct linpool *pool, struct adata *list, lcomm val)
|
||||
{
|
||||
u32 lc[3] = { val.asn, val.ldp1, val.ldp2 };
|
||||
return set_del(pool, list, lc, 3);
|
||||
}
|
||||
|
||||
struct adata *set_union(struct linpool *pool, struct adata *l1, struct adata *l2, int size);
|
||||
static inline struct adata *int_set_union(struct linpool *pool, struct adata *l1, struct adata *l2)
|
||||
{ return set_union(pool, l1, l2, 1); }
|
||||
static inline struct adata *ec_set_union(struct linpool *pool, struct adata *l1, struct adata *l2)
|
||||
{ return set_union(pool, l1, l2, 2); }
|
||||
static inline struct adata *lc_set_union(struct linpool *pool, struct adata *l1, struct adata *l2)
|
||||
{ return set_union(pool, l1, l2, 3); }
|
||||
|
||||
struct adata *ec_set_del_nontrans(struct linpool *pool, struct adata *set);
|
||||
struct adata *int_set_sort(struct linpool *pool, struct adata *src);
|
||||
|
Loading…
Reference in New Issue
Block a user