]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Nest: Clist, EClist and LClist manipulation functions partially joined
authorJan Maria Matejka <mq@ucw.cz>
Thu, 7 Jun 2018 09:49:55 +0000 (11:49 +0200)
committerJan Maria Matejka <mq@ucw.cz>
Thu, 7 Jun 2018 09:49:55 +0000 (11:49 +0200)
The code was the same, just working with different amounts of data.

nest/a-set.c
nest/attrs.h

index 048e522db746c6be8a74c83a8dd175d5ae723387..69d337354526765a9c89ecd536587a6c3486ad77 100644 (file)
@@ -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);
-
-  * (u32 *) (res->data + len) = val;
-
-  return res;
-}
-
-struct adata *
-ec_set_add(struct linpool *pool, struct adata *list, u64 val)
-{
-  if (ec_set_contains(list, val))
-    return list;
-
-  int olen = list ? list->length : 0;
-  struct adata *res = lp_alloc(pool, sizeof(struct adata) + olen + 8);
-  res->length = olen + 8;
-
-  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);
-
-  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;
-}
+    memcpy(res->data, list->data, len);
 
-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];
-      }
+  memcpy(res->data + len, val, size * 4);
 
   return res;
 }
 
 struct adata *
-lc_set_del(struct linpool *pool, struct adata *list, lcomm val)
+set_del(struct linpool *pool, struct adata *list, u32 *val, int size)
 {
-  if (!lc_set_contains(list, val))
+  int pos = set_position(list, val, size);
+  if (pos == -1)
     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;
+  int len = list->length - 4*size;
+  struct adata *res = lp_alloc(pool, sizeof(struct adata) + len);
+  res->length = len;
 
-  for (i=0; i < len; i += 3)
-    if (! lc_match(l, i, val))
-      k = lc_copy(k, l+i);
+  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 *
-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;
 
index 102f378a9a9ca65c161f939212ab04fbcb05c9ac..7058924d82c0e2369509b01756740f53158f2686 100644 (file)
@@ -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);