summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
Diffstat (limited to 'nest')
-rw-r--r--nest/a-set.c64
-rw-r--r--nest/attrs.h2
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