Fixes spin_trylock()
[akaros.git] / kern / include / hashtable.h
1 /* Copyright (C) 2002, 2004 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
2  * 
3  * Modified 2009 by Barret Rhoden <brho@cs.berkeley.edu>
4  * Changes include:
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.
10  *   - hash for each */
11
12 #ifndef __ROS_KERN_HASHTABLE_H__
13 #define __ROS_KERN_HASHTABLE_H__
14
15 #ifdef __DEPUTY__
16 #pragma nodeputy
17 #endif
18
19 #ifdef __SHARC__
20 #pragma nosharc
21 #endif
22
23 #include <ros/common.h>
24
25 /*****************************************************************************/
26 typedef struct hash_entry
27 {
28     void *k, *v;
29     size_t h;
30     struct hash_entry *next;
31 } hash_entry_t;
32
33 typedef struct hashtable {
34     size_t tablelength;
35     hash_entry_t **table;
36     size_t entrycount;
37     size_t loadlimit;
38     size_t primeindex;
39     size_t (*hashfn) (void *k);
40     ssize_t (*eqfn) (void *k1, void *k2);
41 } hashtable_t;
42
43 size_t hash(struct hashtable *h, void *k);
44 static inline size_t indexFor(unsigned int tablelength, unsigned int hashvalue)
45 {
46         return (hashvalue % tablelength);
47 };
48
49 /*****************************************************************************/
50
51 /* Example of use:
52  *              hashtable_init(); // Do this once during kernel initialization
53  *
54  *      struct hashtable  *h;
55  *      struct some_key   *k;
56  *      struct some_value *v;
57  *
58  *      static size_t         hash_from_key_fn( void *k );
59  *      static ssize_t        keys_equal_fn ( void *key1, void *key2 );
60  *
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));
64  *
65  *      (initialise k and v to suitable values)
66  * 
67  *      if (! hashtable_insert(h,k,v) )
68  *      {     panic("Hashtable broken...\n");       }
69  *
70  *      if (NULL == (found = hashtable_search(h,k) ))
71  *      {    printk("not found!");                  }
72  *
73  *      if (NULL == (found = hashtable_remove(h,k) ))
74  *      {    printk("Not found\n");                 }
75  *
76  */
77
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.
80  * 
81  * Example:
82  *
83  * Insert this at the start of your file:
84  *
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);
88  *
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).
94  *
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.
99  *
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
105  *
106  */
107
108 /* Call this once on bootup, after initializing the slab allocator.  */
109 void hashtable_init(void);
110
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);
114
115 /*****************************************************************************
116  * create_hashtable
117    
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
123  */
124
125 hashtable_t *
126 create_hashtable(size_t minsize,
127                  size_t (*hashfunction) (void*),
128                  ssize_t (*key_eq_fn) (void*,void*));
129
130 /*****************************************************************************
131  * hashtable_insert
132    
133  * @name        hashtable_insert
134  * @param   h   the hashtable to insert into
135  * @param   k   the key
136  * @param   v   the value
137  * @return      non-zero for successful insertion
138  *
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.
141  *
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.
147  */
148
149 ssize_t 
150 hashtable_insert(hashtable_t *h, void *k, void *v);
151
152 #define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
153 ssize_t fnname (hashtable_t *h, keytype *k, valuetype *v) \
154 { \
155     return hashtable_insert(h,k,v); \
156 }
157
158 /*****************************************************************************
159  * hashtable_search
160    
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
165  */
166
167 void *
168 hashtable_search(hashtable_t *h, void *k);
169
170 #define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
171 valuetype * fnname (hashtable_t *h, keytype *k) \
172 { \
173     return (valuetype *) (hashtable_search(h,k)); \
174 }
175
176 /*****************************************************************************
177  * hashtable_remove
178    
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
183  *
184  * Caller ought to free the key, if appropriate.
185  */
186
187 void * /* returns value */
188 hashtable_remove(hashtable_t *h, void *k);
189
190 #define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
191 valuetype * fnname (hashtable_t *h, keytype *k) \
192 { \
193     return (valuetype *) (hashtable_remove(h,k)); \
194 }
195
196
197 /*****************************************************************************
198  * hashtable_count
199    
200  * @name        hashtable_count
201  * @param   h   the hashtable
202  * @return      the number of items stored in the hashtable
203  */
204
205 size_t
206 hashtable_count(hashtable_t *h);
207
208
209 /*****************************************************************************
210  * hashtable_destroy
211    
212  * @name        hashtable_destroy
213  * @param   h   the hashtable
214  *
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)).
218  *
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.
221  */
222
223 void
224 hashtable_destroy(hashtable_t *h);
225
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 {
231     hashtable_t *h;
232     hash_entry_t *e;
233     hash_entry_t *parent;
234     size_t index;
235 } hashtable_itr_t;
236
237 /*****************************************************************************/
238 /* hashtable_iterator.  Be sure to kfree this when you are done.
239  */
240
241 hashtable_itr_t *
242 hashtable_iterator(hashtable_t *h);
243
244 /*****************************************************************************/
245 /* hashtable_iterator_key
246  * - return the key of the (key,value) pair at the current position
247  *
248  * Keep this in sync with the non-externed version in the .c */
249
250 extern inline void *
251 hashtable_iterator_key(hashtable_itr_t *i)
252 {
253     return i->e->k;
254 }
255
256 /*****************************************************************************/
257 /* value - return the value of the (key,value) pair at the current position
258  *
259  * Keep this in sync with the non-externed version in the .c */
260
261 extern inline void *
262 hashtable_iterator_value(hashtable_itr_t *i)
263 {
264     return i->e->v;
265 }
266
267 /*****************************************************************************/
268 /* advance - advance the iterator to the next element
269  *           returns zero if advanced to end of table */
270
271 ssize_t
272 hashtable_iterator_advance(hashtable_itr_t *itr);
273
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 */
279
280 ssize_t
281 hashtable_iterator_remove(hashtable_itr_t *itr);
282
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. */
288 ssize_t
289 hashtable_iterator_search(hashtable_itr_t *itr,
290                           hashtable_t *h, void *k);
291
292 #define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
293 ssize_t fnname (hashtable_itr_t *i, hashtable_t *h, keytype *k) \
294 { \
295     return (hashtable_iterator_search(i,h,k)); \
296 }
297
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*));
302
303 #endif /* __ROS_KERN_HASHTABLE_H__ */
304
305 /*
306  * Copyright (c) 2002, 2004, Christopher Clark
307  * All rights reserved.
308  * 
309  * Redistribution and use in source and binary forms, with or without
310  * modification, are permitted provided that the following conditions
311  * are met:
312  * 
313  * * Redistributions of source code must retain the above copyright
314  * notice, this list of conditions and the following disclaimer.
315  * 
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.
319  * 
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.
323  * 
324  * 
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.
336 */