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 <sworley@cumulusnetworks.com>
This commit is contained in:
Stephen Worley 2019-08-12 11:27:09 -04:00
parent 62991a1167
commit 73a381871e
2 changed files with 35 additions and 17 deletions

View File

@ -387,29 +387,14 @@ unsigned int nexthop_level(struct nexthop *nexthop)
return rv; return rv;
} }
#define GATE_SIZE 4 /* Number of uint32_t words in struct g_addr */ /* Only hash word-sized things, let cmp do the rest. */
uint32_t nexthop_hash_quick(const struct nexthop *nexthop)
uint32_t nexthop_hash(const struct nexthop *nexthop)
{ {
uint32_t key = 0x45afe398; uint32_t key = 0x45afe398;
uint32_t gate_src_rmap_raw[GATE_SIZE * 3] = {};
key = jhash_3words(nexthop->type, nexthop->vrf_id, key = jhash_3words(nexthop->type, nexthop->vrf_id,
nexthop->nh_label_type, key); 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) { if (nexthop->nh_label) {
int labels = nexthop->nh_label->num_labels; int labels = nexthop->nh_label->num_labels;
int i = 0; int i = 0;
@ -442,6 +427,31 @@ uint32_t nexthop_hash(const struct nexthop *nexthop)
return key; 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, void nexthop_copy(struct nexthop *copy, const struct nexthop *nexthop,
struct nexthop *rparent) struct nexthop *rparent)
{ {

View File

@ -137,6 +137,14 @@ void nexthop_del_labels(struct nexthop *);
* 32-bit hash of nexthop * 32-bit hash of nexthop
*/ */
uint32_t nexthop_hash(const struct nexthop *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(const struct nexthop *nh1, const struct nexthop *nh2);
extern bool nexthop_same_no_labels(const struct nexthop *nh1, extern bool nexthop_same_no_labels(const struct nexthop *nh1,