1 /* Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
2 /* Modifications made by Jack Lange <jarusl@cs.northwestern.edu> */
4 #ifndef __VMM_HASHTABLE_H__
5 #define __VMM_HASHTABLE_H__
13 * struct hashtable *h;
15 * struct some_value *v;
17 * static uint_t hash_from_key_fn( void *k );
18 * static int keys_equal_fn ( void *key1, void *key2 );
20 * h = create_hashtable(16, hash_from_key_fn, keys_equal_fn);
21 * k = (struct some_key *) malloc(sizeof(struct some_key));
22 * v = (struct some_value *) malloc(sizeof(struct some_value));
24 * (initialise k and v to suitable values)
26 * if (! hashtable_insert(h,k,v) )
29 * if (NULL == (found = hashtable_search(h,k) ))
30 * { printf("not found!"); }
32 * if (NULL == (found = hashtable_remove(h,k) ))
33 * { printf("Not found\n"); }
37 /* Macros may be used to define type-safe(r) hashtable access functions, with
38 * methods specialized to take known key and value types as parameters.
42 * Insert this at the start of your file:
44 * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
45 * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
46 * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
48 * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
49 * These operate just like hashtable_insert etc., with the same parameters,
50 * but their function signatures have 'struct some_key *' rather than
51 * 'void *', and hence can generate compile time errors if your program is
52 * supplying incorrect data as a key (and similarly for value).
54 * Note that the hash and key equality functions passed to create_hashtable
55 * still take 'void *' parameters instead of 'some key *'. This shouldn't be
56 * a difficult issue as they're only defined and passed once, and the other
57 * functions will ensure that only valid keys are supplied to them.
59 * The cost for this checking is increased code size and runtime overhead
60 * - if performance is important, it may be worth switching back to the
61 * unsafe methods once your program has been debugged with the safe methods.
62 * This just requires switching to some simple alternative defines - eg:
63 * #define insert_some hashtable_insert
67 ulong_t hash_long(ulong_t val, uint_t bits);
68 ulong_t hash_buffer(uchar_t * msg, uint_t length);
73 #define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
74 int fnname (struct hashtable * htable, keytype * key, valuetype * value) { \
75 return hashtable_insert(htable, key, value); \
78 #define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
79 valuetype * fnname (struct hashtable * htable, keytype * key) { \
80 return (valuetype *) (hashtable_search(htable, key)); \
83 #define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
84 valuetype * fnname (struct hashtable * htable, keytype * key) { \
85 return (valuetype *) (hashtable_remove(htable, key)); \
93 struct hashtable * create_hashtable(uint_t min_size,
94 uint_t (*hashfunction) (void * key),
95 int (*key_eq_fn) (void * key1, void * key2));
97 void hashtable_destroy(struct hashtable * htable, int free_values);
100 * returns non-zero for successful insertion
102 * This function will cause the table to expand if the insertion would take
103 * the ratio of entries to table size over the maximum load factor.
105 * This function does not check for repeated insertions with a duplicate key.
106 * The value returned when using a duplicate key is undefined -- when
107 * the hashtable changes size, the order of retrieval of duplicate key
108 * entries is reversed.
109 * If in doubt, remove before insert.
111 int hashtable_insert(struct hashtable * htable, void * key, void * value);
113 int hashtable_change(struct hashtable * htable, void * key, void * value);
116 // returns the value associated with the key, or NULL if none found
117 void * hashtable_search(struct hashtable * htable, void * key);
119 // returns the value associated with the key, or NULL if none found
120 void * hashtable_remove(struct hashtable * htable, void * key);
122 uint_t hashtable_count(struct hashtable * htable);
128 #define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
129 int fnname (struct hashtable_itr * iter, struct hashtable * htable, keytype * key) { \
130 return (hashtable_iterator_search(iter, htable, key)); \
135 /*****************************************************************************/
136 /* This struct is only concrete here to allow the inlining of two of the
137 * accessor functions. */
138 struct hashtable_iter {
139 struct hashtable * htable;
140 struct hash_entry * entry;
141 struct hash_entry * parent;
146 struct hashtable_iter * create_hashtable_iterator(struct hashtable * htable);
148 /* - return the value of the (key,value) pair at the current position */
150 void * hashtable_get_iter_key(struct hashtable_iter * iter);
152 return iter->entry->key;
157 /* value - return the value of the (key,value) pair at the current position */
159 void * hashtable_get_iter_value(struct hashtable_iter * iter);
161 return iter->entry->value;
167 /* returns zero if advanced to end of table */
168 int hashtable_iterator_advance(struct hashtable_iter * iter);
170 /* remove current element and advance the iterator to the next element
171 * NB: if you need the value to free it, read it before
172 * removing. ie: beware memory leaks!
173 * returns zero if advanced to end of table
175 int hashtable_iterator_remove(struct hashtable_iter * iter);
178 /* search - overwrite the supplied iterator, to point to the entry
179 * matching the supplied key.
180 * returns zero if not found. */
181 int hashtable_iterator_search(struct hashtable_iter * iter, struct hashtable * htable, void * key);
186 #endif // ! __V3VEE__
189 #endif /* __VMM_HASHTABLE_H__ */
229 * Copyright (c) 2002, Christopher Clark
230 * All rights reserved.
232 * Redistribution and use in source and binary forms, with or without
233 * modification, are permitted provided that the following conditions
236 * * Redistributions of source code must retain the above copyright
237 * notice, this list of conditions and the following disclaimer.
239 * * Redistributions in binary form must reproduce the above copyright
240 * notice, this list of conditions and the following disclaimer in the
241 * documentation and/or other materials provided with the distribution.
243 * * Neither the name of the original author; nor the names of any contributors
244 * may be used to endorse or promote products derived from this software
245 * without specific prior written permission.
248 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
249 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
250 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
251 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
252 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
253 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
254 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
255 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
256 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
257 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
258 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.