page_collect_tuples.diff
text/x-patch
Filename: page_collect_tuples.diff
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/access/heap/heapam.c | 52 | 8 |
| src/backend/access/heap/heapam_visibility.c | 3 | 1 |
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 0dcd6ee817e..e0796dd06fe 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -500,7 +500,8 @@ heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk, BlockNumber numBlk
pg_attribute_always_inline
static int
page_collect_tuples(HeapScanDesc scan, Snapshot snapshot,
- Page page, Buffer buffer,
+ ItemId items, HeapTupleHeader headers,
+ Buffer buffer,
BlockNumber block, int lines,
bool all_visible, bool check_serializable)
{
@@ -509,14 +510,14 @@ page_collect_tuples(HeapScanDesc scan, Snapshot snapshot,
for (lineoff = FirstOffsetNumber; lineoff <= lines; lineoff++)
{
- ItemId lpp = PageGetItemId(page, lineoff);
+ ItemId lpp = &items[lineoff - 1];
HeapTupleData loctup;
bool valid;
if (!ItemIdIsNormal(lpp))
continue;
- loctup.t_data = (HeapTupleHeader) PageGetItem(page, lpp);
+ loctup.t_data = &headers[lineoff - 1];
loctup.t_len = ItemIdGetLength(lpp);
loctup.t_tableOid = RelationGetRelid(scan->rs_base.rs_rd);
ItemPointerSet(&(loctup.t_self), block, lineoff);
@@ -542,6 +543,8 @@ page_collect_tuples(HeapScanDesc scan, Snapshot snapshot,
return ntup;
}
+extern bool SetHintBitsSkipMark;
+
/*
* heap_prepare_pagescan - Prepare current scan page to be scanned in pagemode
*
@@ -557,8 +560,13 @@ heap_prepare_pagescan(TableScanDesc sscan)
Snapshot snapshot;
Page page;
int lines;
+ OffsetNumber lineoff;
bool all_visible;
bool check_serializable;
+ bool set_hints;
+ ItemIdData line_data[MaxHeapTuplesPerPage];
+ HeapTupleHeaderData tup_headers[MaxHeapTuplesPerPage] = {0};
+ uint16 infomasks[MaxHeapTuplesPerPage] = {0};
Assert(BufferGetBlockNumber(buffer) == block);
@@ -580,6 +588,13 @@ heap_prepare_pagescan(TableScanDesc sscan)
page = BufferGetPage(buffer);
lines = PageGetMaxOffsetNumber(page);
+ for (lineoff = FirstOffsetNumber; lineoff <= lines; lineoff++)
+ {
+ line_data[lineoff - 1] = *PageGetItemId(page, lineoff);
+ if (!ItemIdIsNormal(&line_data[lineoff - 1]))
+ continue;
+ tup_headers[lineoff - 1] = *(HeapTupleHeader) PageGetItem(page, &line_data[lineoff - 1]);
+ }
/*
* If the all-visible flag indicates that all tuples on the page are
@@ -605,6 +620,13 @@ heap_prepare_pagescan(TableScanDesc sscan)
check_serializable =
CheckForSerializableConflictOutNeeded(scan->rs_base.rs_rd, snapshot);
+ LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
+
+ for (lineoff = 0; lineoff < lines; lineoff++)
+ infomasks[lineoff] = tup_headers[lineoff].t_infomask;
+
+ SetHintBitsSkipMark = true;
+
/*
* We call page_collect_tuples() with constant arguments, to get the
* compiler to constant fold the constant arguments. Separate calls with
@@ -614,23 +636,45 @@ heap_prepare_pagescan(TableScanDesc sscan)
if (likely(all_visible))
{
if (likely(!check_serializable))
- scan->rs_ntuples = page_collect_tuples(scan, snapshot, page, buffer,
+ scan->rs_ntuples = page_collect_tuples(scan, snapshot, line_data, tup_headers, buffer,
block, lines, true, false);
else
- scan->rs_ntuples = page_collect_tuples(scan, snapshot, page, buffer,
+ scan->rs_ntuples = page_collect_tuples(scan, snapshot, line_data, tup_headers, buffer,
block, lines, true, true);
}
else
{
if (likely(!check_serializable))
- scan->rs_ntuples = page_collect_tuples(scan, snapshot, page, buffer,
+ scan->rs_ntuples = page_collect_tuples(scan, snapshot, line_data, tup_headers, buffer,
block, lines, false, false);
else
- scan->rs_ntuples = page_collect_tuples(scan, snapshot, page, buffer,
+ scan->rs_ntuples = page_collect_tuples(scan, snapshot, line_data, tup_headers, buffer,
block, lines, false, true);
}
+ SetHintBitsSkipMark = false;
- LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
+ set_hints = false;
+ for (lineoff = 0; lineoff < lines; lineoff++)
+ {
+ infomasks[lineoff] ^= tup_headers[lineoff].t_infomask;
+ if (infomasks[lineoff])
+ set_hints = true;
+ }
+
+ if (set_hints)
+ {
+ LockBuffer(buffer, BUFFER_LOCK_SHARE);
+
+ for (lineoff = 0; lineoff < lines; lineoff++)
+ {
+ if (infomasks[lineoff] == 0)
+ continue;
+ ((HeapTupleHeader) PageGetItem(page, &line_data[lineoff]))->t_infomask |= infomasks[lineoff];
+ }
+ MarkBufferDirtyHint(buffer, true);
+
+ LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
+ }
}
/*
diff --git a/src/backend/access/heap/heapam_visibility.c b/src/backend/access/heap/heapam_visibility.c
index 05f6946fe60..34a251056a7 100644
--- a/src/backend/access/heap/heapam_visibility.c
+++ b/src/backend/access/heap/heapam_visibility.c
@@ -78,6 +78,7 @@
#include "utils/builtins.h"
#include "utils/snapmgr.h"
+bool SetHintBitsSkipMark = false;
/*
* SetHintBits()
@@ -128,7 +129,8 @@ SetHintBits(HeapTupleHeader tuple, Buffer buffer,
}
tuple->t_infomask |= infomask;
- MarkBufferDirtyHint(buffer, true);
+ if (!SetHintBitsSkipMark)
+ MarkBufferDirtyHint(buffer, true);
}
/*