Add and use BitmapHeapScanDescData struct
authorMelanie Plageman
Thu, 16 Jan 2025 23:42:39 +0000 (18:42 -0500)
committerMelanie Plageman
Thu, 16 Jan 2025 23:42:39 +0000 (18:42 -0500)
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

src/backend/access/heap/heapam.c
src/backend/access/heap/heapam_handler.c
src/include/access/heapam.h
src/tools/pgindent/typedefs.list

index 485525f4d646043733fe4d55a0b8c03ff99c6884..b6349950294b22b15104d6fb39472cdf1444af14 100644 (file)
@@ -1048,7 +1048,16 @@ heap_beginscan(Relation relation, Snapshot snapshot,
    /*
     * allocate and initialize scan descriptor
     */
-   scan = (HeapScanDesc) palloc(sizeof(HeapScanDescData));
+   if (flags & SO_TYPE_BITMAPSCAN)
+   {
+       BitmapHeapScanDesc bscan = palloc(sizeof(BitmapHeapScanDescData));
+
+       bscan->rs_vmbuffer = InvalidBuffer;
+       bscan->rs_empty_tuples_pending = 0;
+       scan = (HeapScanDesc) bscan;
+   }
+   else
+       scan = (HeapScanDesc) palloc(sizeof(HeapScanDescData));
 
    scan->rs_base.rs_rd = relation;
    scan->rs_base.rs_snapshot = snapshot;
@@ -1056,8 +1065,6 @@ heap_beginscan(Relation relation, Snapshot snapshot,
    scan->rs_base.rs_flags = flags;
    scan->rs_base.rs_parallel = parallel_scan;
    scan->rs_strategy = NULL;   /* set in initscan */
-   scan->rs_vmbuffer = InvalidBuffer;
-   scan->rs_empty_tuples_pending = 0;
 
    /*
     * 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,
    if (BufferIsValid(scan->rs_cbuf))
        ReleaseBuffer(scan->rs_cbuf);
 
-   if (BufferIsValid(scan->rs_vmbuffer))
+   if (scan->rs_base.rs_flags & SO_TYPE_BITMAPSCAN)
    {
-       ReleaseBuffer(scan->rs_vmbuffer);
-       scan->rs_vmbuffer = InvalidBuffer;
-   }
+       BitmapHeapScanDesc bscan = (BitmapHeapScanDesc) scan;
 
-   /*
-    * Reset rs_empty_tuples_pending, a field only used by bitmap heap scan,
-    * to avoid incorrectly emitting NULL-filled tuples from a previous scan
-    * on rescan.
-    */
-   scan->rs_empty_tuples_pending = 0;
+       /*
+        * Reset empty_tuples_pending, a field only used by bitmap heap scan,
+        * to avoid incorrectly emitting NULL-filled tuples from a previous
+        * scan on rescan.
+        */
+       bscan->rs_empty_tuples_pending = 0;
+
+       if (BufferIsValid(bscan->rs_vmbuffer))
+       {
+           ReleaseBuffer(bscan->rs_vmbuffer);
+           bscan->rs_vmbuffer = InvalidBuffer;
+       }
+   }
 
    /*
     * The read stream is reset on rescan. This must be done before
@@ -1213,8 +1225,14 @@ heap_endscan(TableScanDesc sscan)
    if (BufferIsValid(scan->rs_cbuf))
        ReleaseBuffer(scan->rs_cbuf);
 
-   if (BufferIsValid(scan->rs_vmbuffer))
-       ReleaseBuffer(scan->rs_vmbuffer);
+   if (scan->rs_base.rs_flags & SO_TYPE_BITMAPSCAN)
+   {
+       BitmapHeapScanDesc bscan = (BitmapHeapScanDesc) sscan;
+
+       bscan->rs_empty_tuples_pending = 0;
+       if (BufferIsValid(bscan->rs_vmbuffer))
+           ReleaseBuffer(bscan->rs_vmbuffer);
+   }
 
    /*
     * Must free the read stream before freeing the BufferAccessStrategy.
index e817f8f8f8479f6af5e04468a0dd2bee8d47f1f0..a4003cf59e1fb3115419d97ed2079813f36675a8 100644 (file)
@@ -2118,13 +2118,16 @@ heapam_scan_bitmap_next_block(TableScanDesc scan,
                              BlockNumber *blockno, bool *recheck,
                              uint64 *lossy_pages, uint64 *exact_pages)
 {
-   HeapScanDesc hscan = (HeapScanDesc) scan;
+   BitmapHeapScanDesc bscan = (BitmapHeapScanDesc) scan;
+   HeapScanDesc hscan = (HeapScanDesc) bscan;
    BlockNumber block;
    Buffer      buffer;
    Snapshot    snapshot;
    int         ntup;
    TBMIterateResult *tbmres;
 
+   Assert(scan->rs_flags & SO_TYPE_BITMAPSCAN);
+
    hscan->rs_cindex = 0;
    hscan->rs_ntuples = 0;
 
@@ -2162,13 +2165,13 @@ heapam_scan_bitmap_next_block(TableScanDesc scan,
     */
    if (!(scan->rs_flags & SO_NEED_TUPLES) &&
        !tbmres->recheck &&
-       VM_ALL_VISIBLE(scan->rs_rd, tbmres->blockno, &hscan->rs_vmbuffer))
+       VM_ALL_VISIBLE(scan->rs_rd, tbmres->blockno, &bscan->rs_vmbuffer))
    {
        /* can't be lossy in the skip_fetch case */
        Assert(tbmres->ntuples >= 0);
-       Assert(hscan->rs_empty_tuples_pending >= 0);
+       Assert(bscan->rs_empty_tuples_pending >= 0);
 
-       hscan->rs_empty_tuples_pending += tbmres->ntuples;
+       bscan->rs_empty_tuples_pending += tbmres->ntuples;
 
        return true;
    }
