perf: Clean up perf_{session,alloc} management
[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 #pragma once
13
14 #include <ros/common.h>
15
16 /*****************************************************************************/
17 typedef struct hash_entry
18 {
19     void *k, *v;
20     size_t h;
21     struct hash_entry *next;
22 } hash_entry_t;
23
24 typedef struct hashtable {
25     size_t tablelength;
26     hash_entry_t **table;
27     size_t entrycount;
28     size_t loadlimit;
29     size_t primeindex;
30     size_t (*hashfn) (void *k);
31     ssize_t (*eqfn) (void *k1, void *k2);
32 } hashtable_t;
33
34 static inline size_t indexFor(unsigned int tablelength, unsigned int hashvalue)
35 {
36         return (hashvalue % tablelength);
37 };
38
39 /*****************************************************************************/
40
41 /* Example of use:
42  *              hashtable_init(); // Do this once during kernel initialization
43  *
44  *      struct hashtable  *h;
45  *      struct some_key   *k;
46  *      struct some_value *v;
47  *
48  *      static size_t         hash_from_key_fn( void *k );
49  *      static ssize_t        keys_equal_fn ( void *key1, void *key2 );
50  *
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));
54  *
55  *      (initialise k and v to suitable values)
56  *
57  *      if (! hashtable_insert(h,k,v) )
58  *      {     panic("Hashtable broken...\n");       }
59  *
60  *      if (NULL == (found = hashtable_search(h,k) ))
61  *      {    printk("not found!");                  }
62  *
63  *      if (NULL == (found = hashtable_remove(h,k) ))
64  *      {    printk("Not found\n");                 }
65  *
66  */
67
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.
70  *
71  * Example:
72  *
73  * Insert this at the start of your file:
74  *
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);
78  *
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).
84  *
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.
89  *
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
95  *
96  */
97
98 /* Call this once on bootup, after initializing the slab allocator.  */
99 void hashtable_init(void);
100
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);
104
105 /*****************************************************************************
106  * create_hashtable
107
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
113  */
114
115 hashtable_t *
116 create_hashtable(size_t minsize,
117                  size_t (*hashfunction) (void*),
118                  ssize_t (*key_eq_fn) (void*,void*));
119
120 /*****************************************************************************
121  * hashtable_insert
122
123  * @name        hashtable_insert
124  * @param   h   the hashtable to insert into
125  * @param   k   the key
126  * @param   v   the value
127  * @return      non-zero for successful insertion
128  *
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.
131  *
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.
137  */
138
139 ssize_t
140 hashtable_insert(hashtable_t *h, void *k, void *v);
141
142 #define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
143 ssize_t fnname (hashtable_t *h, keytype *k, valuetype *v) \
144 { \
145     return hashtable_insert(h,k,v); \
146 }
147
148 /*****************************************************************************
149  * hashtable_search
150
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
155  */
156
157 void *
158 hashtable_search(hashtable_t *h, void *k);
159
160 #define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
161 valuetype * fnname (hashtable_t *h, keytype *k) \
162 { \
163     return (valuetype *) (hashtable_search(h,k)); \
164 }
165
166 /*****************************************************************************
167  * hashtable_remove
168
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
173  *
174  * Caller ought to free the key, if appropriate.
175  */
176
177 void * /* returns value */
178 hashtable_remove(hashtable_t *h, void *k);
179
180 #define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
181 valuetype * fnname (hashtable_t *h, keytype *k) \
182 { \
183     return (valuetype *) (hashtable_remove(h,k)); \
184 }
185
186
187 /*****************************************************************************
188  * hashtable_count
189
190  * @name        hashtable_count
191  * @param   h   the hashtable
192  * @return      the number of items stored in the hashtable
193  */
194
195 size_t
196 hashtable_count(hashtable_t *h);
197
198
199 /*****************************************************************************
200  * hashtable_destroy
201
202  * @name        hashtable_destroy
203  * @param   h   the hashtable
204  *
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)).
208  *
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.
211  */
212
213 void
214 hashtable_destroy(hashtable_t *h);
215
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 {
221     hashtable_t *h;
222     hash_entry_t *e;
223     hash_entry_t *parent;
224     size_t index;
225 } hashtable_itr_t;
226
227 /*****************************************************************************/
228 /* hashtable_iterator.  Be sure to kfree this when you are done.
229  */
230
231 hashtable_itr_t *
232 hashtable_iterator(hashtable_t *h);
233
234 /*****************************************************************************/
235 /* hashtable_iterator_key
236  * - return the key of the (key,value) pair at the current position
237  *
238  * Keep this in sync with the non-externed version in the .c */
239
240 extern inline void *
241 hashtable_iterator_key(hashtable_itr_t *i)
242 {
243     return i->e->k;
244 }
245
246 /*****************************************************************************/
247 /* value - return the value of the (key,value) pair at the current position
248  *
249  * Keep this in sync with the non-externed version in the .c */
250
251 extern inline void *
252 hashtable_iterator_value(hashtable_itr_t *i)
253 {
254     return i->e->v;
255 }
256
257 /*****************************************************************************/
258 /* advance - advance the iterator to the next element
259  *           returns zero if advanced to end of table */
260
261 ssize_t
262 hashtable_iterator_advance(hashtable_itr_t *itr);
263
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 */
269
270 ssize_t
271 hashtable_iterator_remove(hashtable_itr_t *itr);
272
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. */
278 ssize_t
279 hashtable_iterator_search(hashtable_itr_t *itr,
280                           hashtable_t *h, void *k);
281
282 #define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
283 ssize_t fnname (hashtable_itr_t *i, hashtable_t *h, keytype *k) \
284 { \
285     return (hashtable_iterator_search(i,h,k)); \
286 }
287
288 /* Runs func on each member of the hash table */
289 void hash_for_each(struct hashtable *hash, void func(void *, void *),
290                                    void *opaque);
291 /* Same, but removes the item too */
292 void hash_for_each_remove(struct hashtable *hash, void func(void *, void *),
293                                                   void *opaque);
294
295 /*
296  * Copyright (c) 2002, 2004, Christopher Clark
297  * All rights reserved.
298  *
299  * Redistribution and use in source and binary forms, with or without
300  * modification, are permitted provided that the following conditions
301  * are met:
302  *
303  * * Redistributions of source code must retain the above copyright
304  * notice, this list of conditions and the following disclaimer.
305  *
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.
309  *
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.
313  *
314  *
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.
326 */