From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pd0-f176.google.com (mail-pd0-f176.google.com [209.85.192.176]) by dpdk.org (Postfix) with ESMTP id E2275C930 for ; Fri, 26 Jun 2015 18:49:50 +0200 (CEST) Received: by pdcu2 with SMTP id u2so78099327pdc.3 for ; Fri, 26 Jun 2015 09:49:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; bh=52rbzfFU80e0SBt5DXj+/SLu3RDWWWWofUlsF9lKVFA=; b=lih5KwYBHrhun4QD+u2VSDujNyXU8eIdft+es/pQ7+5m9pIerYPkCELlqQ1+8+hTI6 VXj3pysoaMEBcMYdQid/SvItB++BlKxmOZMCTDU/n2t+HObqlmo9qGx1L8UQFcJg2AsM lNlCEa6v9U7Zqp7v9y3p8pvrP9a8HLMYhlJ2clIqigwrIvimIrH7WLbIoopDCwf2qfLj KWWiTCJja4kgkmY3Qp3R5+pFPcacKCn4Orko2gLfOOtU7N2ekzZlt9YilrKB5gUL/TJv frrA34Wd1cNnRt8Tv2YtDbr/cn9CscoLMcf/flBBEea/kvUvv7c323BGpd6sMlzud8rH A2rA== X-Gm-Message-State: ALoCoQkWcOtSgvEoyfnzQN1uE3plVy6cX0PJEK4TlrH8lZK4lAMgRelc1/RioBAzF48KZYcOE1k1 X-Received: by 10.70.5.101 with SMTP id r5mr5084774pdr.139.1435337390286; Fri, 26 Jun 2015 09:49:50 -0700 (PDT) Received: from urahara (static-50-53-82-155.bvtn.or.frontiernet.net. [50.53.82.155]) by mx.google.com with ESMTPSA id z6sm1753093pdi.88.2015.06.26.09.49.49 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 26 Jun 2015 09:49:49 -0700 (PDT) Date: Fri, 26 Jun 2015 09:49:55 -0700 From: Stephen Hemminger To: Pablo de Lara Message-ID: <20150626094955.4a999f79@urahara> In-Reply-To: <1435269919-7007-9-git-send-email-pablo.de.lara.guarch@intel.com> References: <1433514804-7075-1-git-send-email-pablo.de.lara.guarch@intel.com> <1435269919-7007-1-git-send-email-pablo.de.lara.guarch@intel.com> <1435269919-7007-9-git-send-email-pablo.de.lara.guarch@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Cc: dev@dpdk.org Subject: Re: [dpdk-dev] [PATCH v2 08/11] hash: add new functionality to store data in hash table X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Jun 2015 16:49:51 -0000 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 --- 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;