PostgreSQL Source Code  git master
nodeBitmapHeapscan.c File Reference
#include "postgres.h"
#include <math.h>
#include "access/relscan.h"
#include "access/tableam.h"
#include "access/visibilitymap.h"
#include "executor/executor.h"
#include "executor/nodeBitmapHeapscan.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "storage/bufmgr.h"
#include "utils/rel.h"
#include "utils/snapmgr.h"
#include "utils/spccache.h"
Include dependency graph for nodeBitmapHeapscan.c:

Go to the source code of this file.

Functions

static TupleTableSlotBitmapHeapNext (BitmapHeapScanState *node)
 
static void BitmapDoneInitializingSharedState (ParallelBitmapHeapState *pstate)
 
static void BitmapAdjustPrefetchIterator (BitmapHeapScanState *node, BlockNumber blockno)
 
static void BitmapAdjustPrefetchTarget (BitmapHeapScanState *node)
 
static void BitmapPrefetch (BitmapHeapScanState *node, TableScanDesc scan)
 
static bool BitmapShouldInitializeSharedState (ParallelBitmapHeapState *pstate)
 
static bool BitmapHeapRecheck (BitmapHeapScanState *node, TupleTableSlot *slot)
 
static TupleTableSlotExecBitmapHeapScan (PlanState *pstate)
 
void ExecReScanBitmapHeapScan (BitmapHeapScanState *node)
 
void ExecEndBitmapHeapScan (BitmapHeapScanState *node)
 
BitmapHeapScanStateExecInitBitmapHeapScan (BitmapHeapScan *node, EState *estate, int eflags)
 
void ExecBitmapHeapEstimate (BitmapHeapScanState *node, ParallelContext *pcxt)
 
void ExecBitmapHeapInitializeDSM (BitmapHeapScanState *node, ParallelContext *pcxt)
 
void ExecBitmapHeapReInitializeDSM (BitmapHeapScanState *node, ParallelContext *pcxt)
 
void ExecBitmapHeapInitializeWorker (BitmapHeapScanState *node, ParallelWorkerContext *pwcxt)
 

Function Documentation

◆ BitmapAdjustPrefetchIterator()

static void BitmapAdjustPrefetchIterator ( BitmapHeapScanState node,
BlockNumber  blockno 
)
inlinestatic

Definition at line 344 of file nodeBitmapHeapscan.c.

346 {
347 #ifdef USE_PREFETCH
348  ParallelBitmapHeapState *pstate = node->pstate;
349 
350  if (pstate == NULL)
351  {
352  TBMIterator *prefetch_iterator = node->prefetch_iterator;
353 
354  if (node->prefetch_pages > 0)
355  {
356  /* The main iterator has closed the distance by one page */
357  node->prefetch_pages--;
358  }
359  else if (prefetch_iterator)
360  {
361  /* Do not let the prefetch iterator get behind the main one */
362  TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
363 
364  if (tbmpre == NULL || tbmpre->blockno != blockno)
365  elog(ERROR, "prefetch and main iterators are out of sync");
366  }
367  return;
368  }
369 
370  if (node->prefetch_maximum > 0)
371  {
372  TBMSharedIterator *prefetch_iterator = node->shared_prefetch_iterator;
373 
374  SpinLockAcquire(&pstate->mutex);
375  if (pstate->prefetch_pages > 0)
376  {
377  pstate->prefetch_pages--;
378  SpinLockRelease(&pstate->mutex);
379  }
380  else
381  {
382  /* Release the mutex before iterating */
383  SpinLockRelease(&pstate->mutex);
384 
385  /*
386  * In case of shared mode, we can not ensure that the current
387  * blockno of the main iterator and that of the prefetch iterator
388  * are same. It's possible that whatever blockno we are
389  * prefetching will be processed by another process. Therefore,
390  * we don't validate the blockno here as we do in non-parallel
391  * case.
392  */
393  if (prefetch_iterator)
394  tbm_shared_iterate(prefetch_iterator);
395  }
396  }
397 #endif /* USE_PREFETCH */
398 }
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define SpinLockRelease(lock)
Definition: spin.h:64
#define SpinLockAcquire(lock)
Definition: spin.h:62
ParallelBitmapHeapState * pstate
Definition: execnodes.h:1826
TBMIterator * prefetch_iterator
Definition: execnodes.h:1819
TBMSharedIterator * shared_prefetch_iterator
Definition: execnodes.h:1825
BlockNumber blockno
Definition: tidbitmap.h:42
TBMIterateResult * tbm_shared_iterate(TBMSharedIterator *iterator)
Definition: tidbitmap.c:1052
TBMIterateResult * tbm_iterate(TBMIterator *iterator)
Definition: tidbitmap.c:971

References TBMIterateResult::blockno, elog, ERROR, ParallelBitmapHeapState::mutex, BitmapHeapScanState::prefetch_iterator, BitmapHeapScanState::prefetch_maximum, ParallelBitmapHeapState::prefetch_pages, BitmapHeapScanState::prefetch_pages, BitmapHeapScanState::pstate, BitmapHeapScanState::shared_prefetch_iterator, SpinLockAcquire, SpinLockRelease, tbm_iterate(), and tbm_shared_iterate().

Referenced by BitmapHeapNext().

◆ BitmapAdjustPrefetchTarget()

static void BitmapAdjustPrefetchTarget ( BitmapHeapScanState node)
inlinestatic

Definition at line 409 of file nodeBitmapHeapscan.c.

