1fbaf242cSMasahiro Yamada /* SPDX-License-Identifier: GPL-2.0-only */
2fbaf242cSMasahiro Yamada #ifndef HASHTABLE_H
3fbaf242cSMasahiro Yamada #define HASHTABLE_H
4fbaf242cSMasahiro Yamada
5fbaf242cSMasahiro Yamada #include "array_size.h"
6fbaf242cSMasahiro Yamada #include "list.h"
7fbaf242cSMasahiro Yamada
8fbaf242cSMasahiro Yamada #define HASH_SIZE(name) (ARRAY_SIZE(name))
9fbaf242cSMasahiro Yamada
10fbaf242cSMasahiro Yamada #define HASHTABLE_DECLARE(name, size) struct hlist_head name[size]
11fbaf242cSMasahiro Yamada
12fbaf242cSMasahiro Yamada #define HASHTABLE_DEFINE(name, size) \
13fbaf242cSMasahiro Yamada HASHTABLE_DECLARE(name, size) = \
14fbaf242cSMasahiro Yamada { [0 ... ((size) - 1)] = HLIST_HEAD_INIT }
15fbaf242cSMasahiro Yamada
16fbaf242cSMasahiro Yamada #define hash_head(table, key) (&(table)[(key) % HASH_SIZE(table)])
17fbaf242cSMasahiro Yamada
__hash_init(struct hlist_head * ht,unsigned int sz)18*16ff3f60SMasahiro Yamada static inline void __hash_init(struct hlist_head *ht, unsigned int sz)
19*16ff3f60SMasahiro Yamada {
20*16ff3f60SMasahiro Yamada unsigned int i;
21*16ff3f60SMasahiro Yamada
22*16ff3f60SMasahiro Yamada for (i = 0; i < sz; i++)
23*16ff3f60SMasahiro Yamada INIT_HLIST_HEAD(&ht[i]);
24*16ff3f60SMasahiro Yamada }
25*16ff3f60SMasahiro Yamada
26*16ff3f60SMasahiro Yamada /**
27*16ff3f60SMasahiro Yamada * hash_init - initialize a hash table
28*16ff3f60SMasahiro Yamada * @table: hashtable to be initialized
29*16ff3f60SMasahiro Yamada *
30*16ff3f60SMasahiro Yamada * This has to be a macro since HASH_SIZE() will not work on pointers since
31*16ff3f60SMasahiro Yamada * it calculates the size during preprocessing.
32*16ff3f60SMasahiro Yamada */
33*16ff3f60SMasahiro Yamada #define hash_init(table) __hash_init(table, HASH_SIZE(table))
34*16ff3f60SMasahiro Yamada
35fbaf242cSMasahiro Yamada /**
36fbaf242cSMasahiro Yamada * hash_add - add an object to a hashtable
37fbaf242cSMasahiro Yamada * @table: hashtable to add to
38fbaf242cSMasahiro Yamada * @node: the &struct hlist_node of the object to be added
39fbaf242cSMasahiro Yamada * @key: the key of the object to be added
40fbaf242cSMasahiro Yamada */
41fbaf242cSMasahiro Yamada #define hash_add(table, node, key) \
42fbaf242cSMasahiro Yamada hlist_add_head(node, hash_head(table, key))
43fbaf242cSMasahiro Yamada
44fbaf242cSMasahiro Yamada /**
45*16ff3f60SMasahiro Yamada * hash_del - remove an object from a hashtable
46*16ff3f60SMasahiro Yamada * @node: &struct hlist_node of the object to remove
47*16ff3f60SMasahiro Yamada */
hash_del(struct hlist_node * node)48*16ff3f60SMasahiro Yamada static inline void hash_del(struct hlist_node *node)
49*16ff3f60SMasahiro Yamada {
50*16ff3f60SMasahiro Yamada hlist_del_init(node);
51*16ff3f60SMasahiro Yamada }
52*16ff3f60SMasahiro Yamada
53*16ff3f60SMasahiro Yamada /**
54fbaf242cSMasahiro Yamada * hash_for_each - iterate over a hashtable
55fbaf242cSMasahiro Yamada * @table: hashtable to iterate
56fbaf242cSMasahiro Yamada * @obj: the type * to use as a loop cursor for each entry
57fbaf242cSMasahiro Yamada * @member: the name of the hlist_node within the struct
58fbaf242cSMasahiro Yamada */
59fbaf242cSMasahiro Yamada #define hash_for_each(table, obj, member) \
60fbaf242cSMasahiro Yamada for (int _bkt = 0; _bkt < HASH_SIZE(table); _bkt++) \
61fbaf242cSMasahiro Yamada hlist_for_each_entry(obj, &table[_bkt], member)
62fbaf242cSMasahiro Yamada
63fbaf242cSMasahiro Yamada /**
64*16ff3f60SMasahiro Yamada * hash_for_each_safe - iterate over a hashtable safe against removal of
65*16ff3f60SMasahiro Yamada * hash entry
66*16ff3f60SMasahiro Yamada * @table: hashtable to iterate
67*16ff3f60SMasahiro Yamada * @obj: the type * to use as a loop cursor for each entry
68*16ff3f60SMasahiro Yamada * @tmp: a &struct hlist_node used for temporary storage
69*16ff3f60SMasahiro Yamada * @member: the name of the hlist_node within the struct
70*16ff3f60SMasahiro Yamada */
71*16ff3f60SMasahiro Yamada #define hash_for_each_safe(table, obj, tmp, member) \
72*16ff3f60SMasahiro Yamada for (int _bkt = 0; _bkt < HASH_SIZE(table); _bkt++) \
73*16ff3f60SMasahiro Yamada hlist_for_each_entry_safe(obj, tmp, &table[_bkt], member)
74*16ff3f60SMasahiro Yamada
75*16ff3f60SMasahiro Yamada /**
76fbaf242cSMasahiro Yamada * hash_for_each_possible - iterate over all possible objects hashing to the
77fbaf242cSMasahiro Yamada * same bucket
78fbaf242cSMasahiro Yamada * @table: hashtable to iterate
79fbaf242cSMasahiro Yamada * @obj: the type * to use as a loop cursor for each entry
80fbaf242cSMasahiro Yamada * @member: the name of the hlist_node within the struct
81fbaf242cSMasahiro Yamada * @key: the key of the objects to iterate over
82fbaf242cSMasahiro Yamada */
83fbaf242cSMasahiro Yamada #define hash_for_each_possible(table, obj, member, key) \
84fbaf242cSMasahiro Yamada hlist_for_each_entry(obj, hash_head(table, key), member)
85fbaf242cSMasahiro Yamada
86*16ff3f60SMasahiro Yamada /**
87*16ff3f60SMasahiro Yamada * hash_for_each_possible_safe - iterate over all possible objects hashing to the
88*16ff3f60SMasahiro Yamada * same bucket safe against removals
89*16ff3f60SMasahiro Yamada * @table: hashtable to iterate
90*16ff3f60SMasahiro Yamada * @obj: the type * to use as a loop cursor for each entry
91*16ff3f60SMasahiro Yamada * @tmp: a &struct hlist_node used for temporary storage
92*16ff3f60SMasahiro Yamada * @member: the name of the hlist_node within the struct
93*16ff3f60SMasahiro Yamada * @key: the key of the objects to iterate over
94*16ff3f60SMasahiro Yamada */
95*16ff3f60SMasahiro Yamada #define hash_for_each_possible_safe(table, obj, tmp, member, key) \
96*16ff3f60SMasahiro Yamada hlist_for_each_entry_safe(obj, tmp, hash_head(table, key), member)
97*16ff3f60SMasahiro Yamada
98fbaf242cSMasahiro Yamada #endif /* HASHTABLE_H */
99