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.
14 #include <ros/common.h>
16 /*****************************************************************************/
17 typedef struct hash_entry
21 struct hash_entry *next;
24 typedef struct hashtable {
30 size_t (*hashfn) (void *k);
31 ssize_t (*eqfn) (void *k1, void *k2);
34 static inline size_t indexFor(unsigned int tablelength, unsigned int hashvalue)
36 return (hashvalue % tablelength);
39 /*****************************************************************************/
42 * hashtable_init(); // Do this once during kernel initialization
44 * struct hashtable *h;
46 * struct some_value *v;
48 * static size_t hash_from_key_fn( void *k );
49 * static ssize_t keys_equal_fn ( void *key1, void *key2 );
51 * h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
52 * k = (struct some_key *) kmalloc(sizeof(struct some_key));
53 * v = (struct some_value *) kmalloc(sizeof(struct some_value));
55 * (initialise k and v to suitable values)
57 * if (! hashtable_insert(h,k,v) )
58 * { panic("Hashtable broken...\n"); }
60 * if (NULL == (found = hashtable_search(h,k) ))
61 * { printk("not found!"); }
63 * if (NULL == (found = hashtable_remove(h,k) ))
64 * { printk("Not found\n"); }
68 /* Macros may be used to define type-safe(r) hashtable access functions, with
69 * methods specialized to take known key and value types as parameters.
73 * Insert this at the start of your file:
75 * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
76 * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
77 * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
79 * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
80 * These operate just like hashtable_insert etc., with the same parameters,
81 * but their function signatures have 'struct some_key *' rather than
82 * 'void *', and hence can generate compile time errors if your program is
83 * supplying incorrect data as a key (and similarly for value).
85 * Note that the hash and key equality functions passed to create_hashtable
86 * still take 'void *' parameters instead of 'some key *'. This shouldn't be
87 * a difficult issue as they're only defined and passed once, and the other
88 * functions will ensure that only valid keys are supplied to them.
90 * The cost for this checking is increased code size and runtime overhead
91 * - if performance is important, it may be worth switching back to the
92 * unsafe methods once your program has been debugged with the safe methods.
93 * This just requires switching to some simple alternative defines - eg:
94 * #define insert_some hashtable_insert
98 /* Call this once on bootup, after initializing the slab allocator. */
99 void hashtable_init(void);
101 /* Common hash/equals functions. Don't call these directly. */
102 size_t __generic_hash(void *k);
103 ssize_t __generic_eq(void *k1, void *k2);
105 /*****************************************************************************
108 * @name create_hashtable
109 * @param minsize minimum initial size of hashtable
110 * @param hashfunction function for hashing keys
111 * @param key_eq_fn function for determining key equality
112 * @return newly created hashtable or NULL on failure
116 create_hashtable(size_t minsize,
117 size_t (*hashfunction) (void*),
118 ssize_t (*key_eq_fn) (void*,void*));
120 /*****************************************************************************
123 * @name hashtable_insert
124 * @param h the hashtable to insert into
127 * @return non-zero for successful insertion
129 * This function will cause the table to expand if the insertion would take
130 * the ratio of entries to table size over the maximum load factor.
132 * This function does not check for repeated insertions with a duplicate key.
133 * The value returned when using a duplicate key is undefined -- when
134 * the hashtable changes size, the order of retrieval of duplicate key
135 * entries is reversed.
136 * If in doubt, remove before insert.
140 hashtable_insert(hashtable_t *h, void *k, void *v);
142 #define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
143 ssize_t fnname (hashtable_t *h, keytype *k, valuetype *v) \
145 return hashtable_insert(h,k,v); \
148 /*****************************************************************************
151 * @name hashtable_search
152 * @param h the hashtable to search
153 * @param k the key to search for
154 * @return the value associated with the key, or NULL if none found
158 hashtable_search(hashtable_t *h, void *k);
160 #define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
161 valuetype * fnname (hashtable_t *h, keytype *k) \
163 return (valuetype *) (hashtable_search(h,k)); \
166 /*****************************************************************************
169 * @name hashtable_remove
170 * @param h the hashtable to remove the item from
171 * @param k the key to search for
172 * @return the value associated with the key, or NULL if none found
174 * Caller ought to free the key, if appropriate.
177 void * /* returns value */
178 hashtable_remove(hashtable_t *h, void *k);
180 #define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
181 valuetype * fnname (hashtable_t *h, keytype *k) \
183 return (valuetype *) (hashtable_remove(h,k)); \
187 /*****************************************************************************
190 * @name hashtable_count
191 * @param h the hashtable
192 * @return the number of items stored in the hashtable
196 hashtable_count(hashtable_t *h);
199 /*****************************************************************************
202 * @name hashtable_destroy
203 * @param h the hashtable
205 * This will not free the values or the keys. Each user of the hashtable may
206 * have a different way of freeing (such as the slab allocator, kfree, or
207 * nothing (key is just an integer)).
209 * If the htable isn't empty, you ought to iterate through and destroy manually.
210 * This will warn if you try to destroy an non-empty htable.
214 hashtable_destroy(hashtable_t *h);
216 /***************************** Hashtable Iterator ****************************/
217 /*****************************************************************************/
218 /* This struct is only concrete here to allow the inlining of two of the
219 * accessor functions. */
220 typedef struct hashtable_itr {
223 hash_entry_t *parent;
227 /*****************************************************************************/
228 /* hashtable_iterator. Be sure to kfree this when you are done.
232 hashtable_iterator(hashtable_t *h);
234 /*****************************************************************************/
235 /* hashtable_iterator_key
236 * - return the key of the (key,value) pair at the current position
238 * Keep this in sync with the non-externed version in the .c */
241 hashtable_iterator_key(hashtable_itr_t *i)
246 /*****************************************************************************/
247 /* value - return the value of the (key,value) pair at the current position
249 * Keep this in sync with the non-externed version in the .c */
252 hashtable_iterator_value(hashtable_itr_t *i)
257 /*****************************************************************************/
258 /* advance - advance the iterator to the next element
259 * returns zero if advanced to end of table */
262 hashtable_iterator_advance(hashtable_itr_t *itr);
264 /*****************************************************************************/
265 /* remove - remove current element and advance the iterator to the next element
266 * NB: if you need the key or value to free it, read it before
267 * removing. ie: beware memory leaks! this will not remove the key.
268 * returns zero if advanced to end of table */
271 hashtable_iterator_remove(hashtable_itr_t *itr);
273 /*****************************************************************************/
274 /* search - overwrite the supplied iterator, to point to the entry
275 * matching the supplied key.
276 * h points to the hashtable to be searched.
277 * returns zero if not found. */
279 hashtable_iterator_search(hashtable_itr_t *itr,
280 hashtable_t *h, void *k);
282 #define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
283 ssize_t fnname (hashtable_itr_t *i, hashtable_t *h, keytype *k) \
285 return (hashtable_iterator_search(i,h,k)); \
288 /* Runs func on each member of the hash table */
289 void hash_for_each(struct hashtable *hash, void func(void *, void *),
291 /* Same, but removes the item too */
292 void hash_for_each_remove(struct hashtable *hash, void func(void *, void *),
296 * Copyright (c) 2002, 2004, Christopher Clark
297 * All rights reserved.
299 * Redistribution and use in source and binary forms, with or without
300 * modification, are permitted provided that the following conditions
303 * * Redistributions of source code must retain the above copyright
304 * notice, this list of conditions and the following disclaimer.
306 * * Redistributions in binary form must reproduce the above copyright
307 * notice, this list of conditions and the following disclaimer in the
308 * documentation and/or other materials provided with the distribution.
310 * * Neither the name of the original author; nor the names of any contributors
311 * may be used to endorse or promote products derived from this software
312 * without specific prior written permission.
315 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
316 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
317 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
318 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
319 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
320 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
321 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
322 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
323 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
324 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
325 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.