diff --git a/src/backend/executor/execGrouping.c b/src/backend/executor/execGrouping.c index 94cc59d..ba8a8be 100644 --- a/src/backend/executor/execGrouping.c +++ b/src/backend/executor/execGrouping.c @@ -314,7 +314,7 @@ BuildTupleHashTable(int numCols, AttrNumber *keyColIdx, hashtable->in_hash_funcs = NULL; hashtable->cur_eq_funcs = NULL; - hashtable->hashtab = tuplehash_create(tablecxt, nbuckets); + hashtable->hashtab = tuplehash_create(tablecxt, nbuckets, NULL); hashtable->hashtab->private_data = hashtable; return hashtable; diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c index 826fead..ea79de7 100644 --- a/src/backend/nodes/tidbitmap.c +++ b/src/backend/nodes/tidbitmap.c @@ -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); /* If entry1 is valid, push it into the hashtable */ if (tbm->status == TBM_ONE_PAGE) diff --git a/src/include/lib/simplehash.h b/src/include/lib/simplehash.h index 12aedbc..2328413 100644 --- a/src/include/lib/simplehash.h +++ b/src/include/lib/simplehash.h @@ -66,6 +66,7 @@ #define SH_STATUS_EMPTY SH_MAKE_NAME(EMPTY) #define SH_STATUS_IN_USE SH_MAKE_NAME(IN_USE) #define SH_ITERATOR SH_MAKE_NAME(iterator) +#define SH_ALLOCATOR SH_MAKE_NAME(alloc) /* function declarations */ #define SH_CREATE SH_MAKE_NAME(create) @@ -90,6 +91,22 @@ /* generate forward declarations necessary to use the hash table */ #ifdef SH_DECLARE +/* Memory allocator function pointers */ +typedef void *(*HashAlloc) (Size size, void *args); +typedef void (*HashFree) (void *pointer, void *args); + +typedef struct SH_ALLOCATOR +{ + /* Allocation function */ + void *(*HashAlloc) (Size size, void *args); + + /* Free function*/ + void (*HashFree) (void *pointer, void *args); + + /* Arguments */ + void *args; +} SH_ALLOCATOR; + /* type definitions */ typedef struct SH_TYPE { @@ -112,6 +129,9 @@ typedef struct SH_TYPE /* hash buckets */ SH_ELEMENT_TYPE *data; + /* hash allocator */ + SH_ALLOCATOR *alloc; + /* memory context to use for allocations */ MemoryContext ctx; @@ -133,7 +153,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, + SH_ALLOCATOR *alloc); 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); @@ -281,7 +302,7 @@ SH_ENTRY_HASH(SH_TYPE *tb, SH_ELEMENT_TYPE * entry) * allocating required memory in the passed-in context. */ SH_SCOPE SH_TYPE * -SH_CREATE(MemoryContext ctx, uint32 nelements) +SH_CREATE(MemoryContext ctx, uint32 nelements, SH_ALLOCATOR *alloc) { SH_TYPE *tb; uint64 size; @@ -294,7 +315,17 @@ SH_CREATE(MemoryContext ctx, uint32 nelements) SH_COMPUTE_PARAMETERS(tb, size); - tb->data = MemoryContextAllocExtended(tb->ctx, + tb->alloc = alloc; + + /* + * If allocation handle is passed then use allocation function from the + * handle otherwise use standard allocator. + */ + if (tb->alloc != NULL) + tb->data = tb->alloc->HashAlloc(sizeof(SH_ELEMENT_TYPE) * tb->size, + tb->alloc->args); + else + tb->data = MemoryContextAllocExtended(tb->ctx, sizeof(SH_ELEMENT_TYPE) * tb->size, MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO); @@ -333,8 +364,16 @@ 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, + /* + * If allocation handle is valid then use allocation function from the + * handle otherwise use standard allocator. + */ + if (tb->alloc != NULL) + tb->data = tb->alloc->HashAlloc(sizeof(SH_ELEMENT_TYPE) * tb->size, + tb->alloc->args); + else + tb->data = MemoryContextAllocExtended(tb->ctx, + sizeof(SH_ELEMENT_TYPE) * tb->size, MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO); newdata = tb->data; @@ -421,7 +460,11 @@ SH_GROW(SH_TYPE *tb, uint32 newsize) } } - pfree(olddata); + if (tb->alloc == NULL) + pfree(olddata); + else + tb->alloc->HashFree(olddata, tb->alloc->args); + } /*