410 {
411 #ifdef USE_PREFETCH
412  ParallelBitmapHeapState *pstate = node->pstate;
413 
414  if (pstate == NULL)
415  {
416  if (node->prefetch_target >= node->prefetch_maximum)
417  /* don't increase any further */ ;
418  else if (node->prefetch_target >= node->prefetch_maximum / 2)
419  node->prefetch_target = node->prefetch_maximum;
420  else if (node->prefetch_target > 0)
421  node->prefetch_target *= 2;
422  else
423  node->prefetch_target++;
424  return;
425  }
426 
427  /* Do an unlocked check first to save spinlock acquisitions. */
428  if (pstate->prefetch_target < node->prefetch_maximum)
429  {
430  SpinLockAcquire(&pstate->mutex);
431  if (pstate->prefetch_target >= node->prefetch_maximum)
432  /* don't increase any further */ ;
433  else if (pstate->prefetch_target >= node->prefetch_maximum / 2)
434  pstate->prefetch_target = node->prefetch_maximum;
435  else if (pstate->prefetch_target > 0)
436  pstate->prefetch_target *= 2;
437  else
438  pstate->prefetch_target++;
439  SpinLockRelease(&pstate->mutex);
440  }
441 #endif /* USE_PREFETCH */
442 }

References ParallelBitmapHeapState::mutex, BitmapHeapScanState::prefetch_maximum, ParallelBitmapHeapState::prefetch_target, BitmapHeapScanState::prefetch_target, BitmapHeapScanState::pstate, SpinLockAcquire, and SpinLockRelease.

Referenced by BitmapHeapNext().

◆ BitmapDoneInitializingSharedState()

static void BitmapDoneInitializingSharedState ( ParallelBitmapHeapState pstate)
inlinestatic

Definition at line 332 of file nodeBitmapHeapscan.c.

333 {
334  SpinLockAcquire(&pstate->mutex);
335  pstate->state = BM_FINISHED;
336  SpinLockRelease(&pstate->mutex);
337  ConditionVariableBroadcast(&pstate->cv);
338 }
void ConditionVariableBroadcast(ConditionVariable *cv)
@ BM_FINISHED
Definition: execnodes.h:1763
SharedBitmapState state
Definition: execnodes.h:1785
ConditionVariable cv
Definition: execnodes.h:1786

References BM_FINISHED, ConditionVariableBroadcast(), ParallelBitmapHeapState::cv, ParallelBitmapHeapState::mutex, SpinLockAcquire, SpinLockRelease, and ParallelBitmapHeapState::state.

Referenced by BitmapHeapNext().

◆ BitmapHeapNext()

static TupleTableSlot * BitmapHeapNext ( BitmapHeapScanState node)
static

Definition at line 69 of file nodeBitmapHeapscan.c.

