]> granicus.if.org Git - postgresql/commitdiff
Revise the way the element allocator for a simplehash is specified.
authorRobert Haas <rhaas@postgresql.org>
Tue, 7 Feb 2017 22:01:40 +0000 (17:01 -0500)
committerRobert Haas <rhaas@postgresql.org>
Tue, 7 Feb 2017 22:10:08 +0000 (17:10 -0500)
This method is more elegant and more efficient.

Per a suggestion from Andres Freund, who also briefly reviewed
the patch.

src/backend/executor/execGrouping.c
src/backend/nodes/tidbitmap.c
src/include/lib/simplehash.h

index 2d9ce938bafc6ee6803929875b7ae6dbbcd1dceb..47c9656e1be1fd781a25846bbdf6f16717b972f5 100644 (file)
@@ -330,8 +330,7 @@ BuildTupleHashTable(int numCols, AttrNumber *keyColIdx,
        else
                hashtable->hash_iv = 0;
 
-       hashtable->hashtab =
-                       tuplehash_create(tablecxt, nbuckets, NULL, NULL, NULL);
+       hashtable->hashtab = tuplehash_create(tablecxt, nbuckets);
        hashtable->hashtab->private_data = hashtable;
 
        return hashtable;
index 36102b5deab70959aa808b3fd5bff25f53c534f0..7b31948fd28a8993e01333c67a2b1145089089d8 100644 (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, NULL, NULL, NULL);
+       tbm->pagetable = pagetable_create(tbm->mcxt, 128);
 
        /* If entry1 is valid, push it into the hashtable */
        if (tbm->status == TBM_ONE_PAGE)
index 359c7b8aa0c123c88fc22cdcfe5a2f3d7cde2203..ff50633549de218b50256be4dcf55b65d4fae712 100644 (file)
@@ -23,6 +23,8 @@
  *       - SH_DEFINE - if defined function definitions are generated
  *       - SH_SCOPE - in which scope (e.g. extern, static inline) do function
  *             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:
  *       - SH_KEY - name of the element in SH_ELEMENT_TYPE containing the hash key
  *       - SH_EQUAL(table, a, b) - compare two table keys
@@ -77,6 +79,8 @@
 #define SH_START_ITERATE SH_MAKE_NAME(start_iterate)
 #define SH_START_ITERATE_AT SH_MAKE_NAME(start_iterate_at)
 #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)
 
 /* internal helper functions (no externally visible prototypes) */
 #define SH_INITIAL_BUCKET SH_MAKE_NAME(initial_bucket)
 #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 */
 #ifdef SH_DECLARE
 
@@ -119,11 +116,6 @@ 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;
 
@@ -145,8 +137,7 @@ typedef struct SH_ITERATOR
 } SH_ITERATOR;
 
 /* externally visible function prototypes */
-SH_SCOPE SH_TYPE *SH_CREATE(MemoryContext ctx, uint32 nelements,
-               simplehash_allocate allocfunc, simplehash_free freefunc, void *args);
+SH_SCOPE SH_TYPE *SH_CREATE(MemoryContext ctx, uint32 nelements);
 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);
@@ -289,23 +280,25 @@ SH_ENTRY_HASH(SH_TYPE *tb, SH_ELEMENT_TYPE * entry)
 #endif
 }
 
+#ifndef SH_USE_NONDEFAULT_ALLOCATOR
+
 /* default memory allocator function */
-static void *
-SH_DEFAULT_ALLOC(Size size, void *args)
+static inline void *
+SH_ALLOCATE(SH_TYPE *type, Size size)
 {
-       MemoryContext context = (MemoryContext) args;
-
-       return MemoryContextAllocExtended(context, size,
+       return MemoryContextAllocExtended(type->ctx, size,
                                                                          MCXT_ALLOC_HUGE | MCXT_ALLOC_ZERO);
 }
 
 /* default memory free function */
-static void
-SH_DEFAULT_FREE(void *pointer, void *args)
+static inline void
+SH_FREE(SH_TYPE *type, void *pointer)
 {
        pfree(pointer);
 }
 
+#endif
+
 /*
  * Create a hash table with enough space for `nelements` distinct members.
  * Memory for the hash table is allocated from the passed-in context.  If
@@ -316,8 +309,7 @@ SH_DEFAULT_FREE(void *pointer, void *args)
  * the passed-in context.
  */
 SH_SCOPE SH_TYPE *
-SH_CREATE(MemoryContext ctx, uint32 nelements, simplehash_allocate allocfunc,
-                 simplehash_free freefunc, void *args)
+SH_CREATE(MemoryContext ctx, uint32 nelements)
 {
        SH_TYPE    *tb;
        uint64          size;
@@ -330,22 +322,7 @@ SH_CREATE(MemoryContext ctx, uint32 nelements, simplehash_allocate allocfunc,
 
        SH_COMPUTE_PARAMETERS(tb, size);
 
-       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);
+       tb->data = SH_ALLOCATE(tb, sizeof(SH_ELEMENT_TYPE) * tb->size);
 
        return tb;
 }
@@ -354,7 +331,7 @@ SH_CREATE(MemoryContext ctx, uint32 nelements, simplehash_allocate allocfunc,
 SH_SCOPE void
 SH_DESTROY(SH_TYPE *tb)
 {
-       tb->element_free(tb->data, tb->element_args);
+       SH_FREE(tb, tb->data);
        pfree(tb);
 }
 
@@ -382,8 +359,7 @@ SH_GROW(SH_TYPE *tb, uint32 newsize)
        /* compute parameters for new table */
        SH_COMPUTE_PARAMETERS(tb, newsize);
 
-       tb->data = tb->element_alloc(sizeof(SH_ELEMENT_TYPE) * tb->size,
-                                                                tb->element_args);
+       tb->data = SH_ALLOCATE(tb, sizeof(SH_ELEMENT_TYPE) * tb->size);
 
        newdata = tb->data;
 
@@ -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)
 #undef SH_DEFINE
 #undef SH_GET_HASH
 #undef SH_STORE_HASH
+#undef SH_USE_NONDEFAULT_ALLOCATOR
 
 /* undefine locally declared macros */
 #undef SH_MAKE_PREFIX
@@ -914,6 +891,8 @@ SH_STAT(SH_TYPE *tb)
 #undef SH_START_ITERATE
 #undef SH_START_ITERATE_AT
 #undef SH_ITERATE
+#undef SH_ALLOCATE
+#undef SH_FREE
 #undef SH_STAT
 
 /* internal function names */