From: Stephen Worley Date: Mon, 12 Aug 2019 15:27:09 +0000 (-0400) Subject: lib: Add nexthop quick hash api X-Git-Tag: base_7.3~219^2~36 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=73a381871edd64e841ee6040423cfaca25117b1f;p=mirror%2Ffrr.git lib: Add nexthop quick hash api Add a nexthop hashing api for only hashing on word-sized attributes. Calling the jhash/jhash2 function is quite slow in scaled envrionments but sometimes you do need a more granular hash. The tradeoff here is that hashtable buckets using this hash might be more full. Signed-off-by: Stephen Worley --- diff --git a/lib/nexthop.c b/lib/nexthop.c index 3f6d9ad711..0171318827 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -387,29 +387,14 @@ unsigned int nexthop_level(struct nexthop *nexthop) return rv; } -#define GATE_SIZE 4 /* Number of uint32_t words in struct g_addr */ - -uint32_t nexthop_hash(const struct nexthop *nexthop) +/* Only hash word-sized things, let cmp do the rest. */ +uint32_t nexthop_hash_quick(const struct nexthop *nexthop) { - uint32_t key = 0x45afe398; - uint32_t gate_src_rmap_raw[GATE_SIZE * 3] = {}; key = jhash_3words(nexthop->type, nexthop->vrf_id, nexthop->nh_label_type, key); - assert(((sizeof(nexthop->gate) + sizeof(nexthop->src) - + sizeof(nexthop->rmap_src)) - / 3) - == (GATE_SIZE * sizeof(uint32_t))); - - memcpy(gate_src_rmap_raw, &nexthop->gate, GATE_SIZE); - memcpy(gate_src_rmap_raw + GATE_SIZE, &nexthop->src, GATE_SIZE); - memcpy(gate_src_rmap_raw + (2 * GATE_SIZE), &nexthop->rmap_src, - GATE_SIZE); - - key = jhash2(gate_src_rmap_raw, (GATE_SIZE * 3), key); - if (nexthop->nh_label) { int labels = nexthop->nh_label->num_labels; int i = 0; @@ -442,6 +427,31 @@ uint32_t nexthop_hash(const struct nexthop *nexthop) return key; } + +#define GATE_SIZE 4 /* Number of uint32_t words in struct g_addr */ + +/* For a more granular hash */ +uint32_t nexthop_hash(const struct nexthop *nexthop) +{ + uint32_t gate_src_rmap_raw[GATE_SIZE * 3] = {}; + /* Get all the quick stuff */ + uint32_t key = nexthop_hash_quick(nexthop); + + assert(((sizeof(nexthop->gate) + sizeof(nexthop->src) + + sizeof(nexthop->rmap_src)) + / 3) + == (GATE_SIZE * sizeof(uint32_t))); + + memcpy(gate_src_rmap_raw, &nexthop->gate, GATE_SIZE); + memcpy(gate_src_rmap_raw + GATE_SIZE, &nexthop->src, GATE_SIZE); + memcpy(gate_src_rmap_raw + (2 * GATE_SIZE), &nexthop->rmap_src, + GATE_SIZE); + + key = jhash2(gate_src_rmap_raw, (GATE_SIZE * 3), key); + + return key; +} + void nexthop_copy(struct nexthop *copy, const struct nexthop *nexthop, struct nexthop *rparent) { diff --git a/lib/nexthop.h b/lib/nexthop.h index dfb30a1bce..480c4cc3dd 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -137,6 +137,14 @@ void nexthop_del_labels(struct nexthop *); * 32-bit hash of nexthop */ uint32_t nexthop_hash(const struct nexthop *nexthop); +/* + * Hash a nexthop only on word-sized attributes: + * - vrf_id + * - ifindex + * - type + * - (some) flags + */ +uint32_t nexthop_hash_quick(const struct nexthop *nexthop); extern bool nexthop_same(const struct nexthop *nh1, const struct nexthop *nh2); extern bool nexthop_same_no_labels(const struct nexthop *nh1,