70 {
71  ExprContext *econtext;
72  TableScanDesc scan;
73  TIDBitmap *tbm;
74  TBMIterator *tbmiterator = NULL;
75  TBMSharedIterator *shared_tbmiterator = NULL;
76  TBMIterateResult *tbmres;
77  TupleTableSlot *slot;
78  ParallelBitmapHeapState *pstate = node->pstate;
79  dsa_area *dsa = node->ss.ps.state->es_query_dsa;
80 
81  /*
82  * extract necessary information from index scan node
83  */
84  econtext = node->ss.ps.ps_ExprContext;
85  slot = node->ss.ss_ScanTupleSlot;
86  scan = node->ss.ss_currentScanDesc;
87  tbm = node->tbm;
88  if (pstate == NULL)
89  tbmiterator = node->tbmiterator;
90  else
91  shared_tbmiterator = node->shared_tbmiterator;
92  tbmres = node->tbmres;
93 
94  /*
95  * If we haven't yet performed the underlying index scan, do it, and begin
96  * the iteration over the bitmap.
97  *
98  * For prefetching, we use *two* iterators, one for the pages we are
99  * actually scanning and another that runs ahead of the first for
100  * prefetching. node->prefetch_pages tracks exactly how many pages ahead
101  * the prefetch iterator is. Also, node->prefetch_target tracks the
102  * desired prefetch distance, which starts small and increases up to the
103  * node->prefetch_maximum. This is to avoid doing a lot of prefetching in
104  * a scan that stops after a few tuples because of a LIMIT.
105  */
106  if (!node->initialized)
107  {
108  if (!pstate)
109  {
110  tbm = (TIDBitmap *) MultiExecProcNode(outerPlanState(node));
111 
112  if (!tbm || !IsA(tbm, TIDBitmap))
113  elog(ERROR, "unrecognized result from subplan");
114 
115  node->tbm = tbm;
116  node->tbmiterator = tbmiterator = tbm_begin_iterate(tbm);
117  node->tbmres = tbmres = NULL;
118 
119 #ifdef USE_PREFETCH
120  if (node->prefetch_maximum > 0)
121  {
123  node->prefetch_pages = 0;
124  node->prefetch_target = -1;
125  }
126 #endif /* USE_PREFETCH */
127  }
128  else
129  {
130  /*
131  * The leader will immediately come out of the function, but
132  * others will be blocked until leader populates the TBM and wakes
133  * them up.
134  */
136  {
137  tbm = (TIDBitmap *) MultiExecProcNode(outerPlanState(node));
138  if (!tbm || !IsA(tbm, TIDBitmap))
139  elog(ERROR, "unrecognized result from subplan");
140 
141  node->tbm = tbm;
142 
143  /*
144  * Prepare to iterate over the TBM. This will return the
145  * dsa_pointer of the iterator state which will be used by
146  * multiple processes to iterate jointly.
147  */
149 #ifdef USE_PREFETCH
150  if (node->prefetch_maximum > 0)
151  {
152  pstate->prefetch_iterator =
154 
155  /*
156  * We don't need the mutex here as we haven't yet woke up
157  * others.
158  */
159  pstate->prefetch_pages = 0;
160  pstate->prefetch_target = -1;
161  }
162 #endif
163 
164  /* We have initialized the shared state so wake up others. */
166  }
167 
168  /* Allocate a private iterator and attach the shared state to it */
169  node->shared_tbmiterator = shared_tbmiterator =
171  node->tbmres = tbmres = NULL;
172 
173 #ifdef USE_PREFETCH
174  if (node->prefetch_maximum > 0)
175  {
178  }
179 #endif /* USE_PREFETCH */
180  }
181 
182  /*
183  * If this is the first scan of the underlying table, create the table
184  * scan descriptor and begin the scan.
185  */
186  if (!scan)
187  {
188  bool need_tuples = false;
189 
190  /*
191  * We can potentially skip fetching heap pages if we do not need
192  * any columns of the table, either for checking non-indexable
193  * quals or for returning data. This test is a bit simplistic, as
194  * it checks the stronger condition that there's no qual or return
195  * tlist at all. But in most cases it's probably not worth working
196  * harder than that.
197  */
198  need_tuples = (node->ss.ps.plan->qual != NIL ||
199  node->ss.ps.plan->targetlist != NIL);
200 
202  node->ss.ps.state->es_snapshot,
203  0,
204  NULL,
205  need_tuples);
206 
207  node->ss.ss_currentScanDesc = scan;
208  }
209 
210  node->initialized = true;
211  }
212 
213  for (;;)
214  {
215  bool valid_block;
216 
218 
219  /*
220  * Get next page of results if needed
221  */
222  if (tbmres == NULL)
223  {
224  if (!pstate)
225  node->tbmres = tbmres = tbm_iterate(tbmiterator);
226  else
227  node->tbmres = tbmres = tbm_shared_iterate(shared_tbmiterator);
228  if (tbmres == NULL)
229  {
230  /* no more entries in the bitmap */
231  break;
232  }
233 
234  BitmapAdjustPrefetchIterator(node, tbmres->blockno);
235 
236  valid_block = table_scan_bitmap_next_block(scan, tbmres);
237 
238  if (tbmres->ntuples >= 0)
239  node->exact_pages++;
240  else
241  node->lossy_pages++;
242 
243  if (!valid_block)
244  {
245  /* AM doesn't think this block is valid, skip */
246  continue;
247  }
248 
249  /* Adjust the prefetch target */
251  }
252  else
253  {
254  /*
255  * Continuing in previously obtained page.
256  */
257 
258 #ifdef USE_PREFETCH
259 
260  /*
261  * Try to prefetch at least a few pages even before we get to the
262  * second page if we don't stop reading after the first tuple.
263  */
264  if (!pstate)
265  {
266  if (node->prefetch_target < node->prefetch_maximum)
267  node->prefetch_target++;
268  }
269  else if (pstate->prefetch_target < node->prefetch_maximum)
270  {
271  /* take spinlock while updating shared state */
272  SpinLockAcquire(&pstate->mutex);
273  if (pstate->prefetch_target < node->prefetch_maximum)
274  pstate->prefetch_target++;
275  SpinLockRelease(&pstate->mutex);
276  }
277 #endif /* USE_PREFETCH */
278  }
279 
280  /*
281  * We issue prefetch requests *after* fetching the current page to try
282  * to avoid having prefetching interfere with the main I/O. Also, this
283  * should happen only when we have determined there is still something
284  * to do on the current page, else we may uselessly prefetch the same
285  * page we are just about to request for real.
286  */
287  BitmapPrefetch(node, scan);
288 
289  /*
290  * Attempt to fetch tuple from AM.
291  */
292  if (!table_scan_bitmap_next_tuple(scan, tbmres, slot))
293  {
294  /* nothing more to look at on this page */
295  node->tbmres = tbmres = NULL;
296  continue;
297  }
298 
299  /*
300  * If we are using lossy info, we have to recheck the qual conditions
301  * at every tuple.
302  */
303  if (tbmres->recheck)
304  {
305  econtext->ecxt_scantuple = slot;
306  if (!ExecQualAndReset(node->bitmapqualorig, econtext))
307  {
308  /* Fails recheck, so drop it and loop back for another */
309  InstrCountFiltered2(node, 1);
310  ExecClearTuple(slot);
311  continue;
312  }
313  }
314 
315  /* OK to return this tuple */
316  return slot;
317  }
318 
319  /*
320  * if we get here it means we are at the end of the scan..
321  */
322  return ExecClearTuple(slot);
323 }
Node * MultiExecProcNode(PlanState *node)
Definition: execProcnode.c:502
#define outerPlanState(node)
Definition: execnodes.h:1213
#define InstrCountFiltered2(node, delta)
Definition: execnodes.h:1226
static bool ExecQualAndReset(ExprState *state, ExprContext *econtext)
Definition: executor.h:440
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
static bool BitmapShouldInitializeSharedState(ParallelBitmapHeapState *pstate)
static void BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
static void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node, BlockNumber blockno)
static void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node)
static void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate)
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define NIL
Definition: pg_list.h:68
ExprState * bitmapqualorig
Definition: execnodes.h:1812
TBMIterateResult * tbmres
Definition: execnodes.h:1815
TBMIterator * tbmiterator
Definition: execnodes.h:1814
TIDBitmap * tbm
Definition: execnodes.h:1813
TBMSharedIterator * shared_tbmiterator
Definition: execnodes.h:1824
struct dsa_area * es_query_dsa
Definition: execnodes.h:704
Snapshot es_snapshot
Definition: execnodes.h:624
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:255
dsa_pointer tbmiterator
Definition: execnodes.h:1780
dsa_pointer prefetch_iterator
Definition: execnodes.h:1781
Plan * plan
Definition: execnodes.h:1117
EState * state
Definition: execnodes.h:1119
ExprContext * ps_ExprContext
Definition: execnodes.h:1156
List * qual
Definition: plannodes.h:153
List * targetlist
Definition: plannodes.h:152
Relation ss_currentRelation
Definition: execnodes.h:1565
TupleTableSlot * ss_ScanTupleSlot
Definition: execnodes.h:1567
PlanState ps
Definition: execnodes.h:1564
struct TableScanDescData * ss_currentScanDesc
Definition: execnodes.h:1566
Definition: dsa.c:348
static bool table_scan_bitmap_next_tuple(TableScanDesc scan, struct TBMIterateResult *tbmres, TupleTableSlot *slot)
Definition: tableam.h:1995
static bool table_scan_bitmap_next_block(TableScanDesc scan, struct TBMIterateResult *tbmres)
Definition: tableam.h:1971
static TableScanDesc table_beginscan_bm(Relation rel, Snapshot snapshot, int nkeys, struct ScanKeyData *key, bool need_tuple)
Definition: tableam.h:963
TBMIterator * tbm_begin_iterate(TIDBitmap *tbm)
Definition: tidbitmap.c:689
TBMSharedIterator * tbm_attach_shared_iterate(dsa_area *dsa, dsa_pointer dp)
Definition: tidbitmap.c:1461
dsa_pointer tbm_prepare_shared_iterate(TIDBitmap *tbm)
Definition: tidbitmap.c:766
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:454

