Perhaps a generic hash table APIs (not cuckoo hash) could be put in the main APIs?
> 在 2016年4月6日,下午10:18,Ru Jia <ji...@ict.ac.cn> 写道: > > Last year, there was a discussion about cuckoo hash. I saw the last reply > (https://lists.linaro.org/pipermail/lng-odp/2015-December/017921.html > <https://lists.linaro.org/pipermail/lng-odp/2015-December/017921.html>). > > You recommended to: > “ > 1) have this code with queues api; > 2) remove ring code completely from helper > 3) move ring code inside linux-generic (I will reuse it for shm pktio ipc); > 4) test performance of cuckoo hash > 5) move it to odp hash API when it will be ready (to do that code should > not use other helper code, just native odp apis). > ” > > Now I find a ring structure in platform/linux-generic/pktio, so I use it to > implement cuckoo hash. Then as the 5th point, I put it into odp apis. > > So, where should cuckoo hash be? > > And if it’s need to move cuckoo hash into helper, do I need to use odp_queue > to implement it? > 发件人: Mike Holmes [mailto:mike.hol...@linaro.org] > 发送时间: 2016年4月6日 19:43 > 收件人: Ru Jia > 抄送: lng-odp; hep...@ict.ac.cn > 主题: Re: [lng-odp] [API-NEXT PATCH 1/3] api: add cuckoo hash api > > Thank you for the patch > > Remember that if there is a new API added we also need good validation test > coverage in test/validation for it to be accepted eventually into master. > > The performance test is a really good thing to have but we need a cunit test > case to help platforms ensure that they all operate the same way for a given > release. > > Is there a reason this is not a helper rather than an odp API like the other > hashtable support, can this be HW accelerated ? > > > Mike > > On 6 April 2016 at 06:02, Ru Jia <ji...@ict.ac.cn <mailto:ji...@ict.ac.cn>> > wrote: >> Added cuckoo hash api, which is an efficient hash table. It could >> be used for many algorithms. >> >> Signed-off-by: Ru Jia <ji...@ict.ac.cn <mailto:ji...@ict.ac.cn>> >> --- >> include/odp/api/spec/cuckoo_hash.h | 463 >> +++++++++++++++++++++ >> include/odp_api.h | 1 + >> .../linux-generic/include/odp/api/cuckoo_hash.h | 34 ++ >> 3 files changed, 498 insertions(+) >> create mode 100644 include/odp/api/spec/cuckoo_hash.h >> create mode 100644 platform/linux-generic/include/odp/api/cuckoo_hash.h >> >> diff --git a/include/odp/api/spec/cuckoo_hash.h >> b/include/odp/api/spec/cuckoo_hash.h >> new file mode 100644 >> index 0000000..ca147ce >> --- /dev/null >> +++ b/include/odp/api/spec/cuckoo_hash.h >> @@ -0,0 +1,463 @@ >> +/* Copyright (c) 2015, Linaro Limited >> + * All rights reserved. >> + * >> + * SPDX-License-Identifier: BSD-3-Clause >> + */ >> + >> +/*- >> + * BSD LICENSE >> + * >> + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. >> + * All rights reserved. >> + * >> + * Redistribution and use in source and binary forms, with or without >> + * modification, are permitted provided that the following conditions >> + * are met: >> + * >> + * * Redistributions of source code must retain the above copyright >> + * notice, this list of conditions and the following disclaimer. >> + * * Redistributions in binary form must reproduce the above copyright >> + * notice, this list of conditions and the following disclaimer in >> + * the documentation and/or other materials provided with the >> + * distribution. >> + * * Neither the name of Intel Corporation nor the names of its >> + * contributors may be used to endorse or promote products derived >> + * from this software without specific prior written permission. >> + * >> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT >> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR >> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT >> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, >> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT >> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >> + */ >> + >> +#ifndef ODP_API_CUCKOO_HASH_H_ >> +#define ODP_API_CUCKOO_HASH_H_ >> + >> +#include <odp/api/shared_memory.h> >> +#include <odp/api/hash.h> >> +#include <odp/api/align.h> >> +#include <odp/api/std_types.h> >> + >> +/** >> + * @file >> + * >> + * ODP Cuckoo Hash Table Implementation >> + */ >> + >> +#ifdef __cplusplus >> +extern "C" { >> +#endif >> + >> +/** Maximum number of characters in hash name.*/ >> +#define ODP_CUCKOO_HASH_NAMESIZE 32 >> + >> +/* More efficient access to a map of single ullong */ >> +#define ULLONG_FOR_EACH_1(IDX, MAP) \ >> + for (; MAP && (((IDX) = __builtin_ctzll(MAP)), true); \ >> + MAP = (MAP & (MAP - 1))) >> + >> +typedef struct _ring _ring_t; >> + >> +/** >> + * @typedef odp_hash_function >> + * odp hash function >> + */ >> +typedef uint32_t (*odp_cuckoo_hash_func_t)( >> + const void *key, uint32_t data_len, >> + uint32_t init_val); >> + >> +/** >> + * @typedef odp_hash_cmp_eq_t >> + * odp hash compare function >> + */ >> +typedef int (*odp_cuckoo_hash_cmp_eq_t)( >> + const void *key1, >> + const void *key2, size_t data_len); >> + >> +/** A hash table structure. */ >> +typedef struct odp_cuckoo_hash_tbl { >> + /**< Name of the hash. */ >> + char name[ODP_CUCKOO_HASH_NAMESIZE]; >> + /**< Total table entries. */ >> + uint32_t entries; >> + /**< Number of buckets in table. */ >> + uint32_t num_buckets; >> + /**< Length of hash key. */ >> + uint32_t key_len; >> + /**< Function used by hash_func */ >> + odp_cuckoo_hash_func_t hash_func; >> + /**< Init value used by hash_func. */ >> + uint32_t hash_func_init_val; >> + /**< Function used to compare keys. */ >> + odp_cuckoo_hash_cmp_eq_t hash_cmp_eq; >> + /**< Bitmask for getting bucket index from hash signature. */ >> + uint32_t bucket_bitmask; >> + /**< Size of each key entry. */ >> + uint32_t key_entry_size; >> + /**< Ring that stores all indexes of the free slots in the key table >> */ >> + _ring_t *free_slots; >> + /**< Table storing all keys and data */ >> + void *key_store; >> + /** Table with buckets storing all the hash values and key indexes >> + to the key table*/ >> + struct cuckoo_hash_bucket *buckets; >> + /** memory used to store keys*/ >> + odp_shm_t shm_key; >> + /** memory used to store buckets*/ >> + odp_shm_t shm_bucket; >> +} odp_cuckoo_hash_tbl_t ODP_ALIGNED_CACHE; >> + >> +/** >> + * Parameters used when creating the cuckoo hash table. >> + */ >> +typedef struct odp_cuckoo_hash_param { >> + /**< Name of the hash table. */ >> + const char *name; >> + /**< Total hash table entries. */ >> + uint32_t entries; >> + /**< Length of hash key. */ >> + uint32_t key_len; >> + /**< Primary Hash function used to calculate hash. */ >> + odp_cuckoo_hash_func_t hash_func; >> + /**< Init value used by hash_func. */ >> + uint32_t hash_func_init_val; >> + /**< Indicate if additional parameters are present. */ >> + uint8_t extra_flag; >> +} odp_cuckoo_hash_param_t; >> + >> +/** >> + * Create a new cuckoo hash table. >> + * >> + * @param ht >> + * hash table if successful >> + * @param params >> + * Parameters used to create and initialise the hash table. >> + * @return >> + * 0 on success >> + * negative value on errors including: >> + * - -EINVAL - invalid parameter passed to function >> + * - -EEXIST - a hash table with the same name already exists >> + * - -ENOMEM - no appropriate memory area found in which to create >> memzone >> + */ >> +int >> +odp_cuckoo_hash_create( >> + odp_cuckoo_hash_tbl_t **ht, >> + const odp_cuckoo_hash_param_t *params); >> + >> +/** >> + * Find an existing hash table object and return a pointer to it. >> + * >> + * @param name >> + * Name of the hash table as passed to odp_hash_create() >> + * @return >> + * Pointer to hash table or NULL if object not found >> + */ >> +odp_cuckoo_hash_tbl_t * >> +odp_cuckoo_hash_find_existing(const char *name); >> + >> +/** >> + * De-allocate all memory used by hash table. >> + * @param h >> + * Hash table to free >> + */ >> +void >> +odp_cuckoo_hash_destroy(odp_cuckoo_hash_tbl_t *h); >> + >> +/** >> + * Reset all hash structure, by zeroing all entries >> + * @param h >> + * Hash table to reset >> + */ >> +void >> +odp_cuckoo_hash_reset(odp_cuckoo_hash_tbl_t *h); >> + >> +/** >> + * Add a key-value pair to an existing hash table. >> + * This operation is not multi-thread safe >> + * and should only be called from one thread. >> + * >> + * @param h >> + * Hash table to add the key to. >> + * @param key >> + * Key to add to the hash table. >> + * @param data >> + * Data to add to the hash table. >> + * @return >> + * - 0 if added successfully >> + * - -EINVAL if the parameters are invalid. >> + * - -ENOSPC if there is no space in the hash for this key. >> + */ >> +int >> +odp_cuckoo_hash_add_key_data( >> + const odp_cuckoo_hash_tbl_t *h, >> + const void *key, void *data); >> + >> +/** >> + * Add a key-value pair with a pre-computed hash value >> + * to an existing hash table. >> + * This operation is not multi-thread safe >> + * and should only be called from one thread. >> + * >> + * @param h >> + * Hash table to add the key to. >> + * @param key >> + * Key to add to the hash table. >> + * @param sig >> + * Precomputed hash value for 'key' >> + * @param data >> + * Data to add to the hash table. >> + * @return >> + * - 0 if added successfully >> + * - -EINVAL if the parameters are invalid. >> + * - -ENOSPC if there is no space in the hash for this key. >> + */ >> +int32_t >> +odp_cuckoo_hash_add_key_with_hash_data( >> + const odp_cuckoo_hash_tbl_t *h, const void *key, >> + uint32_t sig, void *data); >> + >> +/** >> + * Add a key to an existing hash table. This operation is not multi-thread >> + * safe and should only be called from one thread. >> + * >> + * @param h >> + * Hash table to add the key to. >> + * @param key >> + * Key to add to the hash table. >> + * @return >> + * - -EINVAL if the parameters are invalid. >> + * - -ENOSPC if there is no space in the hash for this key. >> + * - A positive value that can be used by the caller as an offset into an >> + * array of user data. This value is unique for this key. >> + */ >> +int32_t >> +odp_cuckoo_hash_add_key(const odp_cuckoo_hash_tbl_t *h, const void *key); >> + >> +/** >> + * Add a key to an existing hash table. >> + * This operation is not multi-thread safe >> + * and should only be called from one thread. >> + * >> + * @param h >> + * Hash table to add the key to. >> + * @param key >> + * Key to add to the hash table. >> + * @param sig >> + * Precomputed hash value for 'key'. >> + * @return >> + * - -EINVAL if the parameters are invalid. >> + * - -ENOSPC if there is no space in the hash for this key. >> + * - A positive value that can be used by the caller as an offset into an >> + * array of user data. This value is unique for this key. >> + */ >> +int32_t >> +odp_cuckoo_hash_add_key_with_hash( >> + const odp_cuckoo_hash_tbl_t *h, >> + const void *key, uint32_t sig); >> + >> +/** >> + * Remove a key from an existing hash table. >> + * This operation is not multi-thread safe >> + * and should only be called from one thread. >> + * >> + * @param h >> + * Hash table to remove the key from. >> + * @param key >> + * Key to remove from the hash table. >> + * @return >> + * - -EINVAL if the parameters are invalid. >> + * - -ENOENT if the key is not found. >> + * - A positive value that can be used by the caller as an offset into an >> + * array of user data. This value is unique for this key, and is the >> same >> + * value that was returned when the key was added. >> + */ >> +int32_t >> +odp_cuckoo_hash_del_key( >> + const odp_cuckoo_hash_tbl_t *h, const void *key); >> + >> +/** >> + * Remove a key from an existing hash table. >> + * This operation is not multi-thread safe >> + * and should only be called from one thread. >> + * >> + * @param h >> + * Hash table to remove the key from. >> + * @param key >> + * Key to remove from the hash table. >> + * @param sig >> + * Precomputed hash value for 'key'. >> + * @return >> + * - -EINVAL if the parameters are invalid. >> + * - -ENOENT if the key is not found. >> + * - A positive value that can be used by the caller as an offset into an >> + * array of user data. This value is unique for this key, and is the >> same >> + * value that was returned when the key was added. >> + */ >> +int32_t >> +odp_cuckoo_hash_del_key_with_hash( >> + const odp_cuckoo_hash_tbl_t *h, const void *key, uint32_t sig); >> + >> +/** >> + * Find a key-value pair in the hash table. >> + * This operation is multi-thread safe. >> + * >> + * @param h >> + * Hash table to look in. >> + * @param key >> + * Key to find. >> + * @param data >> + * Output with pointer to data returned from the hash table. >> + * @return >> + * 0 if successful lookup >> + * - EINVAL if the parameters are invalid. >> + * - ENOENT if the key is not found. >> + */ >> +int >> +odp_cukoo_hash_lookup_data( >> + const odp_cuckoo_hash_tbl_t *h, >> + const void *key, void **data); >> + >> +/** >> + * Find a key-value pair with a pre-computed hash value >> + * to an existing hash table. >> + * This operation is multi-thread safe. >> + * >> + * @param h >> + * Hash table to look in. >> + * @param key >> + * Key to find. >> + * @param sig >> + * Precomputed hash value for 'key' >> + * @param data >> + * Output with pointer to data returned from the hash table. >> + * @return >> + * 0 if successful lookup >> + * - EINVAL if the parameters are invalid. >> + * - ENOENT if the key is not found. >> + */ >> +int >> +odp_cuckoo_hash_lookup_with_hash_data( >> + const odp_cuckoo_hash_tbl_t *h, const void *key, >> + uint32_t sig, void **data); >> + >> +/** >> + * Find a key in the hash table. >> + * This operation is multi-thread safe. >> + * >> + * @param h >> + * Hash table to look in. >> + * @param key >> + * Key to find. >> + * @return >> + * - -EINVAL if the parameters are invalid. >> + * - -ENOENT if the key is not found. >> + * - A positive value that can be used by the caller as an offset into an >> + * array of user data. This value is unique for this key, and is the >> same >> + * value that was returned when the key was added. >> + */ >> +int32_t >> +odp_cuckoo_hash_lookup(const odp_cuckoo_hash_tbl_t *h, const void *key); >> + >> +/** >> + * Find a key in the hash table. >> + * This operation is multi-thread safe. >> + * >> + * @param h >> + * Hash table to look in. >> + * @param key >> + * Key to find. >> + * @param sig >> + * Hash value to remove from the hash table. >> + * @return >> + * - -EINVAL if the parameters are invalid. >> + * - -ENOENT if the key is not found. >> + * - A positive value that can be used by the caller as an offset into an >> + * array of user data. This value is unique for this key, and is the >> same >> + * value that was returned when the key was added. >> + */ >> +int32_t >> +odp_cuckoo_hash_lookup_with_hash( >> + const odp_cuckoo_hash_tbl_t *h, const void *key, uint32_t sig); >> + >> +/** >> + * Find multiple keys in the hash table. >> + * This operation is multi-thread safe. >> + * >> + * @param h >> + * Hash table to look in. >> + * @param keys >> + * A pointer to a list of keys to look for. >> + * @param num_keys >> + * How many keys are in the keys list (less than >> odp_HASH_LOOKUP_BULK_MAX). >> + * @param hit_mask >> + * Output containing a bitmask with all successful lookups. >> + * @param data >> + * Output containing array of data returned from all the successful >> lookups. >> + * @return >> + * -EINVAL if there's an error, otherwise number of successful lookups. >> + */ >> +int >> +odp_cuckoo_hash_lookup_bulk_data( >> + const odp_cuckoo_hash_tbl_t *h, const void **keys, >> + uint32_t num_keys, uint64_t *hit_mask, void *data[]); >> + >> +/** >> + * Find multiple keys in the hash table. >> + * This operation is multi-thread safe. >> + * >> + * @param h >> + * Hash table to look in. >> + * @param keys >> + * A pointer to a list of keys to look for. >> + * @param num_keys >> + * How many keys are in the keys list (less than HASH_LOOKUP_BULK_MAX). >> + * @param positions >> + * Output containing a list of values, corresponding to the list of keys >> that >> + * can be used by the caller as an offset into an array of user data. >> These >> + * values are unique for each key, and are the same values that were >> returned >> + * when each key was added. If a key in the list was not found, then >> -ENOENT >> + * will be the value. >> + * @return >> + * -EINVAL if there's an error, otherwise 0. >> + */ >> +int >> +odp_cuckoo_hash_lookup_bulk( >> + const odp_cuckoo_hash_tbl_t *h, const void **keys, >> + uint32_t num_keys, int32_t *positions); >> + >> +/** >> + * Iterate through the hash table, returning key-value pairs. >> + * >> + * @param h >> + * Hash table to iterate >> + * @param key >> + * Output containing the key where current iterator >> + * was pointing at >> + * @param data >> + * Output containing the data associated with key. >> + * Returns NULL if data was not stored. >> + * @param next >> + * Pointer to iterator. Should be 0 to start iterating the hash table. >> + * Iterator is incremented after each call of this function. >> + * @return >> + * Position where key was stored, if successful. >> + * - -EINVAL if the parameters are invalid. >> + * - -ENOENT if end of the hash table. >> + */ >> +int32_t >> +odp_cuckoo_hash_iterate( >> + const odp_cuckoo_hash_tbl_t *h, >> + const void **key, void **data, uint32_t *next); >> + >> +#ifdef __cplusplus >> +} >> +#endif >> + >> +#endif /* ODP_API_HASH_H_ */ >> diff --git a/include/odp_api.h b/include/odp_api.h >> index 44b67ee..721c852 100644 >> --- a/include/odp_api.h >> +++ b/include/odp_api.h >> @@ -59,6 +59,7 @@ extern "C" { >> #include <odp/api/spinlock_recursive.h> >> #include <odp/api/rwlock_recursive.h> >> #include <odp/api/std_clib.h> >> +#include <odp/api/cuckoo_hash.h> >> >> #ifdef __cplusplus >> } >> diff --git a/platform/linux-generic/include/odp/api/cuckoo_hash.h >> b/platform/linux-generic/include/odp/api/cuckoo_hash.h >> new file mode 100644 >> index 0000000..b4dfd78 >> --- /dev/null >> +++ b/platform/linux-generic/include/odp/api/cuckoo_hash.h >> @@ -0,0 +1,34 @@ >> +/* Copyright (c) 2015, Linaro Limited >> + * All rights reserved. >> + * >> + * SPDX-License-Identifier: BSD-3-Clause >> + */ >> + >> +/** >> + * @file >> + * >> + * ODP Cuckoo Hash Table >> + */ >> + >> +#ifndef ODP_PLAT_CUCKOO_HASH_H_ >> +#define ODP_PLAT_CUCKOO_HASH_H_ >> + >> +#ifdef __cplusplus >> +extern "C" { >> +#endif >> + >> +/** @ingroup odp_cuckoo_hash >> + * @{ >> + */ >> + >> +/** >> + * @} >> + */ >> + >> +#include <odp/api/spec/cuckoo_hash.h> >> + >> +#ifdef __cplusplus >> +} >> +#endif >> + >> +#endif >> -- >> 1.9.1 >> >> >> _______________________________________________ >> lng-odp mailing list >> lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org> >> https://lists.linaro.org/mailman/listinfo/lng-odp >> <https://lists.linaro.org/mailman/listinfo/lng-odp> > > > > -- > Mike Holmes > Technical Manager - Linaro Networking Group > Linaro.org <http://www.linaro.org/> │ Open source software for ARM SoCs > "Work should be fun and collaborative, the rest follows" > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org > https://lists.linaro.org/mailman/listinfo/lng-odp
_______________________________________________ lng-odp mailing list lng-odp@lists.linaro.org https://lists.linaro.org/mailman/listinfo/lng-odp