* Add minor optimisations on speed when comparing with int_cmp(), uint_cmp(), u64_cmp(), by removing branching.
* Reorder type checks in val_compare() and val_in_range(). --- filter/filter.c | 64 ++++++++++++++++++++++++------------------------------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/filter/filter.c b/filter/filter.c index 0fc10f1..f92ee9a 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -112,25 +112,22 @@ pm_format(struct f_path_mask *p, byte *buf, unsigned int size) *buf = 0; } -static inline int int_cmp(int i1, int i2) +static inline int +int_cmp(int i1, int i2) { - if (i1 == i2) return 0; - if (i1 < i2) return -1; - else return 1; + return (i1 > i2) - (i1 < i2); } -static inline int uint_cmp(unsigned int i1, unsigned int i2) +static inline int +uint_cmp(unsigned int i1, unsigned int i2) { - if (i1 == i2) return 0; - if (i1 < i2) return -1; - else return 1; + return (i1 > i2) - (i1 < i2); } -static inline int u64_cmp(u64 i1, u64 i2) +static inline int +u64_cmp(u64 i1, u64 i2) { - if (i1 == i2) return 0; - if (i1 < i2) return -1; - else return 1; + return (i1 > i2) - (i1 < i2); } /** @@ -147,14 +144,11 @@ val_compare(struct f_val v1, struct f_val v2) { int rc; - if ((v1.type == T_VOID) && (v2.type == T_VOID)) - return 0; - if (v1.type == T_VOID) /* Hack for else */ - return -1; - if (v2.type == T_VOID) - return 1; - if (v1.type != v2.type) { + if (v1.type == T_VOID) /* Hack for else */ + return -1; + if (v2.type == T_VOID) + return 1; #ifndef IPV6 /* IP->Quad implicit conversion */ if ((v1.type == T_QUAD) && (v2.type == T_IP)) @@ -181,15 +175,13 @@ val_compare(struct f_val v1, struct f_val v2) case T_PREFIX: if (rc = ipa_compare(v1.val.px.ip, v2.val.px.ip)) return rc; - if (v1.val.px.len < v2.val.px.len) - return -1; - if (v1.val.px.len > v2.val.px.len) - return 1; - return 0; + return int_cmp(v1.val.px.len, v2.val.px.len); case T_PATH_MASK: return pm_path_compare(v1.val.path_mask, v2.val.path_mask); case T_STRING: return strcmp(v1.val.s, v2.val.s); + case T_VOID: + return 0; default: debug( "Compare of unknown entities: %x\n", v1.type ); return CMP_ERROR; @@ -408,18 +400,6 @@ val_in_range(struct f_val v1, struct f_val v2) if (res != CMP_ERROR) return res; - - if ((v1.type == T_PREFIX) && (v2.type == T_PREFIX_SET)) - return trie_match_fprefix(v2.val.ti, &v1.val.px); - - if ((v1.type == T_CLIST) && (v2.type == T_SET)) - return clist_match_set(v1.val.ad, v2.val.t); - - if ((v1.type == T_ECLIST) && (v2.type == T_SET)) - return eclist_match_set(v1.val.ad, v2.val.t); - - if ((v1.type == T_PATH) && (v2.type == T_SET)) - return as_path_match_set(v1.val.ad, v2.val.t); if (v2.type == T_SET) switch (v1.type) { @@ -436,7 +416,19 @@ val_in_range(struct f_val v1, struct f_val v2) return 0; return !! (val_simple_in_range(v1, n->from)); /* We turn CMP_ERROR into compared ok, and that's fine */ } + case T_PATH: + return as_path_match_set(v1.val.ad, v2.val.t); + case T_CLIST: + return clist_match_set(v1.val.ad, v2.val.t); + case T_ECLIST: + return eclist_match_set(v1.val.ad, v2.val.t); + } + else if (v2.type == T_PREFIX_SET) + switch (v1.type) { + case T_PREFIX: + return trie_match_fprefix(v2.val.ti, &v1.val.px); } + return CMP_ERROR; } -- 1.7.10.4