Skip to content

Commit f7a8fc1

Browse files
Add and use BitmapHeapScanDescData struct
Move the several members of HeapScanDescData which are specific to Bitmap Heap Scans into a new struct, BitmapHeapScanDescData, which inherits from HeapScanDescData. This reduces the size of the HeapScanDescData for other types of scans and will allow us to add additional bitmap heap scan-specific members in the future without fear of bloating the HeapScanDescData. Reviewed-by: Tomas Vondra Discussion: https://postgr.es/m/c736f6aa-8b35-4e20-9621-62c7c82e2168%40vondra.me
1 parent 7b6468c commit f7a8fc1

File tree

4 files changed

+61
-30
lines changed

4 files changed

+61
-30
lines changed

src/backend/access/heap/heapam.c

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,16 +1048,23 @@ heap_beginscan(Relation relation, Snapshot snapshot,
10481048
/*
10491049
* allocate and initialize scan descriptor
10501050
*/
1051-
scan = (HeapScanDesc) palloc(sizeof(HeapScanDescData));
1051+
if (flags & SO_TYPE_BITMAPSCAN)
1052+
{
1053+
BitmapHeapScanDesc bscan = palloc(sizeof(BitmapHeapScanDescData));
1054+
1055+
bscan->rs_vmbuffer = InvalidBuffer;
1056+
bscan->rs_empty_tuples_pending = 0;
1057+
scan = (HeapScanDesc) bscan;
1058+
}
1059+
else
1060+
scan = (HeapScanDesc) palloc(sizeof(HeapScanDescData));
10521061

10531062
scan->rs_base.rs_rd = relation;
10541063
scan->rs_base.rs_snapshot = snapshot;
10551064
scan->rs_base.rs_nkeys = nkeys;
10561065
scan->rs_base.rs_flags = flags;
10571066
scan->rs_base.rs_parallel = parallel_scan;
10581067
scan->rs_strategy = NULL; /* set in initscan */
1059-
scan->rs_vmbuffer = InvalidBuffer;
1060-
scan->rs_empty_tuples_pending = 0;
10611068

10621069
/*
10631070
* Disable page-at-a-time mode if it's not a MVCC-safe snapshot.
@@ -1173,18 +1180,23 @@ heap_rescan(TableScanDesc sscan, ScanKey key, bool set_params,
11731180
if (BufferIsValid(scan->rs_cbuf))
11741181
ReleaseBuffer(scan->rs_cbuf);
11751182

1176-
if (BufferIsValid(scan->rs_vmbuffer))
1183+
if (scan->rs_base.rs_flags & SO_TYPE_BITMAPSCAN)
11771184
{
1178-
ReleaseBuffer(scan->rs_vmbuffer);
1179-
scan->rs_vmbuffer = InvalidBuffer;
1180-
}
1185+
BitmapHeapScanDesc bscan = (BitmapHeapScanDesc) scan;
11811186

1182-
/*
1183-
* Reset rs_empty_tuples_pending, a field only used by bitmap heap scan,
1184-
* to avoid incorrectly emitting NULL-filled tuples from a previous scan
1185-
* on rescan.
1186-
*/
1187-
scan->rs_empty_tuples_pending = 0;
1187+
/*
1188+
* Reset empty_tuples_pending, a field only used by bitmap heap scan,
1189+
* to avoid incorrectly emitting NULL-filled tuples from a previous
1190+
* scan on rescan.
1191+
*/
1192+
bscan->rs_empty_tuples_pending = 0;
1193+
1194+
if (BufferIsValid(bscan->rs_vmbuffer))
1195+
{
1196+
ReleaseBuffer(bscan->rs_vmbuffer);
1197+
bscan->rs_vmbuffer = InvalidBuffer;
1198+
}
1199+
}
11881200