References BitmapAdjustPrefetchIterator(), BitmapAdjustPrefetchTarget(), BitmapDoneInitializingSharedState(), BitmapPrefetch(), BitmapHeapScanState::bitmapqualorig, BitmapShouldInitializeSharedState(), TBMIterateResult::blockno, CHECK_FOR_INTERRUPTS, ExprContext::ecxt_scantuple, elog, ERROR, EState::es_query_dsa, EState::es_snapshot, BitmapHeapScanState::exact_pages, ExecClearTuple(), ExecQualAndReset(), BitmapHeapScanState::initialized, InstrCountFiltered2, IsA, BitmapHeapScanState::lossy_pages, MultiExecProcNode(), ParallelBitmapHeapState::mutex, NIL, TBMIterateResult::ntuples, outerPlanState, PlanState::plan, ParallelBitmapHeapState::prefetch_iterator, BitmapHeapScanState::prefetch_iterator, BitmapHeapScanState::prefetch_maximum, ParallelBitmapHeapState::prefetch_pages, BitmapHeapScanState::prefetch_pages, ParallelBitmapHeapState::prefetch_target, BitmapHeapScanState::prefetch_target, ScanState::ps, PlanState::ps_ExprContext, BitmapHeapScanState::pstate, Plan::qual, TBMIterateResult::recheck, BitmapHeapScanState::shared_prefetch_iterator, BitmapHeapScanState::shared_tbmiterator, SpinLockAcquire, SpinLockRelease, BitmapHeapScanState::ss, ScanState::ss_currentRelation, ScanState::ss_currentScanDesc, ScanState::ss_ScanTupleSlot, PlanState::state, table_beginscan_bm(), table_scan_bitmap_next_block(), table_scan_bitmap_next_tuple(), Plan::targetlist, BitmapHeapScanState::tbm, tbm_attach_shared_iterate(), tbm_begin_iterate(), tbm_iterate(), tbm_prepare_shared_iterate(), tbm_shared_iterate(), ParallelBitmapHeapState::tbmiterator, BitmapHeapScanState::tbmiterator, and BitmapHeapScanState::tbmres.

Referenced by ExecBitmapHeapScan().

◆ BitmapHeapRecheck()

static bool BitmapHeapRecheck ( BitmapHeapScanState node,
TupleTableSlot slot 
)
static

Definition at line 548 of file nodeBitmapHeapscan.c.

549 {
550  ExprContext *econtext;
551 
552  /*
553  * extract necessary information from index scan node
554  */
555  econtext = node->ss.ps.ps_ExprContext;
556 
557  /* Does the tuple meet the original qual conditions? */
558  econtext->ecxt_scantuple = slot;
559  return ExecQualAndReset(node->bitmapqualorig, econtext);
560 }

References BitmapHeapScanState::bitmapqualorig, ExprContext::ecxt_scantuple, ExecQualAndReset(), ScanState::ps, PlanState::ps_ExprContext, and BitmapHeapScanState::ss.

Referenced by ExecBitmapHeapScan().

◆ BitmapPrefetch()

static void BitmapPrefetch ( BitmapHeapScanState node,
TableScanDesc  scan 
)
inlinestatic

Definition at line 448 of file nodeBitmapHeapscan.c.

