Commit c3c4f6e1 authored by Robert Haas's avatar Robert Haas

Revise the way the element allocator for a simplehash is specified.

This method is more elegant and more efficient.

Per a suggestion from Andres Freund, who also briefly reviewed
the patch.
parent 242066cc
...@@ -330,8 +330,7 @@ BuildTupleHashTable(int numCols, AttrNumber *keyColIdx, ...@@ -330,8 +330,7 @@ BuildTupleHashTable(int numCols, AttrNumber *keyColIdx,
else else
hashtable->hash_iv = 0; hashtable->hash_iv = 0;
hashtable->hashtab = hashtable->hashtab = tuplehash_create(tablecxt, nbuckets);
tuplehash_create(tablecxt, nbuckets, NULL, NULL, NULL);
hashtable->hashtab->private_data = hashtable; hashtable->hashtab->private_data = hashtable;
return hashtable; return hashtable;
......
...@@ -244,7 +244,7 @@ tbm_create_pagetable(TIDBitmap *tbm) ...@@ -244,7 +244,7 @@ tbm_create_pagetable(TIDBitmap *tbm)
Assert(tbm->status != TBM_HASH); Assert(tbm->status != TBM_HASH);
Assert(tbm->pagetable == NULL); Assert(tbm->pagetable == NULL);
tbm->pagetable = pagetable_create(tbm->mcxt, 128, NULL, NULL, NULL); tbm->pagetable = pagetable_create(tbm->mcxt, 128);
/* If entry1 is valid, push it into the hashtable */ /* If entry1 is valid, push it into the hashtable */
if (tbm->status == TBM_ONE_PAGE) if (tbm->status == TBM_ONE_PAGE)
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
* - SH_DEFINE - if defined function definitions are generated * - SH_DEFINE - if defined function definitions are generated
* - SH_SCOPE - in which scope (e.g. extern, static inline) do function * - SH_SCOPE - in which scope (e.g. extern, static inline) do function
* declarations reside * declarations reside
* - SH_USE_NONDEFAULT_ALLOCATOR - if defined no element allocator functions
* are defined, so you can supply your own
* The following parameters are only relevant when SH_DEFINE is defined: * The following parameters are only relevant when SH_DEFINE is defined:
* - SH_KEY - name of the element in SH_ELEMENT_TYPE containing the hash key * - SH_KEY - name of the element in SH_ELEMENT_TYPE containing the hash key
* - SH_EQUAL(table, a, b) - compare two table keys * - SH_EQUAL(table, a, b) - compare two table keys
...@@ -77,6 +79,8 @@ ...@@ -77,6 +79,8 @@
#define SH_START_ITERATE SH_MAKE_NAME(start_iterate) #define SH_START_ITERATE SH_MAKE_NAME(start_iterate)
#define SH_START_ITERATE_AT SH_MAKE_NAME(start_iterate_at) #define SH_START_ITERATE_AT SH_MAKE_NAME(start_iterate_at)
#define SH_ITERATE SH_MAKE_NAME(iterate) #define SH_ITERATE SH_MAKE_NAME(iterate)
#define SH_ALLOCATE SH_MAKE_NAME(allocate)
#define SH_FREE SH_MAKE_NAME(free)
#define SH_STAT SH_MAKE_NAME(stat) #define SH_STAT SH_MAKE_NAME(stat)
/* internal helper functions (no externally visible prototypes) */ /* internal helper functions (no externally visible prototypes) */
...@@ -87,13 +91,6 @@ ...@@ -87,13 +91,6 @@
#define SH_INITIAL_BUCKET SH_MAKE_NAME(initial_bucket) #define SH_INITIAL_BUCKET SH_MAKE_NAME(initial_bucket)
#define SH_ENTRY_HASH SH_MAKE_NAME(entry_hash) #define SH_ENTRY_HASH SH_MAKE_NAME(entry_hash)
/* Allocation function for hash table elements */
#ifndef SIMPLEHASH_TYPEDEFS
#define SIMPLEHASH_TYPEDEFS
typedef void *(*simplehash_allocate) (Size size, void *args);
typedef void (*simplehash_free) (void *pointer, void *args);
#endif
/* generate forward declarations necessary to use the hash table */ /* generate forward declarations necessary to use the hash table */
#ifdef SH_DECLARE #ifdef SH_DECLARE
...@@ -119,11 +116,6 @@ typedef struct SH_TYPE ...@@ -119,11 +116,6 @@ typedef struct SH_TYPE
/* hash buckets */ /* hash buckets */
SH_ELEMENT_TYPE *data; SH_ELEMENT_TYPE *data;
/* Allocation and free functions, and the associated context. */
simplehash_allocate element_alloc;
simplehash_free element_free;
void *element_args;
/* memory context to use for allocations */ /* memory context to use for allocations */
MemoryContext ctx; MemoryContext ctx;
...@@ -145,8 +137,7 @@ typedef struct SH_ITERATOR ...@@ -145,8 +137,7 @@ typedef struct SH_ITERATOR
} SH_ITERATOR; } SH_ITERATOR;
/* externally visible function prototypes */ /* externally visible function prototypes */
SH_SCOPE SH_TYPE *SH_CREATE(MemoryContext ctx, uint32 nelements, SH_SCOPE SH_TYPE *SH_CREATE(MemoryContext ctx, uint32 nelements);
simplehash_allocate allocfunc, simplehash_free freefunc, void *args);
SH_SCOPE void SH_DESTROY(SH_TYPE *tb); SH_SCOPE void SH_DESTROY(SH_TYPE *tb);
SH_SCOPE void SH_GROW(SH_TYPE *tb, uint32 newsize); SH_SCOPE void SH_GROW(SH_TYPE *tb, uint32 newsize);
SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT(SH_TYPE *tb, SH_KEY_TYPE key, bool *found); SH_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) ...@@ -289,23 +280,25 @@ SH_ENTRY_HASH(SH_TYPE *tb, SH_ELEMENT_TYPE * entry)
#endif #endif
} }
#ifndef SH_USE_NONDEFAULT_ALLOCATOR
/* default memory allocator function */ /* default memory allocator function */
static void * static inline void *
SH_DEFAULT_ALLOC(Size size, void *args) SH_ALLOCATE(SH_TYPE *type, Size size)
{ {
MemoryContext context = (MemoryContext) args; return MemoryContextAllocExtended(type->ctx, size,
return MemoryContextAllocExtended(context, size,
MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO); MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO);
} }
/* default memory free function */ /* default memory free function */
static void static inline void
SH_DEFAULT_FREE(void *pointer, void *args) SH_FREE(SH_TYPE *type, void *pointer)
{ {
pfree(pointer); pfree(pointer);
} }
#endif
/* /*
* Create a hash table with enough space for `nelements` distinct members. * Create a hash table with enough space for `nelements` distinct members.
* Memory for the hash table is allocated from the passed-in context. If * Memory for the hash table is allocated from the passed-in context. If
...@@ -316,8 +309,7 @@ SH_DEFAULT_FREE(void *pointer, void *args) ...@@ -316,8 +309,7 @@ SH_DEFAULT_FREE(void *pointer, void *args)
* the passed-in context. * the passed-in context.
*/ */
SH_SCOPE SH_TYPE * SH_SCOPE SH_TYPE *
SH_CREATE(MemoryContext ctx, uint32 nelements, simplehash_allocate allocfunc, SH_CREATE(MemoryContext ctx, uint32 nelements)
simplehash_free freefunc, void *args)
{ {
SH_TYPE *tb; SH_TYPE *tb;
uint64 size; uint64 size;
...@@ -330,22 +322,7 @@ SH_CREATE(MemoryContext ctx, uint32 nelements, simplehash_allocate allocfunc, ...@@ -330,22 +322,7 @@ SH_CREATE(MemoryContext ctx, uint32 nelements, simplehash_allocate allocfunc,
SH_COMPUTE_PARAMETERS(tb, size); SH_COMPUTE_PARAMETERS(tb, size);
if (allocfunc == NULL) tb->data = SH_ALLOCATE(tb, sizeof(SH_ELEMENT_TYPE) * tb->size);
{
tb->element_alloc = SH_DEFAULT_ALLOC;
tb->element_free = SH_DEFAULT_FREE;
tb->element_args = ctx;
}
else
{
tb->element_alloc = allocfunc;
tb->element_free = freefunc;
tb->element_args = args;
}
tb->data = tb->element_alloc(sizeof(SH_ELEMENT_TYPE) * tb->size,
tb->element_args);
return tb; return tb;
} }
...@@ -354,7 +331,7 @@ SH_CREATE(MemoryContext ctx, uint32 nelements, simplehash_allocate allocfunc, ...@@ -354,7 +331,7 @@ SH_CREATE(MemoryContext ctx, uint32 nelements, simplehash_allocate allocfunc,
SH_SCOPE void SH_SCOPE void
SH_DESTROY(SH_TYPE *tb) SH_DESTROY(SH_TYPE *tb)
{ {
tb->element_free(tb->data, tb->element_args); SH_FREE(tb, tb->data);
pfree(tb); pfree(tb);
} }
...@@ -382,8 +359,7 @@ SH_GROW(SH_TYPE *tb, uint32 newsize) ...@@ -382,8 +359,7 @@ SH_GROW(SH_TYPE *tb, uint32 newsize)
/* compute parameters for new table */ /* compute parameters for new table */
SH_COMPUTE_PARAMETERS(tb, newsize); SH_COMPUTE_PARAMETERS(tb, newsize);
tb->data = tb->element_alloc(sizeof(SH_ELEMENT_TYPE) * tb->size, tb->data = SH_ALLOCATE(tb, sizeof(SH_ELEMENT_TYPE) * tb->size);
tb->element_args);
newdata = tb->data; newdata = tb->data;
...@@ -469,7 +445,7 @@ SH_GROW(SH_TYPE *tb, uint32 newsize) ...@@ -469,7 +445,7 @@ SH_GROW(SH_TYPE *tb, uint32 newsize)
} }
} }
tb->element_free(olddata, tb->element_args); SH_FREE(tb, olddata);
} }
/* /*
...@@ -888,6 +864,7 @@ SH_STAT(SH_TYPE *tb) ...@@ -888,6 +864,7 @@ SH_STAT(SH_TYPE *tb)
#undef SH_DEFINE #undef SH_DEFINE
#undef SH_GET_HASH #undef SH_GET_HASH
#undef SH_STORE_HASH #undef SH_STORE_HASH
#undef SH_USE_NONDEFAULT_ALLOCATOR
/* undefine locally declared macros */ /* undefine locally declared macros */
#undef SH_MAKE_PREFIX #undef SH_MAKE_PREFIX
...@@ -914,6 +891,8 @@ SH_STAT(SH_TYPE *tb) ...@@ -914,6 +891,8 @@ SH_STAT(SH_TYPE *tb)
#undef SH_START_ITERATE #undef SH_START_ITERATE
#undef SH_START_ITERATE_AT #undef SH_START_ITERATE_AT
#undef SH_ITERATE #undef SH_ITERATE
#undef SH_ALLOCATE
#undef SH_FREE
#undef SH_STAT #undef SH_STAT
/* internal function names */ /* internal function names */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment