0001-b-split-TID-lists-when-flushing.patch
text/x-patch
Filename: 0001-b-split-TID-lists-when-flushing.patch
Type: text/x-patch
Part: 1
Patch
Format: format-patch
Series: patch 0001
Subject: b: split TID lists when flushing
| File | + | − |
|---|---|---|
| src/backend/access/gin/gininsert.c | 26 | 11 |
From 1c47f44483939a0a7a47073a838164a3296a51c3 Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@vondra.me>
Date: Sun, 26 Oct 2025 21:14:44 +0100
Subject: [PATCH] b: split TID lists when flushing
---
src/backend/access/gin/gininsert.c | 37 +++++++++++++++++++++---------
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index 3d71b442aa9..eff78cc622d 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -152,7 +152,9 @@ typedef struct
* only in the leader process.
*/
GinLeader *bs_leader;
- int bs_worker_id;
+
+ /* number of participating workers (including leader) */
+ int bs_num_workers;
/* used to pass information from workers to leader */
double bs_numtuples;
@@ -494,27 +496,39 @@ ginFlushBuildState(GinBuildState *buildstate, Relation index)
OffsetNumber attnum;
TupleDesc tdesc = RelationGetDescr(index);
+ /* how many TIDs fit into a regular allocation (50% to keep slack) */
+ uint32 maxsize = (MaxAllocSize / sizeof(ItemPointerData) / 2);
+ maxsize /= buildstate->bs_num_workers; /* fair share per worker */
+
ginBeginBAScan(&buildstate->accum);
while ((list = ginGetBAEntry(&buildstate->accum,
&attnum, &key, &category, &nlist)) != NULL)
{
/* information about the key */
CompactAttribute *attr = TupleDescCompactAttr(tdesc, (attnum - 1));
+ uint32 start = 0;
- /* GIN tuple and tuple length */
- GinTuple *tup;
- Size tuplen;
+ /* split the list into smaller parts with up to maxsize items */
+ while (start < nlist)
+ {
+ /* GIN tuple and tuple length */
+ GinTuple *tup;
+ Size tuplen;
- /* there could be many entries, so be willing to abort here */
- CHECK_FOR_INTERRUPTS();
+ /* there could be many entries, so be willing to abort here */
+ CHECK_FOR_INTERRUPTS();
- tup = _gin_build_tuple(attnum, category,
- key, attr->attlen, attr->attbyval,
- list, nlist, &tuplen);
+ tup = _gin_build_tuple(attnum, category,
+ key, attr->attlen, attr->attbyval,
+ &list[start], Min(maxsize, nlist - start),
+ &tuplen);
- tuplesort_putgintuple(buildstate->bs_worker_sort, tup, tuplen);
+ start += maxsize;
- pfree(tup);
+ tuplesort_putgintuple(buildstate->bs_worker_sort, tup, tuplen);
+
+ pfree(tup);
+ }
}
MemoryContextReset(buildstate->tmpCtx);
@@ -2016,6 +2030,7 @@ _gin_parallel_scan_and_build(GinBuildState *state,
/* remember how much space is allowed for the accumulated entries */
state->work_mem = (sortmem / 2);
+ state->bs_num_workers = ginshared->scantuplesortstates;
/* Begin "partial" tuplesort */
state->bs_sortstate = tuplesort_begin_index_gin(heap, index,
--
2.51.0