Skip to content

Commit

Permalink
lib: Add nexthop quick hash api
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
sworleys committed Oct 25, 2019
1 parent 62991a1 commit 73a3818
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 17 deletions.
44 changes: 27 additions & 17 deletions lib/nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down
8 changes: 8 additions & 0 deletions lib/nexthop.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 73a3818

Please sign in to comment.