Commit 0e1fd7ea authored by Alexander Zubkov's avatar Alexander Zubkov Committed by Ondrej Zajicek (work)
Browse files

Filter: Add operators to find minimum and maximum element of sets



Add operators .min and .max to find minumum or maximum element in sets
of types: clist, eclist, lclist. Example usage:

bgp_community.min
bgp_ext_community.max
filter(bgp_large_community, [(as1, as2, *)]).min

Signed-off-by: default avatarAlexander Zubkov <green@qrator.net>
parent e15e4657
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -287,6 +287,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
	DEFINED,
	ADD, DELETE, CONTAINS, RESET,
	PREPEND, FIRST, LAST, LAST_NONAGGREGATED, MATCH,
	MIN, MAX,
	EMPTY,
	FILTER, WHERE, EVAL, ATTRIBUTE,
	BT_ASSERT, BT_TEST_SUITE, BT_CHECK_ASSIGN, BT_TEST_SAME, FORMAT)
@@ -800,6 +801,8 @@ term:
 | term '.' DATA { $$ = f_new_inst(FI_PAIR_DATA, $1); }
 | term '.' DATA1 { $$ = f_new_inst(FI_LC_DATA1, $1); }
 | term '.' DATA2 { $$ = f_new_inst(FI_LC_DATA2, $1); }
 | term '.' MIN  { $$ = f_new_inst(FI_MIN, $1); }
 | term '.' MAX  { $$ = f_new_inst(FI_MAX, $1); }

/* Communities */
/* This causes one shift/reduce conflict
+11 −0
Original line number Diff line number Diff line
@@ -68,6 +68,17 @@ f_type_name(enum f_type t)
  return "?";
}

enum f_type
f_type_element_type(enum f_type t)
{
  switch(t) {
    case T_CLIST:  return T_PAIR;
    case T_ECLIST: return T_EC;
    case T_LCLIST: return T_LC;
    default: return T_VOID;
  };
}

const struct f_val f_const_empty_path = {
  .type = T_PATH,
  .val.ad = &null_adata,
+2 −0
Original line number Diff line number Diff line
@@ -188,6 +188,8 @@ void trie_format(const struct f_trie *t, buffer *buf);

const char *f_type_name(enum f_type t);

enum f_type f_type_element_type(enum f_type t);

int val_same(const struct f_val *v1, const struct f_val *v2);
int val_compare(const struct f_val *v1, const struct f_val *v2);
void val_format(const struct f_val *v, buffer *buf);
+68 −0
Original line number Diff line number Diff line
@@ -983,6 +983,74 @@
    RESULT(T_INT, i, v1.val.lc.ldp2);
  }

  INST(FI_MIN, 1, 1) {	/* Get minimum element from set */
    ARG_ANY(1);
    RESULT_TYPE(f_type_element_type(v1.type));
    switch(v1.type)
    {
      case T_CLIST:
        {
          u32 val = 0;
          int_set_min(v1.val.ad, &val);
          RESULT_(T_PAIR, i, val);
        }
        break;

      case T_ECLIST:
        {
          u64 val = 0;
          ec_set_min(v1.val.ad, &val);
          RESULT_(T_EC, ec, val);
        }
        break;

      case T_LCLIST:
        {
          lcomm val = { 0, 0, 0 };
          lc_set_min(v1.val.ad, &val);
          RESULT_(T_LC, lc, val);
        }
        break;

      default:
        runtime( "Clist or lclist expected" );
    }
  }

  INST(FI_MAX, 1, 1) {	/* Get maximum element from set */
    ARG_ANY(1);
    RESULT_TYPE(f_type_element_type(v1.type));
    switch(v1.type)
    {
      case T_CLIST:
        {
          u32 val = 0;
          int_set_max(v1.val.ad, &val);
          RESULT_(T_PAIR, i, val);
        }
        break;

      case T_ECLIST:
        {
          u64 val = 0;
          ec_set_max(v1.val.ad, &val);
          RESULT_(T_EC, ec, val);
        }
        break;

      case T_LCLIST:
        {
          lcomm val = { 0, 0, 0 };
          lc_set_max(v1.val.ad, &val);
          RESULT_(T_LC, lc, val);
        }
        break;

      default:
        runtime( "Clist or lclist expected" );
    }
  }

  INST(FI_RETURN, 1, 1) {
    NEVER_CONSTANT;
    /* Acquire the return value */
+18 −0
Original line number Diff line number Diff line
@@ -781,6 +781,12 @@ clist r;
	r = filter(l, [(3,1), (*,2)]);
	bt_assert(r = add(add(-empty-, (3,1)), (3,2)));
	bt_assert(format(r) = "(clist (3,1) (3,2))");

	#  minimim & maximum element
	r = add(add(add(add(add(-empty-, (2,1)), (1,3)), (2,2)), (3,1)), (2,3));
	bt_assert(format(r) = "(clist (2,1) (1,3) (2,2) (3,1) (2,3))");
	bt_assert(r.min = (1,3));
	bt_assert(r.max = (3,1));
}

bt_test_suite(t_clist, "Testing lists of communities");
@@ -886,6 +892,12 @@ eclist r;
	r = filter(el, [(rt, 10, 1), (rt, 10, 25..30), (ro, 10, 40)]);
	bt_assert(r = add(add(--empty--, (rt, 10, 1)), (rt, 10, 30)));
	bt_assert(format(r) = "(eclist (rt, 10, 1) (rt, 10, 30))");

	#  minimim & maximum element
	r = add(add(add(add(add(--empty--, (rt, 2, 1)), (rt, 1, 3)), (rt, 2, 2)), (rt, 3, 1)), (rt, 2, 3));
	bt_assert(format(r) = "(eclist (rt, 2, 1) (rt, 1, 3) (rt, 2, 2) (rt, 3, 1) (rt, 2, 3))");
	bt_assert(r.min = (rt, 1, 3));
	bt_assert(r.max = (rt, 3, 1));
}

bt_test_suite(t_eclist, "Testing lists of extended communities");
@@ -995,6 +1007,12 @@ lclist r;
	r = filter(ll, [(5..15, *, *), (20, 15..25, *)]);
	bt_assert(r = add(add(---empty---, (10, 10, 10)), (20, 20, 20)));
	bt_assert(format(r) = "(lclist (10, 10, 10) (20, 20, 20))");

	#  minimim & maximum element
	r = add(add(add(add(add(---empty---, (2, 3, 3)), (1, 2, 3)), (2, 3, 1)), (3, 1, 2)), (2, 1, 3));
	bt_assert(format(r) = "(lclist (2, 3, 3) (1, 2, 3) (2, 3, 1) (3, 1, 2) (2, 1, 3))");
	bt_assert(r.min = (1, 2, 3));
	bt_assert(r.max = (3, 1, 2));
}

bt_test_suite(t_lclist, "Testing lists of large communities");
Loading