449 {
450 #ifdef USE_PREFETCH
451  ParallelBitmapHeapState *pstate = node->pstate;
452 
453  if (pstate == NULL)
454  {
455  TBMIterator *prefetch_iterator = node->prefetch_iterator;
456 
457  if (prefetch_iterator)
458  {
459  while (node->prefetch_pages < node->prefetch_target)
460  {
461  TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
462  bool skip_fetch;
463 
464  if (tbmpre == NULL)
465  {
466  /* No more pages to prefetch */
467  tbm_end_iterate(prefetch_iterator);
468  node->prefetch_iterator = NULL;
469  break;
470  }
471  node->prefetch_pages++;
472 
473  /*
474  * If we expect not to have to actually read this heap page,
475  * skip this prefetch call, but continue to run the prefetch
476  * logic normally. (Would it be better not to increment
477  * prefetch_pages?)
478  */
479  skip_fetch = (!(scan->rs_flags & SO_NEED_TUPLES) &&
480  !tbmpre->recheck &&
482  tbmpre->blockno,
483  &node->pvmbuffer));
484 
485  if (!skip_fetch)
486  PrefetchBuffer(scan->rs_rd, MAIN_FORKNUM, tbmpre->blockno);
487  }
488  }
489 
490  return;
491  }
492 
493  if (pstate->prefetch_pages < pstate->prefetch_target)
494  {
495  TBMSharedIterator *prefetch_iterator = node->shared_prefetch_iterator;
496 
497  if (prefetch_iterator)
498  {
499  while (1)
500  {
501  TBMIterateResult *tbmpre;
502  bool do_prefetch = false;
503  bool skip_fetch;
504 
505  /*
506  * Recheck under the mutex. If some other process has already
507  * done enough prefetching then we need not to do anything.
508  */
509  SpinLockAcquire(&pstate->mutex);
510  if (pstate->prefetch_pages < pstate->prefetch_target)
511  {
512  pstate->prefetch_pages++;
513  do_prefetch = true;
514  }
515  SpinLockRelease(&pstate->mutex);
516 
517  if (!do_prefetch)
518  return;
519 
520  tbmpre = tbm_shared_iterate(prefetch_iterator);
521  if (tbmpre == NULL)
522  {
523  /* No more pages to prefetch */
524  tbm_end_shared_iterate(prefetch_iterator);
525  node->shared_prefetch_iterator = NULL;
526  break;
527  }
528 
529  /* As above, skip prefetch if we expect not to need page */
530  skip_fetch = (!(scan->rs_flags & SO_NEED_TUPLES) &&
531  !tbmpre->recheck &&
533  tbmpre->blockno,
534  &node->pvmbuffer));
535 
536  if (!skip_fetch)
537  PrefetchBuffer(scan->rs_rd, MAIN_FORKNUM, tbmpre->blockno);
538  }
539  }
540  }
541 #endif /* USE_PREFETCH */
542 }
PrefetchBufferResult PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
Definition: bufmgr.c:638
@ MAIN_FORKNUM
Definition: relpath.h:50
Relation rs_rd
Definition: relscan.h:34
uint32 rs_flags
Definition: relscan.h:47
@ SO_NEED_TUPLES
Definition: tableam.h:72
void tbm_end_iterate(TBMIterator *iterator)
Definition: tidbitmap.c:1146
void tbm_end_shared_iterate(TBMSharedIterator *iterator)
Definition: tidbitmap.c:1158
#define VM_ALL_VISIBLE(r, b, v)
Definition: visibilitymap.h:24

References TBMIterateResult::blockno, MAIN_FORKNUM, ParallelBitmapHeapState::mutex, BitmapHeapScanState::prefetch_iterator, ParallelBitmapHeapState::prefetch_pages, BitmapHeapScanState::prefetch_pages, ParallelBitmapHeapState::prefetch_target, BitmapHeapScanState::prefetch_target, PrefetchBuffer(), BitmapHeapScanState::pstate, BitmapHeapScanState::pvmbuffer, TBMIterateResult::recheck, TableScanDescData::rs_flags, TableScanDescData::rs_rd, BitmapHeapScanState::shared_prefetch_iterator, SO_NEED_TUPLES, SpinLockAcquire, SpinLockRelease, BitmapHeapScanState::ss, ScanState::ss_currentRelation, tbm_end_iterate(), tbm_end_shared_iterate(), tbm_iterate(), tbm_shared_iterate(), and VM_ALL_VISIBLE.

Referenced by BitmapHeapNext().

◆ BitmapShouldInitializeSharedState()

static bool BitmapShouldInitializeSharedState ( ParallelBitmapHeapState pstate)
static

Definition at line 770 of file nodeBitmapHeapscan.c.

771 {
773 
774  while (1)
775  {
776  SpinLockAcquire(&pstate->mutex);
777  state = pstate->state;
778  if (pstate->state == BM_INITIAL)
779  pstate->state = BM_INPROGRESS;
780  SpinLockRelease(&pstate->mutex);
781 
782  /* Exit if bitmap is done, or if we're the leader. */
783  if (state != BM_INPROGRESS)
784  break;
785 
786  /* Wait for the leader to wake us up. */
787  ConditionVariableSleep(&pstate->cv, WAIT_EVENT_PARALLEL_BITMAP_SCAN);
788  }
789 
791 
792  return (state == BM_INITIAL);
793 }
bool ConditionVariableCancelSleep(void)
void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
SharedBitmapState
Definition: execnodes.h:1760
@ BM_INITIAL
Definition: execnodes.h:1761
@ BM_INPROGRESS
Definition: execnodes.h:1762
Definition: regguts.h:323

