v8-0004-Remove-additional-pointer-from-TupleHashEntryData.patch
text/x-patch
Filename: v8-0004-Remove-additional-pointer-from-TupleHashEntryData.patch
Type: text/x-patch
Part: 3
Patch
Format: format-patch
Series: patch v8-0004
Subject: Remove 'additional' pointer from TupleHashEntryData.
| File | + | − |
|---|---|---|
| src/backend/executor/execGrouping.c | 25 | 7 |
| src/include/executor/executor.h | 4 | 1 |
| src/include/nodes/execnodes.h | 0 | 1 |
From 7470eb62b45dd5ee5280d8f834a910a64c8bcc85 Mon Sep 17 00:00:00 2001
From: Jeff Davis <jeff@j-davis.com>
Date: Tue, 4 Mar 2025 15:13:22 -0800
Subject: [PATCH v8 4/7] 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 <dgrowleyml@gmail.com>
---
src/backend/executor/execGrouping.c | 32 ++++++++++++++++++++++-------
src/include/executor/executor.h | 5 ++++-
src/include/nodes/execnodes.h | 1 -
3 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/src/backend/executor/execGrouping.c b/src/backend/executor/execGrouping.c
index a9d212aaec6..5c06cc6da40 100644
--- a/src/backend/executor/execGrouping.c
+++ b/src/backend/executor/execGrouping.c
@@ -481,15 +481,33 @@ LookupTupleHashEntry_internal(TupleHashTable hashtable, TupleTableSlot *slot,
else
{
/* created new entry */
- *isnew = true;
+ bool shouldFree;
+ char *mem;
+ MinimalTuple mtup;
- MemoryContextSwitchTo(hashtable->tablecxt);
+ *isnew = true;
- entry->firstTuple = ExecCopySlotMinimalTuple(slot);
- if (hashtable->additionalsize > 0)
- entry->additional = palloc0(hashtable->additionalsize);
- else
- entry->additional = NULL;
+ MemoryContextSwitchTo(hashtable->tempcxt);
+
+ /* ignore shouldFree, because we're in the temp context anyway */
+ mtup = ExecFetchSlotMinimalTuple(slot, &shouldFree);
+
+ /*
+ * Allocate enough memory in the tablecxt for the additionalsize
+ * followed by the tuple. Clear the additional data, and copy the
+ * tuple.
+ *
+ * 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.
+ */
+ mem = MemoryContextAlloc(hashtable->tablecxt,
+ mtup->t_len + hashtable->additionalsize);
+ memset(mem, 0, hashtable->additionalsize);
+ entry->firstTuple = (MinimalTuple) (mem + hashtable->additionalsize);
+ memcpy(entry->firstTuple, mtup, mtup->t_len);
}
}
else
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index d0aa0e94241..90fa466dea4 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 b9ca5f7f5fa..e93533dbbc5 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.34.1