OpenMoHAA 0.82.1
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 */
59typedef int (*TableCompareFn)(const void *elem1, const void *elem2);
60 /* TableMapFn
61 * ----------
62 * TableMapFn defines the space of functions that can be used to map over
63 * the elements in a HashTable. A map function is called with a pointer to
64 * the element and a client data pointer passed in from the original caller.
65 */
66typedef void (*TableMapFn)(void *elem, void *clientData);
67
68 /* TableMapFn2
69 * ----------
70 * Same as TableMapFn, but can return 0 to stop the mapping.
71 * Used by TableMap2.
72 */
73typedef int (*TableMapFn2)(void *elem, void *clientData);
74
75
76/* TableElementFreeFn
77 * ------------------
78 * TableElementFreeFn defines the space of functions that can be used as the
79 * clean-up function for each element as it is deleted from the array
80 * or when the entire array of elements is freed. The cleanup function is
81 * called with a pointer to an element about to be deleted.
82 */
83typedef void (*TableElementFreeFn)(void *elem);
84
85#ifdef __cplusplus
86extern "C" {
87#endif
88
89/* TableNew
90 * --------
91 * Creates a new HashTable with no entries and returns it. The elemSize
92 * parameter specifies the number of bytes that a single element of the
93 * table should take up. For example, if you want to store elements of type
94 * Binky, you would pass sizeof(Binky) as this parameter. An assert is
95 * raised if this size is not greater than 0.
96 *
97 * The nBuckets parameter specifies the number of buckets that the elements
98 * will be partitioned into. Once a HashTable is created, this number does
99 * not change. The nBuckets parameter must be in synch with the behavior of
100 * the hashFn, which must return a hash code between 0 and nBuckets-1.
101 * The hashFn parameter specifies the function that is called to retrieve the
102 * hash code for a given element. See the type declaration of TableHashFn
103 * above for more information. An assert is raised if nBuckets is not
104 * greater than 0.
105 *
106 * The compFn is used for testing equality between elements. See the
107 * type declaration for TableCompareFn above for more information.
108 *
109 * The elemFreeFn is the function that will be called on an element that is
110 * about to be overwritten (by a new entry in TableEnter) or on each element
111 * in the table when the entire table is being freed (using TableFree). This
112 * function is your chance to do any deallocation/cleanup required,
113 * (such as freeing any pointers contained in the element). The client can pass
114 * NULL for the cleanupFn if the elements don't require any handling on free.
115 * An assert is raised if either the hash or compare functions are NULL.
116 *
117 * nChains is the number of chains to allocate initially in each bucket
118 *
119 */
120
121HashTable TableNew(int elemSize, int nBuckets,
122 TableHashFn hashFn, TableCompareFn compFn,
123 TableElementFreeFn freeFn);
124
125HashTable TableNew2(int elemSize, int nBuckets, int nChains,
126 TableHashFn hashFn, TableCompareFn compFn,
127 TableElementFreeFn freeFn);
128
129
130 /* TableFree
131 * ----------
132 * Frees up all the memory for the table and its elements. It DOES NOT
133 * automatically free memory owned by pointers embedded in the elements. This
134 * would require knowledge of the structure of the elements which the HashTable
135 * does not have. However, it will iterate over the elements calling
136 * the elementFreeFn earlier supplied to TableNew and therefore, the client,
137 * who knows what the elements are,can do the appropriate deallocation of any
138 * embedded pointers through that function.
139 * After calling this, the value of what table points to is undefined.
140 */
141void TableFree(HashTable table);
142
143
144/* TableCount
145 * ----------
146 * Returns the number of elements currently in the table.
147 */
148int TableCount(HashTable table);
149
150
151
152/* TableEnter
153 * ----------
154 * Enters a new element into the table. Uses the hash function to determine
155 * which bucket to place the new element. Its contents are copied from the
156 * memory pointed to by newElem. If there is already an element in the table
157 * which is determined to be equal (using the comparison function) this will
158 * use the contents of the new element to replace the previous element,
159 * calling the free function on the replaced element.
160 */
161void TableEnter(HashTable table, const void *newElem);
162
163/* TableRemove
164 * ----------
165 * Remove a element frin the table. If the element does not exist
166 * the function returns 0. If it exists, it returns 1 and calls the
167 * free function on the removed element.
168 */
169int TableRemove(HashTable table, const void *delElem);
170
171
172/* TableLookup
173 * ----------
174 * Returns a pointer to the table element which matches the elemKey parameter
175 * (equality is determined by the comparison function). If there is no
176 * matching element, returns NULL. Calling this function does not
177 * re-arrange or change contents of the table or modify elemKey in any way.
178 */
179void *TableLookup(HashTable table, const void *elemKey);
180
181
182
183/* TableMap
184 * -----------
185 * Iterates through each element in the table (in any order) and calls the
186 * function fn for that element. The function is called with the address of
187 * the table element and the clientData pointer. The clientData value allows
188 * the client to pass extra state information to the client-supplied function,
189 * if necessary. If no client data is required, this argument should be NULL.
190 * An assert is raised if the map function is NULL.
191 */
192void TableMap(HashTable table, TableMapFn fn, void *clientData);
193
194/* TableMapSafe
195 * -----------
196 * Same as TableMap, but allows elements to be freed during the mapping.
197 */
198void TableMapSafe(HashTable table, TableMapFn fn, void *clientData);
199
200/* TableMap2
201 * -----------
202 * Same as TableMap, but allows the mapping to be stopped by returning 0
203 * from the mapping function. If the mapping was stopped, the element
204 * it was stopped at will be returned. If it wasn't stopped, then NULL
205 * will be returned.
206 */
207void * TableMap2(HashTable table, TableMapFn2 fn, void *clientData);
208
209/* TableMapSafe2
210 * -----------
211 * Same as TableMap2, but allows elements to be freed during the mapping.
212 */
213void * TableMapSafe2(HashTable table, TableMapFn2 fn, void *clientData);
214
215/* TableClear
216 * -----------
217 * Clears all the elements in the table without freeing it
218 */
219void TableClear(HashTable table);
220
221#ifdef __cplusplus
222}
223#endif
224
225#endif //_HASHTABLE_H
Definition hashtable.c:39