References BM_INITIAL, BM_INPROGRESS, ConditionVariableCancelSleep(), ConditionVariableSleep(), ParallelBitmapHeapState::cv, ParallelBitmapHeapState::mutex, SpinLockAcquire, SpinLockRelease, and ParallelBitmapHeapState::state.

Referenced by BitmapHeapNext().

◆ ExecBitmapHeapEstimate()

void ExecBitmapHeapEstimate ( BitmapHeapScanState node,
ParallelContext pcxt 
)

Definition at line 803 of file nodeBitmapHeapscan.c.

805 {
807  shm_toc_estimate_keys(&pcxt->estimator, 1);
808 }
#define shm_toc_estimate_chunk(e, sz)
Definition: shm_toc.h:51
#define shm_toc_estimate_keys(e, cnt)
Definition: shm_toc.h:53
shm_toc_estimator estimator
Definition: parallel.h:41

References ParallelContext::estimator, shm_toc_estimate_chunk, and shm_toc_estimate_keys.

Referenced by ExecParallelEstimate().

◆ ExecBitmapHeapInitializeDSM()

void ExecBitmapHeapInitializeDSM ( BitmapHeapScanState node,
ParallelContext pcxt 
)

Definition at line 817 of file nodeBitmapHeapscan.c.

819 {
820  ParallelBitmapHeapState *pstate;
821  dsa_area *dsa = node->ss.ps.state->es_query_dsa;
822 
823  /* If there's no DSA, there are no workers; initialize nothing. */
824  if (dsa == NULL)
825  return;
826 
827  pstate = shm_toc_allocate(pcxt->toc, sizeof(ParallelBitmapHeapState));
828 
829  pstate->tbmiterator = 0;
830  pstate->prefetch_iterator = 0;
831 
832  /* Initialize the mutex */
833  SpinLockInit(&pstate->mutex);
834  pstate->prefetch_pages = 0;
835  pstate->prefetch_target = 0;
836  pstate->state = BM_INITIAL;
837 
838  ConditionVariableInit(&pstate->cv);
839 
840  shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id, pstate);
841  node->pstate = pstate;
842 }
void ConditionVariableInit(ConditionVariable *cv)
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
Definition: shm_toc.c:171
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
Definition: shm_toc.c:88
#define SpinLockInit(lock)
Definition: spin.h:60
shm_toc * toc
Definition: parallel.h:44
int plan_node_id
Definition: plannodes.h:151

References BM_INITIAL, ConditionVariableInit(), ParallelBitmapHeapState::cv, EState::es_query_dsa, ParallelBitmapHeapState::mutex, PlanState::plan, Plan::plan_node_id, ParallelBitmapHeapState::prefetch_iterator, ParallelBitmapHeapState::prefetch_pages, ParallelBitmapHeapState::prefetch_target, ScanState::ps, BitmapHeapScanState::pstate, shm_toc_allocate(), shm_toc_insert(), SpinLockInit, BitmapHeapScanState::ss, PlanState::state, ParallelBitmapHeapState::state, ParallelBitmapHeapState::tbmiterator, and ParallelContext::toc.

Referenced by ExecParallelInitializeDSM().

◆ ExecBitmapHeapInitializeWorker()

void ExecBitmapHeapInitializeWorker ( BitmapHeapScanState node,
ParallelWorkerContext pwcxt 
)

Definition at line 880 of file nodeBitmapHeapscan.c.

882 {
883  ParallelBitmapHeapState *pstate;
884 
885  Assert(node->ss.ps.state->es_query_dsa != NULL);
886 
887  pstate = shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, false);
888  node->pstate = pstate;
889 }
#define Assert(condition)
Definition: c.h:858
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
Definition: shm_toc.c:232

References Assert, EState::es_query_dsa, PlanState::plan, Plan::plan_node_id, ScanState::ps, BitmapHeapScanState::pstate, shm_toc_lookup(), BitmapHeapScanState::ss, PlanState::state, and ParallelWorkerContext::toc.

Referenced by ExecParallelInitializeWorker().

◆ ExecBitmapHeapReInitializeDSM()

void ExecBitmapHeapReInitializeDSM ( BitmapHeapScanState node,
ParallelContext pcxt 
)

Definition at line 851 of file nodeBitmapHeapscan.c.

853 {
854  ParallelBitmapHeapState *pstate = node->pstate;
855  dsa_area *dsa = node->ss.ps.state->es_query_dsa;
856 
857  /* If there's no DSA, there are no workers; do nothing. */
858  if (dsa == NULL)
859  return;
860 
861  pstate->state = BM_INITIAL;
862 
863  if (DsaPointerIsValid(pstate->tbmiterator))
864  tbm_free_shared_area(dsa, pstate->tbmiterator);
865 
868 
869  pstate->tbmiterator = InvalidDsaPointer;
871 }
#define InvalidDsaPointer
Definition: dsa.h:78
#define DsaPointerIsValid(x)
Definition: dsa.h:106
void tbm_free_shared_area(dsa_area *dsa, dsa_pointer dp)
Definition: tidbitmap.c:341

References BM_INITIAL, DsaPointerIsValid, EState::es_query_dsa, InvalidDsaPointer, ParallelBitmapHeapState::prefetch_iterator, ScanState::ps, BitmapHeapScanState::pstate, BitmapHeapScanState::ss, PlanState::state, ParallelBitmapHeapState::state, tbm_free_shared_area(), and ParallelBitmapHeapState::tbmiterator.

