0001-a-use-huge-allocations.patch
text/x-patch
Filename: 0001-a-use-huge-allocations.patch
Type: text/x-patch
Part: 0
Patch
Format: format-patch
Series: patch 0001
Subject: a: use huge allocations
| File | + | − |
|---|---|---|
| src/backend/access/gin/gininsert.c | 75 | 6 |
From be3417e947a1f17e5fa4137481668779be532bc5 Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@vondra.me>
Date: Sun, 26 Oct 2025 21:14:44 +0100
Subject: [PATCH 1/3] a: use huge allocations
---
src/backend/access/gin/gininsert.c | 81 +++++++++++++++++++++++++++---
1 file changed, 75 insertions(+), 6 deletions(-)
diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c
index 3d71b442aa9..085c85718cc 100644
--- a/src/backend/access/gin/gininsert.c
+++ b/src/backend/access/gin/gininsert.c
@@ -198,6 +198,10 @@ static GinTuple *_gin_build_tuple(OffsetNumber attrnum, unsigned char category,
ItemPointerData *items, uint32 nitems,
Size *len);
+static ItemPointer mergeItemPointers(ItemPointerData *a, uint32 na,
+ ItemPointerData *b, uint32 nb,
+ int *nmerged);
+
/*
* Adds array of item pointers to tuple's posting list, or
* creates posting tree and tuple pointing to tree in case
@@ -1496,14 +1500,15 @@ GinBufferStoreTuple(GinBuffer *buffer, GinTuple *tup)
* still pass 0 as number of elements in that array though.
*/
if (buffer->items == NULL)
- buffer->items = palloc((buffer->nitems + tup->nitems) * sizeof(ItemPointerData));
+ buffer->items = MemoryContextAllocHuge(CurrentMemoryContext,
+ (buffer->nitems + tup->nitems) * sizeof(ItemPointerData));
else
- buffer->items = repalloc(buffer->items,
- (buffer->nitems + tup->nitems) * sizeof(ItemPointerData));
+ buffer->items = repalloc_huge(buffer->items,
+ (buffer->nitems + tup->nitems) * sizeof(ItemPointerData));
- new = ginMergeItemPointers(&buffer->items[buffer->nfrozen], /* first unfrozen */
- (buffer->nitems - buffer->nfrozen), /* num of unfrozen */
- items, tup->nitems, &nnew);
+ new = mergeItemPointers(&buffer->items[buffer->nfrozen], /* first unfrozen */
+ (buffer->nitems - buffer->nfrozen), /* num of unfrozen */
+ items, tup->nitems, &nnew);
Assert(nnew == (tup->nitems + (buffer->nitems - buffer->nfrozen)));
@@ -2441,3 +2446,67 @@ _gin_compare_tuples(GinTuple *a, GinTuple *b, SortSupport ssup)
return ItemPointerCompare(GinTupleGetFirst(a),
GinTupleGetFirst(b));
}
+
+
+/*
+ * local copy, doing palloc_huge
+ */
+static ItemPointer
+mergeItemPointers(ItemPointerData *a, uint32 na,
+ ItemPointerData *b, uint32 nb,
+ int *nmerged)
+{
+ ItemPointerData *dst;
+
+ dst = (ItemPointer) MemoryContextAllocHuge(CurrentMemoryContext,
+ (na + nb) * sizeof(ItemPointerData));
+
+ /*
+ * If the argument arrays don't overlap, we can just append them to each
+ * other.
+ */
+ if (na == 0 || nb == 0 || ginCompareItemPointers(&a[na - 1], &b[0]) < 0)
+ {
+ memcpy(dst, a, na * sizeof(ItemPointerData));
+ memcpy(&dst[na], b, nb * sizeof(ItemPointerData));
+ *nmerged = na + nb;
+ }
+ else if (ginCompareItemPointers(&b[nb - 1], &a[0]) < 0)
+ {
+ memcpy(dst, b, nb * sizeof(ItemPointerData));
+ memcpy(&dst[nb], a, na * sizeof(ItemPointerData));
+ *nmerged = na + nb;
+ }
+ else
+ {
+ ItemPointerData *dptr = dst;
+ ItemPointerData *aptr = a;
+ ItemPointerData *bptr = b;
+
+ while (aptr - a < na && bptr - b < nb)
+ {
+ int cmp = ginCompareItemPointers(aptr, bptr);
+
+ if (cmp > 0)
+ *dptr++ = *bptr++;
+ else if (cmp == 0)
+ {
+ /* only keep one copy of the identical items */
+ *dptr++ = *bptr++;
+ aptr++;
+ }
+ else
+ *dptr++ = *aptr++;
+ }
+
+ while (aptr - a < na)
+ *dptr++ = *aptr++;
+
+ while (bptr - b < nb)
+ *dptr++ = *bptr++;
+
+ *nmerged = dptr - dst;
+ }
+
+ return dst;
+}
--
2.51.0