This hashtable implementation is using hlist buckets to provide a simple hashtable to prevent it from getting reimplemented all over the kernel.
Signed-off-by: Sasha Levin <levinsasha...@gmail.com> --- include/linux/hashtable.h | 75 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 75 insertions(+), 0 deletions(-) create mode 100644 include/linux/hashtable.h diff --git a/include/linux/hashtable.h b/include/linux/hashtable.h new file mode 100644 index 0000000..b004cf7 --- /dev/null +++ b/include/linux/hashtable.h @@ -0,0 +1,75 @@ +#ifndef _LINUX_HASHTABLE_H +#define _LINUX_HASHTABLE_H + +#include <linux/list.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/hash.h> + +struct hash_table { + size_t bits; + struct hlist_head buckets[]; +}; + +#define DEFINE_STATIC_HASHTABLE(n, b) \ + static struct hash_table n = { .bits = (b), \ + .buckets = { [0 ... ((1 << (b)) - 1)] = HLIST_HEAD_INIT } } + +#define DEFINE_HASHTABLE(n, b) \ + union { \ + struct hash_table n; \ + struct { \ + size_t bits; \ + struct hlist_head buckets[1 << (b)]; \ + } __##n ; \ + }; + +#define HASH_BITS(name) ((name)->bits) +#define HASH_SIZE(name) (1 << (HASH_BITS(name))) + +__attribute__ ((unused)) +static void hash_init(struct hash_table *ht, size_t bits) +{ + size_t i; + + ht->bits = bits; + for (i = 0; i < (1 << bits); i++) + INIT_HLIST_HEAD(&ht->buckets[i]); +} + +static void hash_add(struct hash_table *ht, struct hlist_node *node, long key) +{ + hlist_add_head(node, + &ht->buckets[hash_long((unsigned long)key, HASH_BITS(ht))]); +} + + +#define hash_get(name, key, type, member, cmp_fn) \ +({ \ + struct hlist_node *__node; \ + typeof(key) __key = key; \ + type *__obj = NULL; \ + hlist_for_each_entry(__obj, __node, &(name)->buckets[ \ + hash_long((unsigned long) __key, \ + HASH_BITS(name))], member) \ + if (cmp_fn(__obj, __key)) \ + break; \ + __obj; \ +}) + +__attribute__ ((unused)) +static void hash_del(struct hlist_node *node) +{ + hlist_del_init(node); +} + +#define hash_for_each(bkt, node, name, obj, member) \ + for (bkt = 0; bkt < HASH_SIZE(name); bkt++) \ + hlist_for_each_entry(obj, node, &(name)->buckets[i], member) + +#define hash_for_each_possible(name, node, obj, member, key) \ + hlist_for_each_entry(obj, node, \ + &(name)->buckets[hash_long((unsigned long) key, \ + HASH_BITS(name))], member) + +#endif -- 1.7.8.6 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/