Referenced by ExecParallelReInitializeDSM().

◆ ExecBitmapHeapScan()

static TupleTableSlot* ExecBitmapHeapScan ( PlanState pstate)
static

Definition at line 567 of file nodeBitmapHeapscan.c.

568 {
570 
571  return ExecScan(&node->ss,
574 }
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
Definition: execScan.c:156
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
Definition: executor.h:473
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
Definition: executor.h:474
static TupleTableSlot * BitmapHeapNext(BitmapHeapScanState *node)
static bool BitmapHeapRecheck(BitmapHeapScanState *node, TupleTableSlot *slot)
#define castNode(_type_, nodeptr)
Definition: nodes.h:176

References BitmapHeapNext(), BitmapHeapRecheck(), castNode, ExecScan(), and BitmapHeapScanState::ss.

Referenced by ExecInitBitmapHeapScan().

◆ ExecEndBitmapHeapScan()

void ExecEndBitmapHeapScan ( BitmapHeapScanState node)

Definition at line 626 of file nodeBitmapHeapscan.c.

627 {
628  TableScanDesc scanDesc;
629 
630  /*
631  * extract information from the node
632  */
633  scanDesc = node->ss.ss_currentScanDesc;
634 
635  /*
636  * close down subplans
637  */
639 
640  /*
641  * release bitmaps and buffers if any
642  */
643  if (node->tbmiterator)
645  if (node->prefetch_iterator)
647  if (node->tbm)
648  tbm_free(node->tbm);
649  if (node->shared_tbmiterator)
651  if (node->shared_prefetch_iterator)
653  if (node->pvmbuffer != InvalidBuffer)
654  ReleaseBuffer(node->pvmbuffer);
655 
656  /*
657  * close heap scan
658  */
659  if (scanDesc)
660  table_endscan(scanDesc);
661 
662 }
#define InvalidBuffer
Definition: buf.h:25
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:4850
void ExecEndNode(PlanState *node)
Definition: execProcnode.c:557
static void table_endscan(TableScanDesc scan)
Definition: tableam.h:1029
void tbm_free(TIDBitmap *tbm)
Definition: tidbitmap.c:322

References ExecEndNode(), InvalidBuffer, outerPlanState, BitmapHeapScanState::prefetch_iterator, BitmapHeapScanState::pvmbuffer, ReleaseBuffer(), BitmapHeapScanState::shared_prefetch_iterator, BitmapHeapScanState::shared_tbmiterator, BitmapHeapScanState::ss, ScanState::ss_currentScanDesc, table_endscan(), BitmapHeapScanState::tbm, tbm_end_iterate(), tbm_end_shared_iterate(), tbm_free(), and BitmapHeapScanState::tbmiterator.

Referenced by ExecEndNode().

◆ ExecInitBitmapHeapScan()

BitmapHeapScanState* ExecInitBitmapHeapScan ( BitmapHeapScan node,
EState estate,
int  eflags 
)

Definition at line 671 of file nodeBitmapHeapscan.c.

672 {
673  BitmapHeapScanState *scanstate;
674  Relation currentRelation;
675 
676  /* check for unsupported flags */
677  Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
678 
679  /*
680  * Assert caller didn't ask for an unsafe snapshot --- see comments at
681  * head of file.
682  */
684 
685  /*
686  * create state structure
687  */
688  scanstate = makeNode(BitmapHeapScanState);
689  scanstate->ss.ps.plan = (Plan *) node;
690  scanstate->ss.ps.state = estate;
691  scanstate->ss.ps.ExecProcNode = ExecBitmapHeapScan;
692 
693  scanstate->tbm = NULL;
694  scanstate->tbmiterator = NULL;
695  scanstate->tbmres = NULL;
696  scanstate->pvmbuffer = InvalidBuffer;
697  scanstate->exact_pages = 0;
698  scanstate->lossy_pages = 0;
699  scanstate->prefetch_iterator = NULL;
700  scanstate->prefetch_pages = 0;
701  scanstate->prefetch_target = 0;
702  scanstate->initialized = false;
703  scanstate->shared_tbmiterator = NULL;
704  scanstate->shared_prefetch_iterator = NULL;
705  scanstate->pstate = NULL;
706 
707  /*
708  * Miscellaneous initialization
709  *
710  * create expression context for node
711  */
712  ExecAssignExprContext(estate, &scanstate->ss.ps);
713 
714  /*
715  * open the scan relation
716  */
717  currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
718 
719  /*
720  * initialize child nodes
721  */
722  outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, eflags);
723 
724  /*
725  * get the scan type from the relation descriptor.
726  */
727  ExecInitScanTupleSlot(estate, &scanstate->ss,
728  RelationGetDescr(currentRelation),
729  table_slot_callbacks(currentRelation));
730 
731  /*
732  * Initialize result type and projection.
733  */
734  ExecInitResultTypeTL(&scanstate->ss.ps);
735  ExecAssignScanProjectionInfo(&scanstate->ss);
736 
737  /*
738  * initialize child expressions
739  */
740  scanstate->ss.ps.qual =
741  ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
742  scanstate->bitmapqualorig =
743  ExecInitQual(node->bitmapqualorig, (PlanState *) scanstate);
744 
745  /*
746  * Maximum number of prefetches for the tablespace if configured,
747  * otherwise the current value of the effective_io_concurrency GUC.
748  */
749  scanstate->prefetch_maximum =
750  get_tablespace_io_concurrency(currentRelation->rd_rel->reltablespace);
751 
752  scanstate->ss.ss_currentRelation = currentRelation;
753 
754  /*
755  * all done.
756  */
757  return scanstate;
758 }
ExprState * ExecInitQual(List *qual, PlanState *parent)
Definition: execExpr.c:220
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
Definition: execProcnode.c:142
void ExecAssignScanProjectionInfo(ScanState *node)
Definition: execScan.c:270
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1898
void ExecInitResultTypeTL(PlanState *planstate)
Definition: execTuples.c:1842
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:483
Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
Definition: execUtils.c:697
#define EXEC_FLAG_BACKWARD
Definition: executor.h:68
#define EXEC_FLAG_MARK
Definition: executor.h:69
static TupleTableSlot * ExecBitmapHeapScan(PlanState *pstate)
#define makeNode(_type_)
Definition: nodes.h:155
#define outerPlan(node)
Definition: plannodes.h:182
#define RelationGetDescr(relation)
Definition: rel.h:531
#define IsMVCCSnapshot(snapshot)
Definition: snapmgr.h:62
int get_tablespace_io_concurrency(Oid spcid)
Definition: spccache.c:215
List * bitmapqualorig
Definition: plannodes.h:541
ExprState * qual
Definition: execnodes.h:1138
ExecProcNodeMtd ExecProcNode
Definition: execnodes.h:1123
Form_pg_class rd_rel
Definition: rel.h:111
Index scanrelid
Definition: plannodes.h:389
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
Definition: tableam.c:58

