2 * Implementation of the hash table type.
4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
6 #include <linux/kernel.h>
7 #include <linux/slab.h>
8 #include <linux/errno.h>
11 struct hashtab
*hashtab_create(u32 (*hash_value
)(struct hashtab
*h
, const void *key
),
12 int (*keycmp
)(struct hashtab
*h
, const void *key1
, const void *key2
),
18 p
= kzalloc(sizeof(*p
), GFP_KERNEL
);
24 p
->hash_value
= hash_value
;
26 p
->htable
= kmalloc(sizeof(*(p
->htable
)) * size
, GFP_KERNEL
);
27 if (p
->htable
== NULL
) {
32 for (i
= 0; i
< size
; i
++)
38 int hashtab_insert(struct hashtab
*h
, void *key
, void *datum
)
41 struct hashtab_node
*prev
, *cur
, *newnode
;
43 if (!h
|| h
->nel
== HASHTAB_MAX_NODES
)
46 hvalue
= h
->hash_value(h
, key
);
48 cur
= h
->htable
[hvalue
];
49 while (cur
&& h
->keycmp(h
, key
, cur
->key
) > 0) {
54 if (cur
&& (h
->keycmp(h
, key
, cur
->key
) == 0))
57 newnode
= kzalloc(sizeof(*newnode
), GFP_KERNEL
);
61 newnode
->datum
= datum
;
63 newnode
->next
= prev
->next
;
66 newnode
->next
= h
->htable
[hvalue
];
67 h
->htable
[hvalue
] = newnode
;
74 void *hashtab_search(struct hashtab
*h
, const void *key
)
77 struct hashtab_node
*cur
;
82 hvalue
= h
->hash_value(h
, key
);
83 cur
= h
->htable
[hvalue
];
84 while (cur
&& h
->keycmp(h
, key
, cur
->key
) > 0)
87 if (cur
== NULL
|| (h
->keycmp(h
, key
, cur
->key
) != 0))
93 void hashtab_destroy(struct hashtab
*h
)
96 struct hashtab_node
*cur
, *temp
;
101 for (i
= 0; i
< h
->size
; i
++) {
117 int hashtab_map(struct hashtab
*h
,
118 int (*apply
)(void *k
, void *d
, void *args
),
123 struct hashtab_node
*cur
;
128 for (i
= 0; i
< h
->size
; i
++) {
131 ret
= apply(cur
->key
, cur
->datum
, args
);
141 void hashtab_stat(struct hashtab
*h
, struct hashtab_info
*info
)
143 u32 i
, chain_len
, slots_used
, max_chain_len
;
144 struct hashtab_node
*cur
;
148 for (slots_used
= max_chain_len
= i
= 0; i
< h
->size
; i
++) {
158 if (chain_len
> max_chain_len
)
159 max_chain_len
= chain_len
;
163 info
->slots_used
= slots_used
;
164 info
->max_chain_len
= max_chain_len
;