1
1
/*
2
2
* simplehash.h
3
3
*
4
- * Hash table implementation which will be specialized to user-defined
5
- * types, by including this file to generate the required code. It's
6
- * probably not worthwhile to do so for hash tables that aren't performance
7
- * or space sensitive.
4
+ * When included this file generates a "templated" (by way of macros)
5
+ * open-addressing hash table implementation specialized to user-defined
6
+ * types.
7
+ *
8
+ * It's probably not worthwhile to generate such a specialized implementation
9
+ * for hash tables that aren't performance or space sensitive.
10
+ *
11
+ * Compared to dynahash, simplehash has the following benefits:
12
+ *
13
+ * - Due to the "templated" code generation has known structure sizes and no
14
+ * indirect function calls (which show up substantially in dynahash
15
+ * profiles). These features considerably increase speed for small
16
+ * entries.
17
+ * - Open addressing has better CPU cache behavior than dynahash's chained
18
+ * hashtables.
19
+ * - The generated interface is type-safe and easier to use than dynahash,
20
+ * though at the cost of more complex setup.
21
+ * - Allocates memory in a MemoryContext or another allocator with a
22
+ * malloc/free style interface (which isn't easily usable in a shared
23
+ * memory context)
24
+ * - Does not require the overhead of a separate memory context.
8
25
*
9
26
* Usage notes:
10
27
*
34
51
* - SH_STORE_HASH - if defined the hash is stored in the elements
35
52
* - SH_GET_HASH(tb, a) - return the field to store the hash in
36
53
*
54
+ * The element type is required to contain a "uint32 status" member.
55
+ *
56
+ * While SH_STORE_HASH (and subsequently SH_GET_HASH) are optional, because
57
+ * the hash table implementation needs to compare hashes to move elements
58
+ * (particularly when growing the hash), it's preferable, if possible, to
59
+ * store the element's hash in the element's data type. If the hash is so
60
+ * stored, the hash table will also compare hashes before calling SH_EQUAL
61
+ * when comparing two keys.
62
+ *
63
+ * For convenience the hash table create functions accept a void pointer
64
+ * that will be stored in the hash table type's member private_data. This
65
+ * allows callbacks to reference caller provided data.
66
+ *
37
67
* For examples of usage look at tidbitmap.c (file local definition) and
38
68
* execnodes.h/execGrouping.c (exposed declaration, file local
39
69
* implementation).
@@ -149,24 +179,59 @@ typedef struct SH_ITERATOR
149
179
150
180
/* externally visible function prototypes */
151
181
#ifdef SH_RAW_ALLOCATOR
182
+ /* <prefix>_hash <prefix>_create(uint32 nelements, void *private_data) */
152
183
SH_SCOPE SH_TYPE * SH_CREATE (uint32 nelements , void * private_data );
153
184
#else
185
+ /*
186
+ * <prefix>_hash <prefix>_create(MemoryContext ctx, uint32 nelements,
187
+ * void *private_data)
188
+ */
154
189
SH_SCOPE SH_TYPE * SH_CREATE (MemoryContext ctx , uint32 nelements ,
155
190
void * private_data );
156
191
#endif
192
+
193
+ /* void <prefix>_destroy(<prefix>_hash *tb) */
157
194
SH_SCOPE void SH_DESTROY (SH_TYPE * tb );
195
+
196
+ /* void <prefix>_reset(<prefix>_hash *tb) */
158
197
SH_SCOPE void SH_RESET (SH_TYPE * tb );
198
+
199
+ /* void <prefix>_grow(<prefix>_hash *tb) */
159
200
SH_SCOPE void SH_GROW (SH_TYPE * tb , uint32 newsize );
201
+
202
+ /* <element> *<prefix>_insert(<prefix>_hash *tb, <key> key, bool *found) */
160
203
SH_SCOPE SH_ELEMENT_TYPE * SH_INSERT (SH_TYPE * tb , SH_KEY_TYPE key , bool * found );
204
+
205
+ /*
206
+ * <element> *<prefix>_insert_hash(<prefix>_hash *tb, <key> key, uint32 hash,
207
+ * bool *found)
208
+ */
161
209
SH_SCOPE SH_ELEMENT_TYPE * SH_INSERT_HASH (SH_TYPE * tb , SH_KEY_TYPE key ,
162
210
uint32 hash , bool * found );
211
+
212
+ /* <element> *<prefix>_lookup(<prefix>_hash *tb, <key> key) */
163
213
SH_SCOPE SH_ELEMENT_TYPE * SH_LOOKUP (SH_TYPE * tb , SH_KEY_TYPE key );
214
+
215
+ /* <element> *<prefix>_lookup_hash(<prefix>_hash *tb, <key> key, uint32 hash) */
164
216
SH_SCOPE SH_ELEMENT_TYPE * SH_LOOKUP_HASH (SH_TYPE * tb , SH_KEY_TYPE key ,
165
217
uint32 hash );
218
+
219
+ /* bool <prefix>_delete(<prefix>_hash *tb, <key> key) */
166
220
SH_SCOPE bool SH_DELETE (SH_TYPE * tb , SH_KEY_TYPE key );
221
+
222
+ /* void <prefix>_start_iterate(<prefix>_hash *tb, <prefix>_iterator *iter) */
167
223
SH_SCOPE void SH_START_ITERATE (SH_TYPE * tb , SH_ITERATOR * iter );
224
+
225
+ /*
226
+ * void <prefix>_start_iterate_at(<prefix>_hash *tb, <prefix>_iterator *iter,
227
+ * uint32 at)
228
+ */
168
229
SH_SCOPE void SH_START_ITERATE_AT (SH_TYPE * tb , SH_ITERATOR * iter , uint32 at );
230
+
231
+ /* <element> *<prefix>_iterate(<prefix>_hash *tb, <prefix>_iterator *iter) */
169
232
SH_SCOPE SH_ELEMENT_TYPE * SH_ITERATE (SH_TYPE * tb , SH_ITERATOR * iter );
233
+
234
+ /* void <prefix>_stat(<prefix>_hash *tb */
170
235
SH_SCOPE void SH_STAT (SH_TYPE * tb );
171
236
172
237
#endif /* SH_DECLARE */
0 commit comments