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.
pull/17/merge
Robert Haas 9 years ago
parent 94708c0e8c
commit 565903af47
  1. 3
      src/backend/executor/execGrouping.c
  2. 2
      src/backend/nodes/tidbitmap.c
  3. 69
      src/include/lib/simplehash.h

@ -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;

@ -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)

@ -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);
}
/*

Loading…
Cancel
Save