Remove 'additional' pointer from TupleHashEntryData.
authorJeff Davis <[email protected]>
Tue, 25 Mar 2025 05:06:02 +0000 (22:06 -0700)
committerJeff Davis <[email protected]>
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 <[email protected]>
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;