@@ -2282,18 +2285,19 @@ static bool
 heapam_scan_bitmap_next_tuple(TableScanDesc scan,
                              TupleTableSlot *slot)
 {
-   HeapScanDesc hscan = (HeapScanDesc) scan;
+   BitmapHeapScanDesc bscan = (BitmapHeapScanDesc) scan;
+   HeapScanDesc hscan = (HeapScanDesc) bscan;
    OffsetNumber targoffset;
    Page        page;
    ItemId      lp;
 
-   if (hscan->rs_empty_tuples_pending > 0)
+   if (bscan->rs_empty_tuples_pending > 0)
    {
        /*
         * If we don't have to fetch the tuple, just return nulls.
         */
        ExecStoreAllNullTuple(slot);
-       hscan->rs_empty_tuples_pending--;
+       bscan->rs_empty_tuples_pending--;
        return true;
    }
 
index 7d06dad83fcd30ce13307f1d040d838900083c22..1640d9c32f7c3f337a0de52842a5bcce51c32259 100644 (file)
@@ -92,22 +92,30 @@ typedef struct HeapScanDescData
     */
    ParallelBlockTableScanWorkerData *rs_parallelworkerdata;
 
+   /* these fields only used in page-at-a-time mode and for bitmap scans */
+   uint32      rs_cindex;      /* current tuple's index in vistuples */
+   uint32      rs_ntuples;     /* number of visible tuples on page */
+   OffsetNumber rs_vistuples[MaxHeapTuplesPerPage];    /* their offsets */
+}          HeapScanDescData;
+typedef struct HeapScanDescData *HeapScanDesc;
+
+typedef struct BitmapHeapScanDescData
+{
+   HeapScanDescData rs_heap_base;
+
    /*
     * These fields are only used for bitmap scans for the "skip fetch"
     * optimization. Bitmap scans needing no fields from the heap may skip
     * fetching an all visible block, instead using the number of tuples per
     * block reported by the bitmap to determine how many NULL-filled tuples
-    * to return.
+    * to return. They are common to parallel and serial BitmapHeapScans
     */
+
+   /* page of VM containing info for current block */
    Buffer      rs_vmbuffer;
    int         rs_empty_tuples_pending;
-
-   /* these fields only used in page-at-a-time mode and for bitmap scans */
-   uint32      rs_cindex;      /* current tuple's index in vistuples */
-   uint32      rs_ntuples;     /* number of visible tuples on page */
-   OffsetNumber rs_vistuples[MaxHeapTuplesPerPage];    /* their offsets */
-}          HeapScanDescData;
-typedef struct HeapScanDescData *HeapScanDesc;
+}          BitmapHeapScanDescData;
+typedef struct BitmapHeapScanDescData *BitmapHeapScanDesc;
 
 /*
  * Descriptor for fetches from heap via an index.
index ebba5b7c9537c1b5a876553847296c4930f7c24b..d03921a48223b111f1212097a15341dac66f766c 100644 (file)
@@ -264,6 +264,7 @@ BitmapAndState
 BitmapHeapPath
 BitmapHeapScan
 BitmapHeapScanInstrumentation
+BitmapHeapScanDesc
 BitmapHeapScanState
 BitmapIndexScan
 BitmapIndexScanState