We did same thing with a slightly different method.

Subject: rte_hash: split key and bucket size

It is useful to store more data in the has bucket than just the key size.
For example, storing an addresss and additional data.

Signed-off-by: Stephen Hemminger <stephen at networkplumber.org>


--- a/lib/librte_hash/rte_hash.h
+++ b/lib/librte_hash/rte_hash.h
@@ -78,7 +78,8 @@ struct rte_hash_parameters {
        const char *name;               /**< Name of the hash. */
        uint32_t entries;               /**< Total hash table entries. */
        uint32_t bucket_entries;        /**< Bucket entries. */
-       uint32_t key_len;               /**< Length of hash key. */
+       uint16_t key_len;               /**< Length of hash key. */
+       uint16_t cmp_len;               /**< Length of hash key compare 
(bytes). */
        rte_hash_function hash_func;    /**< Function used to calculate hash. */
        uint32_t hash_func_init_val;    /**< Init value used by hash_func. */
        int socket_id;                  /**< NUMA Socket ID for memory. */
@@ -89,7 +90,8 @@ struct rte_hash {
        char name[RTE_HASH_NAMESIZE];   /**< Name of the hash. */
        uint32_t entries;               /**< Total table entries. */
        uint32_t bucket_entries;        /**< Bucket entries. */
-       uint32_t key_len;               /**< Length of hash key. */
+       uint16_t key_len;               /**< Length of hash key. */
+       uint16_t cmp_len;               /**< Length of hash key compare (bytes) 
*/
        rte_hash_function hash_func;    /**< Function used to calculate hash. */
        uint32_t hash_func_init_val;    /**< Init value used by hash_func. */
        uint32_t num_buckets;           /**< Number of buckets in table. */
@@ -240,7 +242,7 @@ rte_hash_del_key_with_hash(const struct
  *     value that was returned when the key was added.
  */
 int32_t
-rte_hash_lookup(const struct rte_hash *h, const void *key);
+rte_hash_lookup(const struct rte_hash *h, void *key);

 /**
  * Find a key in the hash table. This operation is multi-thread safe.
@@ -260,7 +262,7 @@ rte_hash_lookup(const struct rte_hash *h
  */
 int32_t
 rte_hash_lookup_with_hash(const struct rte_hash *h,
-                               const void *key, hash_sig_t sig);
+                         void *key, hash_sig_t sig);


 /**
@@ -277,7 +279,7 @@ static inline hash_sig_t
 rte_hash_hash(const struct rte_hash *h, const void *key)
 {
        /* calc hash result by key */
-       return h->hash_func(key, h->key_len, h->hash_func_init_val);
+       return h->hash_func(key, h->cmp_len, h->hash_func_init_val);
 }

 #define rte_hash_lookup_multi rte_hash_lookup_bulk
--- a/lib/librte_hash/rte_hash.c
+++ b/lib/librte_hash/rte_hash.c
@@ -185,7 +185,8 @@ rte_hash_create(const struct rte_hash_pa
                        !rte_is_power_of_2(params->entries) ||
                        !rte_is_power_of_2(params->bucket_entries) ||
                        (params->key_len == 0) ||
-                       (params->key_len > RTE_HASH_KEY_LENGTH_MAX)) {
+                       (params->key_len > RTE_HASH_KEY_LENGTH_MAX)||
+                       (params->cmp_len > params->key_len)) {
                rte_errno = EINVAL;
                RTE_LOG(ERR, HASH, "rte_hash_create has invalid parameters\n");
                return NULL;
@@ -238,6 +239,7 @@ rte_hash_create(const struct rte_hash_pa
        h->entries = params->entries;
        h->bucket_entries = params->bucket_entries;
        h->key_len = params->key_len;
+       h->cmp_len = params->cmp_len ? params->cmp_len : h->key_len;
        h->hash_func_init_val = params->hash_func_init_val;
        h->num_buckets = num_buckets;
        h->bucket_bitmask = h->num_buckets - 1;
@@ -310,7 +312,7 @@ __rte_hash_add_key_with_hash(const struc
        for (i = 0; i < h->bucket_entries; i++) {
                if ((sig == sig_bucket[i]) &&
                    likely(memcmp(key, get_key_from_bucket(h, key_bucket, i),
-                                 h->key_len) == 0)) {
+                                 h->cmp_len) == 0)) {
                        return bucket_index * h->bucket_entries + i;
                }
        }
@@ -360,7 +362,7 @@ __rte_hash_del_key_with_hash(const struc
        for (i = 0; i < h->bucket_entries; i++) {
                if ((sig == sig_bucket[i]) &&
                    likely(memcmp(key, get_key_from_bucket(h, key_bucket, i),
-                                 h->key_len) == 0)) {
+                                 h->cmp_len) == 0)) {
                        sig_bucket[i] = NULL_SIGNATURE;
                        return bucket_index * h->bucket_entries + i;
                }
@@ -386,7 +388,7 @@ rte_hash_del_key(const struct rte_hash *

 static inline int32_t
 __rte_hash_lookup_with_hash(const struct rte_hash *h,
-                       const void *key, hash_sig_t sig)
+                           void *key, hash_sig_t sig)
 {
        hash_sig_t *sig_bucket;
        uint8_t *key_bucket;
@@ -402,7 +404,9 @@ __rte_hash_lookup_with_hash(const struct
        for (i = 0; i < h->bucket_entries; i++) {
                if ((sig == sig_bucket[i]) &&
                    likely(memcmp(key, get_key_from_bucket(h, key_bucket, i),
-                                 h->key_len) == 0)) {
+                                 h->cmp_len) == 0)) {
+                       rte_memcpy(key, get_key_from_bucket(h, key_bucket, i),
+                                  h->key_len);
                        return bucket_index * h->bucket_entries + i;
                }
        }
@@ -412,14 +416,14 @@ __rte_hash_lookup_with_hash(const struct

 int32_t
 rte_hash_lookup_with_hash(const struct rte_hash *h,
-                       const void *key, hash_sig_t sig)
+                         void *key, hash_sig_t sig)
 {
        RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
        return __rte_hash_lookup_with_hash(h, key, sig);
 }

 int32_t
-rte_hash_lookup(const struct rte_hash *h, const void *key)
+rte_hash_lookup(const struct rte_hash *h, void *key)
 {
        RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
        return __rte_hash_lookup_with_hash(h, key, rte_hash_hash(h, key));
@@ -438,7 +442,7 @@ rte_hash_lookup_bulk(const struct rte_ha

        /* Get the hash signature and bucket index */
        for (i = 0; i < num_keys; i++) {
-               sigs[i] = h->hash_func(keys[i], h->key_len,
+               sigs[i] = h->hash_func(keys[i], h->cmp_len,
                                h->hash_func_init_val) | h->sig_msb;
                bucket_index = sigs[i] & h->bucket_bitmask;

@@ -459,7 +463,7 @@ rte_hash_lookup_bulk(const struct rte_ha
                        if ((sigs[i] == sig_bucket[j]) &&
                            likely(memcmp(keys[i],
                                          get_key_from_bucket(h, key_bucket, j),
-                                         h->key_len) == 0)) {
+                                         h->cmp_len) == 0)) {
                                positions[i] = bucket_index *
                                        h->bucket_entries + j;
                                break;

Reply via email to