]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Remove 'additional' pointer from TupleHashEntryData.
authorJeff Davis <jdavis@postgresql.org>
Tue, 25 Mar 2025 05:06:02 +0000 (22:06 -0700)
committerJeff Davis <jdavis@postgresql.org>
Tue, 25 Mar 2025 05:06:02 +0000 (22:06 -0700)
Reduces memory required for hash aggregation by avoiding an allocation
and a pointer in the TupleHashEntryData structure. That structure is
used for all buckets, whether occupied or not, so the savings is
substantial.

Discussion: https://postgr.es/m/AApHDvpN4v3t_sdz4dvrv1Fx_ZPw=twSnxuTEytRYP7LFz5K9A@mail.gmail.com
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
src/backend/executor/execGrouping.c
src/include/executor/executor.h
src/include/nodes/execnodes.h

index a9d212aaec60cbf83a3a3618b5cffc6396c24cc3..255bd795361a20a7210d1e6de46da609f74f33d6 100644 (file)
@@ -485,11 +485,18 @@ LookupTupleHashEntry_internal(TupleHashTable hashtable, TupleTableSlot *slot,
 
                        MemoryContextSwitchTo(hashtable->tablecxt);
 
-                       entry->firstTuple = ExecCopySlotMinimalTuple(slot);
-                       if (hashtable->additionalsize > 0)
-                               entry->additional = palloc0(hashtable->additionalsize);
-                       else
-                               entry->additional = NULL;
+                       /*
+                        * Copy the first tuple into the table context, and request
+                        * additionalsize extra bytes before the allocation.
+                        *
+                        * The caller can get a pointer to the additional data with
+                        * TupleHashEntryGetAdditional(), and store arbitrary data there.
+                        * Placing both the tuple and additional data in the same
+                        * allocation avoids the need to store an extra pointer in
+                        * TupleHashEntryData or allocate an additional chunk.
+                        */
+                       entry->firstTuple = ExecCopySlotMinimalTupleExtra(slot,
+                                                                                                                         hashtable->additionalsize);
                }
        }
        else
index 69396a9d7f8952b15f078432e64ec5f3ff565c4c..6a1fec88928114c525e7e2b74e0bd158816d507d 100644 (file)
@@ -188,7 +188,10 @@ TupleHashEntryGetTuple(TupleHashEntry entry)
 static inline void *
 TupleHashEntryGetAdditional(TupleHashTable hashtable, TupleHashEntry entry)
 {
-       return entry->additional;
+       if (hashtable->additionalsize > 0)
+               return (char *) entry->firstTuple - hashtable->additionalsize;
+       else
+               return NULL;
 }
 #endif
 
index 7df25d7e64f13cd5ebf8b3fe6b0f0852537e9a6d..e42f9f9f9574ea1ec75f1ec03c6512b8ef9aa228 100644 (file)
@@ -840,7 +840,6 @@ typedef struct TupleHashTableData *TupleHashTable;
 typedef struct TupleHashEntryData
 {
        MinimalTuple firstTuple;        /* copy of first tuple in this group */
-       void       *additional;         /* user data */
        uint32          status;                 /* hash status */
        uint32          hash;                   /* hash value (cached) */
 } TupleHashEntryData;