11891201
/*
11901202
* The read stream is reset on rescan. This must be done before
@@ -1213,8 +1225,14 @@ heap_endscan(TableScanDesc sscan)
12131225
if (BufferIsValid(scan->rs_cbuf))
12141226
ReleaseBuffer(scan->rs_cbuf);
12151227

1216-
if (BufferIsValid(scan->rs_vmbuffer))
1217-
ReleaseBuffer(scan->rs_vmbuffer);
1228+
if (scan->rs_base.rs_flags & SO_TYPE_BITMAPSCAN)
1229+
{
1230+
BitmapHeapScanDesc bscan = (BitmapHeapScanDesc) sscan;
1231+
1232+
bscan->rs_empty_tuples_pending = 0;
1233+
if (BufferIsValid(bscan->rs_vmbuffer))
1234+
ReleaseBuffer(bscan->rs_vmbuffer);
1235+
}
12181236

12191237
/*
12201238
* Must free the read stream before freeing the BufferAccessStrategy.

src/backend/access/heap/heapam_handler.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2118,13 +2118,16 @@ heapam_scan_bitmap_next_block(TableScanDesc scan,
21182118
BlockNumber *blockno, bool *recheck,
21192119
uint64 *lossy_pages, uint64 *exact_pages)
21202120
{
2121-
HeapScanDesc hscan = (HeapScanDesc) scan;
2121+
BitmapHeapScanDesc bscan = (BitmapHeapScanDesc) scan;
2122+
HeapScanDesc hscan = (HeapScanDesc) bscan;
21222123
BlockNumber block;
21232124
Buffer buffer;
21242125
Snapshot snapshot;
21252126
int ntup;
21262127
TBMIterateResult *tbmres;
21272128

2129+
Assert(scan->rs_flags & SO_TYPE_BITMAPSCAN);
2130+
21282131
hscan->rs_cindex = 0;
21292132
hscan->rs_ntuples = 0;
21302133

@@ -2162,13 +2165,13 @@ heapam_scan_bitmap_next_block(TableScanDesc scan,
21622165
*/
21632166
if (!(scan->rs_flags & SO_NEED_TUPLES) &&
21642167
!tbmres->recheck &&
2165-
VM_ALL_VISIBLE(scan->rs_rd, tbmres->blockno, &hscan->rs_vmbuffer))
2168+
VM_ALL_VISIBLE(scan->rs_rd, tbmres->blockno, &bscan->rs_vmbuffer))
21662169
{
21672170
/* can't be lossy in the skip_fetch case */
21682171
Assert(tbmres->ntuples >= 0);
2169-
Assert(hscan->rs_empty_tuples_pending >= 0);
2172+
Assert(bscan->rs_empty_tuples_pending >= 0);
21702173

2171-
hscan->rs_empty_tuples_pending += tbmres->ntuples;
2174+
bscan->rs_empty_tuples_pending += tbmres->ntuples;
21722175

21732176
return true;
21742177
}
@@ -2282,18 +2285,19 @@ static bool
22822285
heapam_scan_bitmap_next_tuple(TableScanDesc scan,
22832286
TupleTableSlot *slot)
22842287
{
2285-
HeapScanDesc hscan = (HeapScanDesc) scan;
2288+
BitmapHeapScanDesc bscan = (BitmapHeapScanDesc) scan;
2289+
HeapScanDesc hscan = (HeapScanDesc) bscan;
22862290
OffsetNumber targoffset;
22872291
Page page;
22882292
ItemId lp;
22892293

2290-
if (hscan->rs_empty_tuples_pending > 0)
2294+
if (bscan->rs_empty_tuples_pending > 0)
22912295
{
22922296
/*
22932297
* If we don't have to fetch the tuple, just return nulls.
22942298
*/
22952299
ExecStoreAllNullTuple(slot);
2296-
hscan->rs_empty_tuples_pending--;
2300+
bscan->rs_empty_tuples_pending--;
22972301
return true;
22982302
}
22992303

src/include/access/heapam.h

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,22 +92,30 @@ typedef struct HeapScanDescData
9292
*/
9393
ParallelBlockTableScanWorkerData *rs_parallelworkerdata;
9494

95+
/* these fields only used in page-at-a-time mode and for bitmap scans */
96+
uint32 rs_cindex; /* current tuple's index in vistuples */
97+
uint32 rs_ntuples; /* number of visible tuples on page */
98+
OffsetNumber rs_vistuples[MaxHeapTuplesPerPage]; /* their offsets */
99+
} HeapScanDescData;
100+
typedef struct HeapScanDescData *HeapScanDesc;
101+
102+
typedef struct BitmapHeapScanDescData
103+
{
104+
HeapScanDescData rs_heap_base;
105+
95106
/*
96107
* These fields are only used for bitmap scans for the "skip fetch"
97108
* optimization. Bitmap scans needing no fields from the heap may skip
98109
* fetching an all visible block, instead using the number of tuples per
99110
* block reported by the bitmap to determine how many NULL-filled tuples
100-
* to return.
111+
* to return. They are common to parallel and serial BitmapHeapScans
101112
*/
113+
114+
/* page of VM containing info for current block */
102115
Buffer rs_vmbuffer;
103116
int rs_empty_tuples_pending;
104-
105-
/* these fields only used in page-at-a-time mode and for bitmap scans */
106-
uint32 rs_cindex; /* current tuple's index in vistuples */
107-
uint32 rs_ntuples; /* number of visible tuples on page */
108-
OffsetNumber rs_vistuples[MaxHeapTuplesPerPage]; /* their offsets */
109-
} HeapScanDescData;
110-
typedef struct HeapScanDescData *HeapScanDesc;
117+
} BitmapHeapScanDescData;
118+
typedef struct BitmapHeapScanDescData *BitmapHeapScanDesc;
111119

112120
/*
113121
* Descriptor for fetches from heap via an index.

src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ BitmapAndState
264264
BitmapHeapPath
265265
BitmapHeapScan
266266
BitmapHeapScanInstrumentation
267+
BitmapHeapScanDesc
267268
BitmapHeapScanState
268269
BitmapIndexScan
269270
BitmapIndexScanState

0 commit comments

Comments
 (0)