summaryrefslogtreecommitdiff
path: root/lib/nexthop.c
diff options
context:
space:
mode:
authorStephen Worley <sworley@cumulusnetworks.com>2019-08-12 11:27:09 -0400
committerStephen Worley <sworley@cumulusnetworks.com>2019-10-25 11:13:42 -0400
commit73a381871edd64e841ee6040423cfaca25117b1f (patch)
tree2b96cb1127f490daab4b404350c2963febc4fcb3 /lib/nexthop.c
parent62991a11679da8912815c763980a505d1ad37ed7 (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.c44
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)
{