OpenMoHAA 0.82.0
Loading...
Searching...
No Matches
hashtable.h
1 #ifndef _HASHTABLE_H
2#define _HASHTABLE_H
3
4/* File: hashtable.h
5 * ------------------
6 * Defines the interface for the HashTable ADT.
7 * The HashTable allows the client to store any number of elements of any
8 * type in a hash table for fast storage and retrieval. The client specifies
9 * the size (in bytes) of the elements that will be stored in the table when
10 * it is created. Thereafter the client and the HashTable refer to elements
11 * via (void*) ptrs. The HashTable imposes no upper bound on the number of
12 * elements and deals with all its own memory management.
13 *
14 * The client-supplied information (in the form of the number of buckets
15 * to use and the hashing function to be applied to each element) is employed
16 * to divide elements in buckets with hopefully only few collisions, resulting
17 * in Enter & Lookup performance in constant-time. The HashTable also supports
18 * iterating over all elements by use of mapping function.
19 */
20
21/* Type: HashTable
22 * ----------------
23 * Defines the HashTable type itself. The client can declare variables of type
24 * HashTable, but these variables must be initialized with the result of
25 * TableNew. The HashTable is implemented with pointers, so all client
26 * copies in variables or parameters will be "shallow" -- they will all
27 * actually point to the same HashTable structure. Only calls to TableNew
28 * create new tables. The struct declaration below is "incomplete"- the
29 * implementation details are literally not visible in the client .h file.
30 */
31typedef struct HashImplementation *HashTable;
32
33
34/* TableHashFn
35 * -----------
36 * TableHashFn is a pointer to a client-supplied function which the
37 * HashTable uses to hash elements. The hash function takes a (const void*)
38 * pointer to an element and the number of buckets and returns an int,
39 * which represents the hash code for this element. The returned hash code
40 * should be within the range 0 to numBuckets-1 and should be stable (i.e.
41 * an element's hash code should not change over time).
42 * For best performance, the hash function should be designed to
43 * uniformly distribute elements over the available number of buckets.
44 */
45typedef int (*TableHashFn)(const void *elem, int numBuckets);
46
47
48/* TableCompareFn
49 * --------------
50 * TableCompareFn is a pointer to a client-supplied function which the
51 * HashTable uses to compare elements. The comparator takes two
52 * (const void*) pointers (these will point to elements) and returns an int.
53 * The comparator should indicate the ordering of the two elements
54 * using the same convention as the strcmp library function:
55 * If elem1 is "less than" elem2, return a negative number.
56 * If elem1 is "greater than" elem2, return a positive number.
57 * If the two elements are "equal", return 0.
58 */
59#if defined(WIN32)
60// explicitly set __cdecl so that Win devs can change default calling convention
61typedef int (__cdecl *TableCompareFn)(const void *elem1, const void *elem2);
62#else
63typedef int (*TableCompareFn)(const void *elem1, const void *elem2);
64#endif
65
66 /* TableMapFn
67 * ----------
68 * TableMapFn defines the space of functions that can be used to map over
69 * the elements in a HashTable. A map function is called with a pointer to
70 * the element and a client data pointer passed in from the original caller.
71 */
72typedef void (*TableMapFn)(void *elem, void *clientData);
73
74 /* TableMapFn2
75 * ----------
76 * Same as TableMapFn, but can return 0 to stop the mapping.
77 * Used by TableMap2.
78 */
79typedef int (*TableMapFn2)(void *elem, void *clientData);
80
81
82/* TableElementFreeFn
83 * ------------------
84 * TableElementFreeFn defines the space of functions that can be used as the
85 * clean-up function for each element as it is deleted from the array
86 * or when the entire array of elements is freed. The cleanup function is
87 * called with a pointer to an element about to be deleted.
88 */
89typedef void (*TableElementFreeFn)(void *elem);
90
91#ifdef __cplusplus
92extern "C" {
93#endif
94
95/* TableNew
96 * --------
97 * Creates a new HashTable with no entries and returns it. The elemSize
98 * parameter specifies the number of bytes that a single element of the
99 * table should take up. For example, if you want to store elements of type
100 * Binky, you would pass sizeof(Binky) as this parameter. An assert is
101 * raised if this size is not greater than 0.
102 *
103 * The nBuckets parameter specifies the number of buckets that the elements
104 * will be partitioned into. Once a HashTable is created, this number does
105 * not change. The nBuckets parameter must be in synch with the behavior of
106 * the hashFn, which must return a hash code between 0 and nBuckets-1.
107 * The hashFn parameter specifies the function that is called to retrieve the
108 * hash code for a given element. See the type declaration of TableHashFn
109 * above for more information. An assert is raised if nBuckets is not
110 * greater than 0.
111 *
112 * The compFn is used for testing equality between elements. See the
113 * type declaration for TableCompareFn above for more information.
114 *
115 * The elemFreeFn is the function that will be called on an element that is
116 * about to be overwritten (by a new entry in TableEnter) or on each element
117 * in the table when the entire table is being freed (using TableFree). This
118 * function is your chance to do any deallocation/cleanup required,
119 * (such as freeing any pointers contained in the element). The client can pass
120 * NULL for the cleanupFn if the elements don't require any handling on free.
121 * An assert is raised if either the hash or compare functions are NULL.
122 *
123 * nChains is the number of chains to allocate initially in each bucket
124 *
125 */
126
127HashTable TableNew(int elemSize, int nBuckets,
128 TableHashFn hashFn, TableCompareFn compFn,
129 TableElementFreeFn freeFn);
130
131HashTable TableNew2(int elemSize, int nBuckets, int nChains,
132 TableHashFn hashFn, TableCompareFn compFn,
133 TableElementFreeFn freeFn);
134
135
136 /* TableFree
137 * ----------
138 * Frees up all the memory for the table and its elements. It DOES NOT
139 * automatically free memory owned by pointers embedded in the elements. This
140 * would require knowledge of the structure of the elements which the HashTable
141 * does not have. However, it will iterate over the elements calling
142 * the elementFreeFn earlier supplied to TableNew and therefore, the client,
143 * who knows what the elements are,can do the appropriate deallocation of any
144 * embedded pointers through that function.
145 * After calling this, the value of what table points to is undefined.
146 */
147void TableFree(HashTable table);
148
149
150/* TableCount
151 * ----------
152 * Returns the number of elements currently in the table.
153 */
154int TableCount(HashTable table);
155
156
157
158/* TableEnter
159 * ----------
160 * Enters a new element into the table. Uses the hash function to determine
161 * which bucket to place the new element. Its contents are copied from the
162 * memory pointed to by newElem. If there is already an element in the table
163 * which is determined to be equal (using the comparison function) this will
164 * use the contents of the new element to replace the previous element,
165 * calling the free function on the replaced element.
166 */
167void TableEnter(HashTable table, const void *newElem);
168
169/* TableRemove
170 * ----------
171 * Remove a element frin the table. If the element does not exist
172 * the function returns 0. If it exists, it returns 1 and calls the
173 * free function on the removed element.
174 */
175int TableRemove(HashTable table, const void *delElem);
176
177
178/* TableLookup
179 * ----------
180 * Returns a pointer to the table element which matches the elemKey parameter
181 * (equality is determined by the comparison function). If there is no
182 * matching element, returns NULL. Calling this function does not
183 * re-arrange or change contents of the table or modify elemKey in any way.
184 */
185void *TableLookup(HashTable table, const void *elemKey);
186
187
188
189/* TableMap
190 * -----------
191 * Iterates through each element in the table (in any order) and calls the
192 * function fn for that element. The function is called with the address of
193 * the table element and the clientData pointer. The clientData value allows
194 * the client to pass extra state information to the client-supplied function,
195 * if necessary. If no client data is required, this argument should be NULL.
196 * An assert is raised if the map function is NULL.
197 */
198void TableMap(HashTable table, TableMapFn fn, void *clientData);
199
200/* TableMapSafe
201 * -----------
202 * Same as TableMap, but allows elements to be freed during the mapping.
203 */
204void TableMapSafe(HashTable table, TableMapFn fn, void *clientData);
205
206/* TableMap2
207 * -----------
208 * Same as TableMap, but allows the mapping to be stopped by returning 0
209 * from the mapping function. If the mapping was stopped, the element
210 * it was stopped at will be returned. If it wasn't stopped, then NULL
211 * will be returned.
212 */
213void * TableMap2(HashTable table, TableMapFn2 fn, void *clientData);
214
215/* TableMapSafe2
216 * -----------
217 * Same as TableMap2, but allows elements to be freed during the mapping.
218 */
219void * TableMapSafe2(HashTable table, TableMapFn2 fn, void *clientData);
220
221/* TableClear
222 * -----------
223 * Clears all the elements in the table without freeing it
224 */
225void TableClear(HashTable table);
226
227#ifdef __cplusplus
228}
229#endif
230
231#endif //_HASHTABLE_H
Definition hashtable.c:35