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>
9 #include <linux/sched.h>
12 struct hashtab
*hashtab_create(u32 (*hash_value
)(struct hashtab
*h
, const void *key
),
13 int (*keycmp
)(struct hashtab
*h
, const void *key1
, const void *key2
),
19 p
= kzalloc(sizeof(*p
), GFP_KERNEL
);
25 p
->hash_value
= hash_value
;
27 p
->htable
= kmalloc(sizeof(*(p
->htable
)) * size
, GFP_KERNEL
);
28 if (p
->htable
== NULL
) {
33 for (i
= 0; i
< size
; i
++)
39 int hashtab_insert(struct hashtab
*h
, void *key
, void *datum
)
42 struct hashtab_node
*prev
, *cur
, *newnode
;
46 if (!h
|| h
->nel
== HASHTAB_MAX_NODES
)
49 hvalue
= h
->hash_value(h
, key
);
51 cur
= h
->htable
[hvalue
];
52 while (cur
&& h
->keycmp(h
, key
, cur
->key
) > 0) {
57 if (cur
&& (h
->keycmp(h
, key
, cur
->key
) == 0))
60 newnode
= kzalloc(sizeof(*newnode
), GFP_KERNEL
);
64 newnode
->datum
= datum
;
66 newnode
->next
= prev
->next
;
69 newnode
->next
= h
->htable
[hvalue
];
70 h
->htable
[hvalue
] = newnode
;
77 void *hashtab_search(struct hashtab
*h
, const void *key
)
80 struct hashtab_node
*cur
;
85 hvalue
= h
->hash_value(h
, key
);
86 cur
= h
->htable
[hvalue
];
87 while (cur
&& h
->keycmp(h
, key
, cur
->key
) > 0)
90 if (cur
== NULL
|| (h
->keycmp(h
, key
, cur
->key
) != 0))
96 void hashtab_destroy(struct hashtab
*h
)
99 struct hashtab_node
*cur
, *temp
;
104 for (i
= 0; i
< h
->size
; i
++) {
120 int hashtab_map(struct hashtab
*h
,
121 int (*apply
)(void *k
, void *d
, void *args
),
126 struct hashtab_node
*cur
;
131 for (i
= 0; i
< h
->size
; i
++) {
134 ret
= apply(cur
->key
, cur
->datum
, args
);
144 void hashtab_stat(struct hashtab
*h
, struct hashtab_info
*info
)
146 u32 i
, chain_len
, slots_used
, max_chain_len
;
147 struct hashtab_node
*cur
;
151 for (slots_used
= max_chain_len
= i
= 0; i
< h
->size
; i
++) {
161 if (chain_len
> max_chain_len
)
162 max_chain_len
= chain_len
;
166 info
->slots_used
= slots_used
;
167 info
->max_chain_len
= max_chain_len
;