From fee6bda064037b2abd0510241ac59d5358a7f684 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Fri, 25 Jan 2019 16:50:23 +0100 Subject: evaluate: remove anon sets with exactly one element Auto-replace lookups in single-element anon sets with a standard compare. 'add rule foo bar meta iif { "lo" }' gets replaced with 'add rule foo bar meta iif "lo"'. The former is a set lookup, the latter is a comparision. Comparisions are faster for the one-element case. Only prefixes, ranges and values are handled at this time. Anonymous maps are left alone, same for concatenations. Concatenations could be handled, but it would require more work: the concatenation would have to be replaced with a singleton value. Evaluation step rejects concat RHS on a relational expression. Signed-off-by: Florian Westphal --- src/evaluate.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/evaluate.c') diff --git a/src/evaluate.c b/src/evaluate.c index 384e2fa7..2ed68aad 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1455,8 +1455,25 @@ static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr) } } - if (ctx->set && (ctx->set->flags & NFT_SET_CONCAT)) - set->set_flags |= NFT_SET_CONCAT; + if (ctx->set) { + if (ctx->set->flags & NFT_SET_CONCAT) + set->set_flags |= NFT_SET_CONCAT; + } else if (set->size == 1) { + i = list_first_entry(&set->expressions, struct expr, list); + if (i->etype == EXPR_SET_ELEM) { + switch (i->key->etype) { + case EXPR_PREFIX: + case EXPR_RANGE: + case EXPR_VALUE: + *expr = i->key; + i->key = NULL; + expr_free(set); + return 0; + default: + break; + } + } + } set->set_flags |= NFT_SET_CONSTANT; -- cgit v1.2.3