diff options
Diffstat (limited to 'nest')
-rw-r--r-- | nest/a-set.c | 64 | ||||
-rw-r--r-- | nest/attrs.h | 2 |
2 files changed, 66 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; +} diff --git a/nest/attrs.h b/nest/attrs.h index 85e4e59a..42f81a10 100644 --- a/nest/attrs.h +++ b/nest/attrs.h @@ -96,6 +96,8 @@ 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 *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 *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); #endif |