References Assert, BitmapHeapScanState::bitmapqualorig, BitmapHeapScan::bitmapqualorig, EState::es_snapshot, BitmapHeapScanState::exact_pages, EXEC_FLAG_BACKWARD, EXEC_FLAG_MARK, ExecAssignExprContext(), ExecAssignScanProjectionInfo(), ExecBitmapHeapScan(), ExecInitNode(), ExecInitQual(), ExecInitResultTypeTL(), ExecInitScanTupleSlot(), ExecOpenScanRelation(), PlanState::ExecProcNode, get_tablespace_io_concurrency(), BitmapHeapScanState::initialized, InvalidBuffer, IsMVCCSnapshot, BitmapHeapScanState::lossy_pages, makeNode, outerPlan, outerPlanState, PlanState::plan, BitmapHeapScanState::prefetch_iterator, BitmapHeapScanState::prefetch_maximum, BitmapHeapScanState::prefetch_pages, BitmapHeapScanState::prefetch_target, ScanState::ps, BitmapHeapScanState::pstate, BitmapHeapScanState::pvmbuffer, PlanState::qual, RelationData::rd_rel, RelationGetDescr, BitmapHeapScan::scan, Scan::scanrelid, BitmapHeapScanState::shared_prefetch_iterator, BitmapHeapScanState::shared_tbmiterator, BitmapHeapScanState::ss, ScanState::ss_currentRelation, PlanState::state, table_slot_callbacks(), BitmapHeapScanState::tbm, BitmapHeapScanState::tbmiterator, and BitmapHeapScanState::tbmres.

Referenced by ExecInitNode().

◆ ExecReScanBitmapHeapScan()

void ExecReScanBitmapHeapScan ( BitmapHeapScanState node)

Definition at line 581 of file nodeBitmapHeapscan.c.

582 {
584 
585  /* rescan to release any page pin */
586  if (node->ss.ss_currentScanDesc)
587  table_rescan(node->ss.ss_currentScanDesc, NULL);
588 
589  /* release bitmaps and buffers if any */
590  if (node->tbmiterator)
592  if (node->prefetch_iterator)
594  if (node->shared_tbmiterator)
596  if (node->shared_prefetch_iterator)
598  if (node->tbm)
599  tbm_free(node->tbm);
600  if (node->pvmbuffer != InvalidBuffer)
601  ReleaseBuffer(node->pvmbuffer);
602  node->tbm = NULL;
603  node->tbmiterator = NULL;
604  node->tbmres = NULL;
605  node->prefetch_iterator = NULL;
606  node->initialized = false;
607  node->shared_tbmiterator = NULL;
608  node->shared_prefetch_iterator = NULL;
609  node->pvmbuffer = InvalidBuffer;
610 
611  ExecScanReScan(&node->ss);
612 
613  /*
614  * if chgParam of subnode is not null then plan will be re-scanned by
615  * first ExecProcNode.
616  */
617  if (outerPlan->chgParam == NULL)
619 }
void ExecReScan(PlanState *node)
Definition: execAmi.c:76
void ExecScanReScan(ScanState *node)
Definition: execScan.c:297
static void table_rescan(TableScanDesc scan, struct ScanKeyData *key)
Definition: tableam.h:1038

References ExecReScan(), ExecScanReScan(), BitmapHeapScanState::initialized, InvalidBuffer, outerPlan, outerPlanState, BitmapHeapScanState::prefetch_iterator, BitmapHeapScanState::pvmbuffer, ReleaseBuffer(), BitmapHeapScanState::shared_prefetch_iterator, BitmapHeapScanState::shared_tbmiterator, BitmapHeapScanState::ss, ScanState::ss_currentScanDesc, table_rescan(), BitmapHeapScanState::tbm, tbm_end_iterate(), tbm_end_shared_iterate(), tbm_free(), BitmapHeapScanState::tbmiterator, and BitmapHeapScanState::tbmres.

Referenced by ExecReScan().