1*b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21698872bSJosh Poimboeuf /*
31698872bSJosh Poimboeuf * Statically sized hash table implementation
41698872bSJosh Poimboeuf * (C) 2012 Sasha Levin <[email protected]>
51698872bSJosh Poimboeuf */
61698872bSJosh Poimboeuf
71698872bSJosh Poimboeuf #ifndef _LINUX_HASHTABLE_H
81698872bSJosh Poimboeuf #define _LINUX_HASHTABLE_H
91698872bSJosh Poimboeuf
101698872bSJosh Poimboeuf #include <linux/list.h>
111698872bSJosh Poimboeuf #include <linux/types.h>
121698872bSJosh Poimboeuf #include <linux/kernel.h>
131698872bSJosh Poimboeuf #include <linux/bitops.h>
141698872bSJosh Poimboeuf #include <linux/hash.h>
151698872bSJosh Poimboeuf #include <linux/log2.h>
161698872bSJosh Poimboeuf
171698872bSJosh Poimboeuf #define DEFINE_HASHTABLE(name, bits) \
181698872bSJosh Poimboeuf struct hlist_head name[1 << (bits)] = \
191698872bSJosh Poimboeuf { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
201698872bSJosh Poimboeuf
211698872bSJosh Poimboeuf #define DECLARE_HASHTABLE(name, bits) \
221698872bSJosh Poimboeuf struct hlist_head name[1 << (bits)]
231698872bSJosh Poimboeuf
241698872bSJosh Poimboeuf #define HASH_SIZE(name) (ARRAY_SIZE(name))
251698872bSJosh Poimboeuf #define HASH_BITS(name) ilog2(HASH_SIZE(name))
261698872bSJosh Poimboeuf
271698872bSJosh Poimboeuf /* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */
281698872bSJosh Poimboeuf #define hash_min(val, bits) \
291698872bSJosh Poimboeuf (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits))
301698872bSJosh Poimboeuf
__hash_init(struct hlist_head * ht,unsigned int sz)311698872bSJosh Poimboeuf static inline void __hash_init(struct hlist_head *ht, unsigned int sz)
321698872bSJosh Poimboeuf {
331698872bSJosh Poimboeuf unsigned int i;
341698872bSJosh Poimboeuf
351698872bSJosh Poimboeuf for (i = 0; i < sz; i++)
361698872bSJosh Poimboeuf INIT_HLIST_HEAD(&ht[i]);
371698872bSJosh Poimboeuf }
381698872bSJosh Poimboeuf
391698872bSJosh Poimboeuf /**
401698872bSJosh Poimboeuf * hash_init - initialize a hash table
411698872bSJosh Poimboeuf * @hashtable: hashtable to be initialized
421698872bSJosh Poimboeuf *
431698872bSJosh Poimboeuf * Calculates the size of the hashtable from the given parameter, otherwise
441698872bSJosh Poimboeuf * same as hash_init_size.
451698872bSJosh Poimboeuf *
461698872bSJosh Poimboeuf * This has to be a macro since HASH_BITS() will not work on pointers since
471698872bSJosh Poimboeuf * it calculates the size during preprocessing.
481698872bSJosh Poimboeuf */
491698872bSJosh Poimboeuf #define hash_init(hashtable) __hash_init(hashtable, HASH_SIZE(hashtable))
501698872bSJosh Poimboeuf
511698872bSJosh Poimboeuf /**
521698872bSJosh Poimboeuf * hash_add - add an object to a hashtable
531698872bSJosh Poimboeuf * @hashtable: hashtable to add to
541698872bSJosh Poimboeuf * @node: the &struct hlist_node of the object to be added
551698872bSJosh Poimboeuf * @key: the key of the object to be added
561698872bSJosh Poimboeuf */
571698872bSJosh Poimboeuf #define hash_add(hashtable, node, key) \
581698872bSJosh Poimboeuf hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))])
591698872bSJosh Poimboeuf
601698872bSJosh Poimboeuf /**
611698872bSJosh Poimboeuf * hash_hashed - check whether an object is in any hashtable
621698872bSJosh Poimboeuf * @node: the &struct hlist_node of the object to be checked
631698872bSJosh Poimboeuf */
hash_hashed(struct hlist_node * node)641698872bSJosh Poimboeuf static inline bool hash_hashed(struct hlist_node *node)
651698872bSJosh Poimboeuf {
661698872bSJosh Poimboeuf return !hlist_unhashed(node);
671698872bSJosh Poimboeuf }
681698872bSJosh Poimboeuf
__hash_empty(struct hlist_head * ht,unsigned int sz)691698872bSJosh Poimboeuf static inline bool __hash_empty(struct hlist_head *ht, unsigned int sz)
701698872bSJosh Poimboeuf {
711698872bSJosh Poimboeuf unsigned int i;
721698872bSJosh Poimboeuf
731698872bSJosh Poimboeuf for (i = 0; i < sz; i++)
741698872bSJosh Poimboeuf if (!hlist_empty(&ht[i]))
751698872bSJosh Poimboeuf return false;
761698872bSJosh Poimboeuf
771698872bSJosh Poimboeuf return true;
781698872bSJosh Poimboeuf }
791698872bSJosh Poimboeuf
801698872bSJosh Poimboeuf /**
811698872bSJosh Poimboeuf * hash_empty - check whether a hashtable is empty
821698872bSJosh Poimboeuf * @hashtable: hashtable to check
831698872bSJosh Poimboeuf *
841698872bSJosh Poimboeuf * This has to be a macro since HASH_BITS() will not work on pointers since
851698872bSJosh Poimboeuf * it calculates the size during preprocessing.
861698872bSJosh Poimboeuf */
871698872bSJosh Poimboeuf #define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable))
881698872bSJosh Poimboeuf
891698872bSJosh Poimboeuf /**
901698872bSJosh Poimboeuf * hash_del - remove an object from a hashtable
911698872bSJosh Poimboeuf * @node: &struct hlist_node of the object to remove
921698872bSJosh Poimboeuf */
hash_del(struct hlist_node * node)931698872bSJosh Poimboeuf static inline void hash_del(struct hlist_node *node)
941698872bSJosh Poimboeuf {
951698872bSJosh Poimboeuf hlist_del_init(node);
961698872bSJosh Poimboeuf }
971698872bSJosh Poimboeuf
981698872bSJosh Poimboeuf /**
991698872bSJosh Poimboeuf * hash_for_each - iterate over a hashtable
1001698872bSJosh Poimboeuf * @name: hashtable to iterate
1011698872bSJosh Poimboeuf * @bkt: integer to use as bucket loop cursor
1021698872bSJosh Poimboeuf * @obj: the type * to use as a loop cursor for each entry
1031698872bSJosh Poimboeuf * @member: the name of the hlist_node within the struct
1041698872bSJosh Poimboeuf */
1051698872bSJosh Poimboeuf #define hash_for_each(name, bkt, obj, member) \
1061698872bSJosh Poimboeuf for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\
1071698872bSJosh Poimboeuf (bkt)++)\
1081698872bSJosh Poimboeuf hlist_for_each_entry(obj, &name[bkt], member)
1091698872bSJosh Poimboeuf
1101698872bSJosh Poimboeuf /**
1111698872bSJosh Poimboeuf * hash_for_each_safe - iterate over a hashtable safe against removal of
1121698872bSJosh Poimboeuf * hash entry
1131698872bSJosh Poimboeuf * @name: hashtable to iterate
1141698872bSJosh Poimboeuf * @bkt: integer to use as bucket loop cursor
1151698872bSJosh Poimboeuf * @tmp: a &struct used for temporary storage
1161698872bSJosh Poimboeuf * @obj: the type * to use as a loop cursor for each entry
1171698872bSJosh Poimboeuf * @member: the name of the hlist_node within the struct
1181698872bSJosh Poimboeuf */
1191698872bSJosh Poimboeuf #define hash_for_each_safe(name, bkt, tmp, obj, member) \
1201698872bSJosh Poimboeuf for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\
1211698872bSJosh Poimboeuf (bkt)++)\
1221698872bSJosh Poimboeuf hlist_for_each_entry_safe(obj, tmp, &name[bkt], member)
1231698872bSJosh Poimboeuf
1241698872bSJosh Poimboeuf /**
1251698872bSJosh Poimboeuf * hash_for_each_possible - iterate over all possible objects hashing to the
1261698872bSJosh Poimboeuf * same bucket
1271698872bSJosh Poimboeuf * @name: hashtable to iterate
1281698872bSJosh Poimboeuf * @obj: the type * to use as a loop cursor for each entry
1291698872bSJosh Poimboeuf * @member: the name of the hlist_node within the struct
1301698872bSJosh Poimboeuf * @key: the key of the objects to iterate over
1311698872bSJosh Poimboeuf */
1321698872bSJosh Poimboeuf #define hash_for_each_possible(name, obj, member, key) \
1331698872bSJosh Poimboeuf hlist_for_each_entry(obj, &name[hash_min(key, HASH_BITS(name))], member)
1341698872bSJosh Poimboeuf
1351698872bSJosh Poimboeuf /**
1361698872bSJosh Poimboeuf * hash_for_each_possible_safe - iterate over all possible objects hashing to the
1371698872bSJosh Poimboeuf * same bucket safe against removals
1381698872bSJosh Poimboeuf * @name: hashtable to iterate
1391698872bSJosh Poimboeuf * @obj: the type * to use as a loop cursor for each entry
1401698872bSJosh Poimboeuf * @tmp: a &struct used for temporary storage
1411698872bSJosh Poimboeuf * @member: the name of the hlist_node within the struct
1421698872bSJosh Poimboeuf * @key: the key of the objects to iterate over
1431698872bSJosh Poimboeuf */
1441698872bSJosh Poimboeuf #define hash_for_each_possible_safe(name, obj, tmp, member, key) \
1451698872bSJosh Poimboeuf hlist_for_each_entry_safe(obj, tmp,\
1461698872bSJosh Poimboeuf &name[hash_min(key, HASH_BITS(name))], member)
1471698872bSJosh Poimboeuf
1481698872bSJosh Poimboeuf
1491698872bSJosh Poimboeuf #endif
150