2323 * - SH_DEFINE - if defined function definitions are generated
2424 * - SH_SCOPE - in which scope (e.g. extern, static inline) do function
2525 *declarations reside
26+ * - SH_USE_NONDEFAULT_ALLOCATOR - if defined no element allocator functions
27+ * are defined, so you can supply your own
2628 * The following parameters are only relevant when SH_DEFINE is defined:
2729 * - SH_KEY - name of the element in SH_ELEMENT_TYPE containing the hash key
2830 * - SH_EQUAL(table, a, b) - compare two table keys
7779#define SH_START_ITERATE SH_MAKE_NAME(start_iterate)
7880#define SH_START_ITERATE_AT SH_MAKE_NAME(start_iterate_at)
7981#define SH_ITERATE SH_MAKE_NAME(iterate)
82+ #define SH_ALLOCATE SH_MAKE_NAME(allocate)
83+ #define SH_FREE SH_MAKE_NAME(free)
8084#define SH_STAT SH_MAKE_NAME(stat)
8185
8286/* internal helper functions (no externally visible prototypes) */
8791#define SH_INITIAL_BUCKET SH_MAKE_NAME(initial_bucket)
8892#define SH_ENTRY_HASH SH_MAKE_NAME(entry_hash)
8993
90- /* Allocation function for hash table elements */
91- #ifndef SIMPLEHASH_TYPEDEFS
92- #define SIMPLEHASH_TYPEDEFS
93- typedef void * (* simplehash_allocate ) (Size size ,void * args );
94- typedef void (* simplehash_free ) (void * pointer ,void * args );
95- #endif
96-
9794/* generate forward declarations necessary to use the hash table */
9895#ifdef SH_DECLARE
9996
@@ -119,11 +116,6 @@ typedef struct SH_TYPE
119116/* hash buckets */
120117SH_ELEMENT_TYPE * data ;
121118
122- /* Allocation and free functions, and the associated context. */
123- simplehash_allocate element_alloc ;
124- simplehash_free element_free ;
125- void * element_args ;
126-
127119/* memory context to use for allocations */
128120MemoryContext ctx ;
129121
@@ -145,8 +137,7 @@ typedef struct SH_ITERATOR
145137}SH_ITERATOR ;
146138
147139/* externally visible function prototypes */
148- SH_SCOPE SH_TYPE * SH_CREATE (MemoryContext ctx ,uint32 nelements ,
149- simplehash_allocate allocfunc ,simplehash_free freefunc ,void * args );
140+ SH_SCOPE SH_TYPE * SH_CREATE (MemoryContext ctx ,uint32 nelements );
150141SH_SCOPE void SH_DESTROY (SH_TYPE * tb );
151142SH_SCOPE void SH_GROW (SH_TYPE * tb ,uint32 newsize );
152143SH_SCOPE SH_ELEMENT_TYPE * SH_INSERT (SH_TYPE * tb ,SH_KEY_TYPE key ,bool * found );
@@ -289,23 +280,25 @@ SH_ENTRY_HASH(SH_TYPE *tb, SH_ELEMENT_TYPE * entry)
289280#endif
290281}
291282
283+ #ifndef SH_USE_NONDEFAULT_ALLOCATOR
284+
292285/* default memory allocator function */
293- static void *
294- SH_DEFAULT_ALLOC ( Size size , void * args )
286+ static inline void *
287+ SH_ALLOCATE ( SH_TYPE * type , Size size )
295288{
296- MemoryContext context = (MemoryContext )args ;
297-
298- return MemoryContextAllocExtended (context ,size ,
289+ return MemoryContextAllocExtended (type -> ctx ,size ,
299290MCXT_ALLOC_HUGE |MCXT_ALLOC_ZERO );
300291}
301292
302293/* default memory free function */
303- static void
304- SH_DEFAULT_FREE ( void * pointer ,void * args )
294+ static inline void
295+ SH_FREE ( SH_TYPE * type ,void * pointer )
305296{
306297pfree (pointer );
307298}
308299
300+ #endif
301+
309302/*
310303 * Create a hash table with enough space for `nelements` distinct members.
311304 * Memory for the hash table is allocated from the passed-in context. If
@@ -316,8 +309,7 @@ SH_DEFAULT_FREE(void *pointer, void *args)
316309 * the passed-in context.
317310 */
318311SH_SCOPE SH_TYPE *
319- SH_CREATE (MemoryContext ctx ,uint32 nelements ,simplehash_allocate allocfunc ,
320- simplehash_free freefunc ,void * args )
312+ SH_CREATE (MemoryContext ctx ,uint32 nelements )
321313{
322314SH_TYPE * tb ;
323315uint64 size ;
@@ -330,22 +322,7 @@ SH_CREATE(MemoryContext ctx, uint32 nelements, simplehash_allocate allocfunc,
330322
331323SH_COMPUTE_PARAMETERS (tb ,size );
332324
333- if (allocfunc == NULL )
334- {
335- tb -> element_alloc = SH_DEFAULT_ALLOC ;
336- tb -> element_free = SH_DEFAULT_FREE ;
337- tb -> element_args = ctx ;
338- }
339- else
340- {
341- tb -> element_alloc = allocfunc ;
342- tb -> element_free = freefunc ;
343-
344- tb -> element_args = args ;
345- }
346-
347- tb -> data = tb -> element_alloc (sizeof (SH_ELEMENT_TYPE )* tb -> size ,
348- tb -> element_args );
325+ tb -> data = SH_ALLOCATE (tb ,sizeof (SH_ELEMENT_TYPE )* tb -> size );
349326
350327return tb ;
351328}
@@ -354,7 +331,7 @@ SH_CREATE(MemoryContext ctx, uint32 nelements, simplehash_allocate allocfunc,
354331SH_SCOPE void
355332SH_DESTROY (SH_TYPE * tb )
356333{
357- tb -> element_free (tb -> data ,tb -> element_args );
334+ SH_FREE (tb ,tb -> data );
358335pfree (tb );
359336}
360337
@@ -382,8 +359,7 @@ SH_GROW(SH_TYPE *tb, uint32 newsize)
382359/* compute parameters for new table */
383360SH_COMPUTE_PARAMETERS (tb ,newsize );
384361
385- tb -> data = tb -> element_alloc (sizeof (SH_ELEMENT_TYPE )* tb -> size ,
386- tb -> element_args );
362+ tb -> data = SH_ALLOCATE (tb ,sizeof (SH_ELEMENT_TYPE )* tb -> size );
387363
388364newdata = tb -> data ;
389365
@@ -469,7 +445,7 @@ SH_GROW(SH_TYPE *tb, uint32 newsize)
469445}
470446}
471447
472- tb -> element_free ( olddata , tb -> element_args );
448+ SH_FREE ( tb , olddata );
473449}
474450
475451/*
@@ -888,6 +864,7 @@ SH_STAT(SH_TYPE *tb)
888864#undef SH_DEFINE
889865#undef SH_GET_HASH
890866#undef SH_STORE_HASH
867+ #undef SH_USE_NONDEFAULT_ALLOCATOR
891868
892869/* undefine locally declared macros */
893870#undef SH_MAKE_PREFIX
@@ -914,6 +891,8 @@ SH_STAT(SH_TYPE *tb)
914891#undef SH_START_ITERATE
915892#undef SH_START_ITERATE_AT
916893#undef SH_ITERATE
894+ #undef SH_ALLOCATE
895+ #undef SH_FREE
917896#undef SH_STAT
918897
919898/* internal function names */