1 /* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
3 * Modified 2009 by Barret Rhoden <brho@cs.berkeley.edu>
5 * - No longer frees keys or values. It's up to the client to do that.
6 * - Provides common hash and equality functions (meant for longs)
7 * - Uses the slab allocator for hash entry allocation.
8 * - Merges the iterator code with the main hash table code, mostly to avoid
9 * externing the hentry cache.
12 #ifndef __ROS_KERN_HASHTABLE_H__
13 #define __ROS_KERN_HASHTABLE_H__
23 #include <ros/common.h>
25 /*****************************************************************************/
26 typedef struct hash_entry
30 struct hash_entry *next;
33 typedef struct hashtable {
39 size_t (*hashfn) (void *k);
40 ssize_t (*eqfn) (void *k1, void *k2);
43 size_t hash(struct hashtable *h, void *k);
44 static inline size_t indexFor(unsigned int tablelength, unsigned int hashvalue)
46 return (hashvalue % tablelength);
49 /*****************************************************************************/
52 * hashtable_init(); // Do this once during kernel initialization
54 * struct hashtable *h;
56 * struct some_value *v;
58 * static size_t hash_from_key_fn( void *k );
59 * static ssize_t keys_equal_fn ( void *key1, void *key2 );
61 * h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
62 * k = (struct some_key *) kmalloc(sizeof(struct some_key));
63 * v = (struct some_value *) kmalloc(sizeof(struct some_value));
65 * (initialise k and v to suitable values)
67 * if (! hashtable_insert(h,k,v) )
68 * { panic("Hashtable broken...\n"); }
70 * if (NULL == (found = hashtable_search(h,k) ))
71 * { printk("not found!"); }
73 * if (NULL == (found = hashtable_remove(h,k) ))
74 * { printk("Not found\n"); }
78 /* Macros may be used to define type-safe(r) hashtable access functions, with
79 * methods specialized to take known key and value types as parameters.
83 * Insert this at the start of your file:
85 * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
86 * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
87 * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
89 * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
90 * These operate just like hashtable_insert etc., with the same parameters,
91 * but their function signatures have 'struct some_key *' rather than
92 * 'void *', and hence can generate compile time errors if your program is
93 * supplying incorrect data as a key (and similarly for value).
95 * Note that the hash and key equality functions passed to create_hashtable
96 * still take 'void *' parameters instead of 'some key *'. This shouldn't be
97 * a difficult issue as they're only defined and passed once, and the other
98 * functions will ensure that only valid keys are supplied to them.
100 * The cost for this checking is increased code size and runtime overhead
101 * - if performance is important, it may be worth switching back to the
102 * unsafe methods once your program has been debugged with the safe methods.
103 * This just requires switching to some simple alternative defines - eg:
104 * #define insert_some hashtable_insert
108 /* Call this once on bootup, after initializing the slab allocator. */
109 void hashtable_init(void);
111 /* Common hash/equals functions. Don't call these directly. */
112 size_t __generic_hash(void *k);
113 ssize_t __generic_eq(void *k1, void *k2);
115 /*****************************************************************************
118 * @name create_hashtable
119 * @param minsize minimum initial size of hashtable
120 * @param hashfunction function for hashing keys
121 * @param key_eq_fn function for determining key equality
122 * @return newly created hashtable or NULL on failure
126 create_hashtable(size_t minsize,
127 size_t (*hashfunction) (void*),
128 ssize_t (*key_eq_fn) (void*,void*));
130 /*****************************************************************************
133 * @name hashtable_insert
134 * @param h the hashtable to insert into
137 * @return non-zero for successful insertion
139 * This function will cause the table to expand if the insertion would take
140 * the ratio of entries to table size over the maximum load factor.
142 * This function does not check for repeated insertions with a duplicate key.
143 * The value returned when using a duplicate key is undefined -- when
144 * the hashtable changes size, the order of retrieval of duplicate key
145 * entries is reversed.
146 * If in doubt, remove before insert.
150 hashtable_insert(hashtable_t *h, void *k, void *v);
152 #define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
153 ssize_t fnname (hashtable_t *h, keytype *k, valuetype *v) \
155 return hashtable_insert(h,k,v); \
158 /*****************************************************************************
161 * @name hashtable_search
162 * @param h the hashtable to search
163 * @param k the key to search for
164 * @return the value associated with the key, or NULL if none found
168 hashtable_search(hashtable_t *h, void *k);
170 #define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
171 valuetype * fnname (hashtable_t *h, keytype *k) \
173 return (valuetype *) (hashtable_search(h,k)); \
176 /*****************************************************************************
179 * @name hashtable_remove
180 * @param h the hashtable to remove the item from
181 * @param k the key to search for
182 * @return the value associated with the key, or NULL if none found
184 * Caller ought to free the key, if appropriate.
187 void * /* returns value */
188 hashtable_remove(hashtable_t *h, void *k);
190 #define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
191 valuetype * fnname (hashtable_t *h, keytype *k) \
193 return (valuetype *) (hashtable_remove(h,k)); \
197 /*****************************************************************************
200 * @name hashtable_count
201 * @param h the hashtable
202 * @return the number of items stored in the hashtable
206 hashtable_count(hashtable_t *h);
209 /*****************************************************************************
212 * @name hashtable_destroy
213 * @param h the hashtable
215 * This will not free the values or the keys. Each user of the hashtable may
216 * have a different way of freeing (such as the slab allocator, kfree, or
217 * nothing (key is just an integer)).
219 * If the htable isn't empty, you ought to iterate through and destroy manually.
220 * This will warn if you try to destroy an non-empty htable.
224 hashtable_destroy(hashtable_t *h);
226 /***************************** Hashtable Iterator ****************************/
227 /*****************************************************************************/
228 /* This struct is only concrete here to allow the inlining of two of the
229 * accessor functions. */
230 typedef struct hashtable_itr {
233 hash_entry_t *parent;
237 /*****************************************************************************/
238 /* hashtable_iterator. Be sure to kfree this when you are done.
242 hashtable_iterator(hashtable_t *h);
244 /*****************************************************************************/
245 /* hashtable_iterator_key
246 * - return the key of the (key,value) pair at the current position
248 * Keep this in sync with the non-externed version in the .c */
251 hashtable_iterator_key(hashtable_itr_t *i)
256 /*****************************************************************************/
257 /* value - return the value of the (key,value) pair at the current position
259 * Keep this in sync with the non-externed version in the .c */
262 hashtable_iterator_value(hashtable_itr_t *i)
267 /*****************************************************************************/
268 /* advance - advance the iterator to the next element
269 * returns zero if advanced to end of table */
272 hashtable_iterator_advance(hashtable_itr_t *itr);
274 /*****************************************************************************/
275 /* remove - remove current element and advance the iterator to the next element
276 * NB: if you need the key or value to free it, read it before
277 * removing. ie: beware memory leaks! this will not remove the key.
278 * returns zero if advanced to end of table */
281 hashtable_iterator_remove(hashtable_itr_t *itr);
283 /*****************************************************************************/
284 /* search - overwrite the supplied iterator, to point to the entry
285 * matching the supplied key.
286 * h points to the hashtable to be searched.
287 * returns zero if not found. */
289 hashtable_iterator_search(hashtable_itr_t *itr,
290 hashtable_t *h, void *k);
292 #define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
293 ssize_t fnname (hashtable_itr_t *i, hashtable_t *h, keytype *k) \
295 return (hashtable_iterator_search(i,h,k)); \
298 /* Runs func on each member of the hash table */
299 void hash_for_each(struct hashtable *hash, void func(void*));
300 /* Same, but removes the item too */
301 void hash_for_each_remove(struct hashtable *hash, void func(void*));
303 #endif /* __ROS_KERN_HASHTABLE_H__ */
306 * Copyright (c) 2002, 2004, Christopher Clark
307 * All rights reserved.
309 * Redistribution and use in source and binary forms, with or without
310 * modification, are permitted provided that the following conditions
313 * * Redistributions of source code must retain the above copyright
314 * notice, this list of conditions and the following disclaimer.
316 * * Redistributions in binary form must reproduce the above copyright
317 * notice, this list of conditions and the following disclaimer in the
318 * documentation and/or other materials provided with the distribution.
320 * * Neither the name of the original author; nor the names of any contributors
321 * may be used to endorse or promote products derived from this software
322 * without specific prior written permission.
325 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
326 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
327 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
328 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
329 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
330 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
331 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
332 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
333 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
334 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
335 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.