diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2012-03-15 20:42:29 +0100 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2012-03-15 21:07:58 +0100 |
commit | 0888a737b045b48106edbd28ba3cd62fcc8c191e (patch) | |
tree | 5a9321e48934ede411e7f8b1bc2c947c0f2a3b7e /nest/a-set.c | |
parent | 9f1500f50a0196f912eeb97e77ccf6873e186c29 (diff) |
Extends set operations in filters.
Allows add/filter/delete clist on clist (set algebra on clists).
Allows number ~ bgppath match.
Diffstat (limited to 'nest/a-set.c')
-rw-r--r-- | nest/a-set.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/nest/a-set.c b/nest/a-set.c index 020d0978..42ef9b06 100644 --- a/nest/a-set.c +++ b/nest/a-set.c @@ -264,3 +264,67 @@ ec_set_del(struct linpool *pool, struct adata *list, u64 val) return res; } + + +struct adata * +int_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++) + 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; +} |