diff options
| author | Stephen Worley <sworley@cumulusnetworks.com> | 2019-08-12 11:27:09 -0400 | 
|---|---|---|
| committer | Stephen Worley <sworley@cumulusnetworks.com> | 2019-10-25 11:13:42 -0400 | 
| commit | 73a381871edd64e841ee6040423cfaca25117b1f (patch) | |
| tree | 2b96cb1127f490daab4b404350c2963febc4fcb3 /lib/nexthop.c | |
| parent | 62991a11679da8912815c763980a505d1ad37ed7 (diff) | |
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>
Diffstat (limited to 'lib/nexthop.c')
| -rw-r--r-- | lib/nexthop.c | 44 | 
1 files changed, 27 insertions, 17 deletions
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)  {  | 
