Allow the element allocator for a simplehash to be specified.

This is infrastructure for a pending patch to allow parallel bitmap
heap scans.

Dilip Kumar, reviewed (in earlier versions) by Andres Freund and
(more recently) by me.  Some further renaming by me, also.
This commit is contained in:
Robert Haas 2017-02-07 15:58:30 -05:00
parent 94708c0e8c
commit 565903af47
3 changed files with 60 additions and 14 deletions

View File

@ -330,7 +330,8 @@ BuildTupleHashTable(int numCols, AttrNumber *keyColIdx,
else
hashtable->hash_iv = 0;
hashtable->hashtab = tuplehash_create(tablecxt, nbuckets);
hashtable->hashtab =
tuplehash_create(tablecxt, nbuckets, NULL, NULL, NULL);
hashtable->hashtab->private_data = hashtable;
return hashtable;

View File

@ -244,7 +244,7 @@ tbm_create_pagetable(TIDBitmap *tbm)
Assert(tbm->status != TBM_HASH);
Assert(tbm->pagetable == NULL);
tbm->pagetable = pagetable_create(tbm->mcxt, 128);
tbm->pagetable = pagetable_create(tbm->mcxt, 128, NULL, NULL, NULL);
/* If entry1 is valid, push it into the hashtable */
if (tbm->status == TBM_ONE_PAGE)

View File

@ -87,6 +87,10 @@
#define SH_INITIAL_BUCKET SH_MAKE_NAME(initial_bucket)
#define SH_ENTRY_HASH SH_MAKE_NAME(entry_hash)
/* Allocation function for hash table elements */
typedef void *(*simplehash_allocate) (Size size, void *args);
typedef void (*simplehash_free) (void *pointer, void *args);
/* generate forward declarations necessary to use the hash table */
#ifdef SH_DECLARE
@ -112,6 +116,11 @@ typedef struct SH_TYPE
/* hash buckets */
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 */
MemoryContext ctx;
@ -133,7 +142,8 @@ typedef struct SH_ITERATOR
} SH_ITERATOR;
/* 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_GROW(SH_TYPE *tb, uint32 newsize);
SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT(SH_TYPE *tb, SH_KEY_TYPE key, bool *found);
@ -276,12 +286,35 @@ SH_ENTRY_HASH(SH_TYPE *tb, SH_ELEMENT_TYPE * entry)
#endif
}
/* default memory allocator function */
static void *
SH_DEFAULT_ALLOC(Size size, void *args)
{
MemoryContext context = (MemoryContext) args;
return MemoryContextAllocExtended(context, size,
MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO);
}
/* default memory free function */
static void
SH_DEFAULT_FREE(void *pointer, void *args)
{
pfree(pointer);
}
/*
* Create a hash table with enough space for `nelements` distinct members,
* allocating required memory in the passed-in context.
* Create a hash table with enough space for `nelements` distinct members.
* Memory for the hash table is allocated from the passed-in context. If
* desired, the array of elements can be allocated using a passed-in allocator;
* this could be useful in order to place the array of elements in a shared
* memory, or in a context that will outlive the rest of the hash table.
* Memory other than for the array of elements will still be allocated from
* the passed-in context.
*/
SH_SCOPE SH_TYPE *
SH_CREATE(MemoryContext ctx, uint32 nelements)
SH_CREATE(MemoryContext ctx, uint32 nelements, simplehash_allocate allocfunc,
simplehash_free freefunc, void *args)
{
SH_TYPE *tb;
uint64 size;
@ -294,9 +327,22 @@ SH_CREATE(MemoryContext ctx, uint32 nelements)
SH_COMPUTE_PARAMETERS(tb, size);
tb->data = MemoryContextAllocExtended(tb->ctx,
sizeof(SH_ELEMENT_TYPE) * tb->size,
MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO);
if (allocfunc == NULL)
{
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;
}
@ -305,7 +351,7 @@ SH_CREATE(MemoryContext ctx, uint32 nelements)
SH_SCOPE void
SH_DESTROY(SH_TYPE *tb)
{
pfree(tb->data);
tb->element_free(tb->data, tb->element_args);
pfree(tb);
}
@ -333,9 +379,8 @@ SH_GROW(SH_TYPE *tb, uint32 newsize)
/* compute parameters for new table */
SH_COMPUTE_PARAMETERS(tb, newsize);
tb->data = MemoryContextAllocExtended(
tb->ctx, sizeof(SH_ELEMENT_TYPE) * tb->size,
MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO);
tb->data = tb->element_alloc(sizeof(SH_ELEMENT_TYPE) * tb->size,
tb->element_args);
newdata = tb->data;
@ -421,7 +466,7 @@ SH_GROW(SH_TYPE *tb, uint32 newsize)
}
}
pfree(olddata);
tb->element_free(olddata, tb->element_args);
}
/*