]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: Add nexthop quick hash api
authorStephen Worley <sworley@cumulusnetworks.com>
Mon, 12 Aug 2019 15:27:09 +0000 (11:27 -0400)
committerStephen Worley <sworley@cumulusnetworks.com>
Fri, 25 Oct 2019 15:13:42 +0000 (11:13 -0400)
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>
lib/nexthop.c
lib/nexthop.h

index 3f6d9ad71138e56f038d685eeae5290328acb603..017131882725fd3228e81618ddb97c069f8b6bd0 100644 (file)
@@ -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)
 {
index dfb30a1bcebadbe03de941c09260e25b564f9909..480c4cc3dd696091acd17d9b3696124cf0feb9d3 100644 (file)
@@ -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,