From 626df47ad9db809dc8f93330175ab95b75914721 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Mon, 24 Mar 2025 22:06:02 -0700 Subject: [PATCH] Remove 'additional' pointer from TupleHashEntryData. 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 --- src/backend/executor/execGrouping.c | 17 ++++++++++++----- src/include/executor/executor.h | 5 ++++- src/include/nodes/execnodes.h | 1 - 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/backend/executor/execGrouping.c b/src/backend/executor/execGrouping.c index a9d212aaec6..255bd795361 100644 --- a/src/backend/executor/execGrouping.c +++ b/src/backend/executor/execGrouping.c @@ -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 diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 69396a9d7f8..6a1fec88928 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -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 diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 7df25d7e64f..e42f9f9f957 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -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; -- 2.39.5