*/
if (!node->initialized)
{
- TBMPrivateIterator *tbmiterator = NULL;
- TBMSharedIterator *shared_tbmiterator = NULL;
+ TBMIterator tbmiterator;
if (!pstate)
{
elog(ERROR, "unrecognized result from subplan");
node->tbm = tbm;
- tbmiterator = tbm_begin_private_iterate(tbm);
#ifdef USE_PREFETCH
if (node->prefetch_maximum > 0)
- {
- node->prefetch_iterator = tbm_begin_private_iterate(tbm);
- node->prefetch_pages = 0;
- node->prefetch_target = -1;
- }
+ node->prefetch_iterator =
+ tbm_begin_iterate(node->tbm, dsa,
+ pstate ?
+ pstate->prefetch_iterator :
+ InvalidDsaPointer);
#endif /* USE_PREFETCH */
}
- else
+ else if (BitmapShouldInitializeSharedState(pstate))
{
/*
* The leader will immediately come out of the function, but
* others will be blocked until leader populates the TBM and wakes
* them up.
*/
- if (BitmapShouldInitializeSharedState(pstate))
- {
- tbm = (TIDBitmap *) MultiExecProcNode(outerPlanState(node));
- if (!tbm || !IsA(tbm, TIDBitmap))
- elog(ERROR, "unrecognized result from subplan");
-
- node->tbm = tbm;
-
- /*
- * Prepare to iterate over the TBM. This will return the
- * dsa_pointer of the iterator state which will be used by
- * multiple processes to iterate jointly.
- */
- pstate->tbmiterator = tbm_prepare_shared_iterate(tbm);
-#ifdef USE_PREFETCH
- if (node->prefetch_maximum > 0)
- {
- pstate->prefetch_iterator =
- tbm_prepare_shared_iterate(tbm);
-
- /*
- * We don't need the mutex here as we haven't yet woke up
- * others.
- */
- pstate->prefetch_pages = 0;
- pstate->prefetch_target = -1;
- }
-#endif
+ tbm = (TIDBitmap *) MultiExecProcNode(outerPlanState(node));
+ if (!tbm || !IsA(tbm, TIDBitmap))
+ elog(ERROR, "unrecognized result from subplan");
- /* We have initialized the shared state so wake up others. */
- BitmapDoneInitializingSharedState(pstate);
- }
+ node->tbm = tbm;
- /* Allocate a private iterator and attach the shared state to it */
- shared_tbmiterator =
- tbm_attach_shared_iterate(dsa, pstate->tbmiterator);
+ /*
+ * Prepare to iterate over the TBM. This will return the
+ * dsa_pointer of the iterator state which will be used by
+ * multiple processes to iterate jointly.
+ */
+ pstate->tbmiterator = tbm_prepare_shared_iterate(tbm);
#ifdef USE_PREFETCH
if (node->prefetch_maximum > 0)
{
- node->shared_prefetch_iterator =
- tbm_attach_shared_iterate(dsa, pstate->prefetch_iterator);
+ pstate->prefetch_iterator =
+ tbm_prepare_shared_iterate(tbm);
}
#endif /* USE_PREFETCH */
+
+ /* We have initialized the shared state so wake up others. */
+ BitmapDoneInitializingSharedState(pstate);
}
+ tbmiterator = tbm_begin_iterate(tbm, dsa,
+ pstate ?
+ pstate->tbmiterator :
+ InvalidDsaPointer);
+
+#ifdef USE_PREFETCH
+ if (node->prefetch_maximum > 0)
+ node->prefetch_iterator =
+ tbm_begin_iterate(tbm, dsa,
+ pstate ?
+ pstate->prefetch_iterator :
+ InvalidDsaPointer);
+#endif /* USE_PREFETCH */
+
/*
* If this is the first scan of the underlying table, create the table
* scan descriptor and begin the scan.
node->ss.ss_currentScanDesc = scan;
}
- scan->st.bitmap.rs_iterator = tbmiterator;
- scan->st.bitmap.rs_shared_iterator = shared_tbmiterator;
+ scan->st.rs_tbmiterator = tbmiterator;
node->initialized = true;
goto new_page;
* ahead of the current block.
*/
if (node->pstate == NULL &&
- node->prefetch_iterator &&
+ !tbm_exhausted(&node->prefetch_iterator) &&
node->prefetch_blockno < node->blockno)
elog(ERROR,
"prefetch and main iterators are out of sync. pfblockno: %d. blockno: %d",
if (pstate == NULL)
{
- TBMPrivateIterator *prefetch_iterator = node->prefetch_iterator;
+ TBMIterator *prefetch_iterator = &node->prefetch_iterator;
if (node->prefetch_pages > 0)
{
/* The main iterator has closed the distance by one page */
node->prefetch_pages--;
}
- else if (prefetch_iterator)
+ else if (!tbm_exhausted(prefetch_iterator))
{
- tbmpre = tbm_private_iterate(prefetch_iterator);
+ tbmpre = tbm_iterate(prefetch_iterator);
node->prefetch_blockno = tbmpre ? tbmpre->blockno :
InvalidBlockNumber;
}
*/
if (node->prefetch_maximum > 0)
{
- TBMSharedIterator *prefetch_iterator = node->shared_prefetch_iterator;
+ TBMIterator *prefetch_iterator = &node->prefetch_iterator;
SpinLockAcquire(&pstate->mutex);
if (pstate->prefetch_pages > 0)
* we don't validate the blockno here as we do in non-parallel
* case.
*/
- if (prefetch_iterator)
+ if (!tbm_exhausted(prefetch_iterator))
{
- tbmpre = tbm_shared_iterate(prefetch_iterator);
+ tbmpre = tbm_iterate(prefetch_iterator);
node->prefetch_blockno = tbmpre ? tbmpre->blockno :
InvalidBlockNumber;
}
if (pstate == NULL)
{
- TBMPrivateIterator *prefetch_iterator = node->prefetch_iterator;
+ TBMIterator *prefetch_iterator = &node->prefetch_iterator;
- if (prefetch_iterator)
+ if (!tbm_exhausted(prefetch_iterator))
{
while (node->prefetch_pages < node->prefetch_target)
{
- TBMIterateResult *tbmpre;
+ TBMIterateResult *tbmpre = tbm_iterate(prefetch_iterator);
bool skip_fetch;
- tbmpre = tbm_private_iterate(prefetch_iterator);
if (tbmpre == NULL)
{
/* No more pages to prefetch */
- tbm_end_private_iterate(prefetch_iterator);
- node->prefetch_iterator = NULL;
+ tbm_end_iterate(prefetch_iterator);
break;
}
node->prefetch_pages++;
if (pstate->prefetch_pages < pstate->prefetch_target)
{
- TBMSharedIterator *prefetch_iterator = node->shared_prefetch_iterator;
+ TBMIterator *prefetch_iterator = &node->prefetch_iterator;
- if (prefetch_iterator)
+ if (!tbm_exhausted(prefetch_iterator))
{
while (1)
{
if (!do_prefetch)
return;
- tbmpre = tbm_shared_iterate(prefetch_iterator);
+ tbmpre = tbm_iterate(prefetch_iterator);
if (tbmpre == NULL)
{
/* No more pages to prefetch */
- tbm_end_shared_iterate(prefetch_iterator);
- node->shared_prefetch_iterator = NULL;
+ tbm_end_iterate(prefetch_iterator);
break;
}
/*
* End iteration on iterators saved in scan descriptor.
*/
- if (scan->st.bitmap.rs_shared_iterator)
- {
- tbm_end_shared_iterate(scan->st.bitmap.rs_shared_iterator);
- scan->st.bitmap.rs_shared_iterator = NULL;
- }
-
- if (scan->st.bitmap.rs_iterator)
- {
- tbm_end_private_iterate(scan->st.bitmap.rs_iterator);
- scan->st.bitmap.rs_iterator = NULL;
- }
+ tbm_end_iterate(&scan->st.rs_tbmiterator);
/* rescan to release any page pin */
table_rescan(node->ss.ss_currentScanDesc, NULL);
}
+ /* If we did not already clean up the prefetch iterator, do so now. */
+ if (!tbm_exhausted(&node->prefetch_iterator))
+ tbm_end_iterate(&node->prefetch_iterator);
+
/* release bitmaps and buffers if any */
- if (node->prefetch_iterator)
- tbm_end_private_iterate(node->prefetch_iterator);
- if (node->shared_prefetch_iterator)
- tbm_end_shared_iterate(node->shared_prefetch_iterator);
if (node->tbm)
tbm_free(node->tbm);
if (node->pvmbuffer != InvalidBuffer)
ReleaseBuffer(node->pvmbuffer);
node->tbm = NULL;
- node->prefetch_iterator = NULL;
node->initialized = false;
- node->shared_prefetch_iterator = NULL;
node->pvmbuffer = InvalidBuffer;
node->recheck = true;
+ /* Only used for serial BHS */
node->blockno = InvalidBlockNumber;
node->prefetch_blockno = InvalidBlockNumber;
+ node->prefetch_pages = 0;
+ node->prefetch_target = -1;
ExecScanReScan(&node->ss);
/*
* End iteration on iterators saved in scan descriptor.
*/
- if (scanDesc->st.bitmap.rs_shared_iterator)
- {
- tbm_end_shared_iterate(scanDesc->st.bitmap.rs_shared_iterator);
- scanDesc->st.bitmap.rs_shared_iterator = NULL;
- }
-
- if (scanDesc->st.bitmap.rs_iterator)
- {
- tbm_end_private_iterate(scanDesc->st.bitmap.rs_iterator);
- scanDesc->st.bitmap.rs_iterator = NULL;
- }
+ tbm_end_iterate(&scanDesc->st.rs_tbmiterator);
/*
* close table scan
table_endscan(scanDesc);
}
+ /* If we did not already clean up the prefetch iterator, do so now. */
+ if (!tbm_exhausted(&node->prefetch_iterator))
+ tbm_end_iterate(&node->prefetch_iterator);
+
/*
* release bitmaps and buffers if any
*/
- if (node->prefetch_iterator)
- tbm_end_private_iterate(node->prefetch_iterator);
if (node->tbm)
tbm_free(node->tbm);
- if (node->shared_prefetch_iterator)
- tbm_end_shared_iterate(node->shared_prefetch_iterator);
if (node->pvmbuffer != InvalidBuffer)
ReleaseBuffer(node->pvmbuffer);
}
/* Zero the statistics counters */
memset(&scanstate->stats, 0, sizeof(BitmapHeapScanInstrumentation));
- scanstate->prefetch_iterator = NULL;
scanstate->prefetch_pages = 0;
- scanstate->prefetch_target = 0;
+ scanstate->prefetch_target = -1;
scanstate->initialized = false;
- scanstate->shared_prefetch_iterator = NULL;
scanstate->pstate = NULL;
scanstate->recheck = true;
scanstate->blockno = InvalidBlockNumber;
/* Initialize the mutex */
SpinLockInit(&pstate->mutex);
pstate->prefetch_pages = 0;
- pstate->prefetch_target = 0;
+ pstate->prefetch_target = -1;
pstate->state = BM_INITIAL;
ConditionVariableInit(&pstate->cv);
return;
pstate->state = BM_INITIAL;
+ pstate->prefetch_pages = 0;
+ pstate->prefetch_target = -1;
if (DsaPointerIsValid(pstate->tbmiterator))
tbm_free_shared_area(dsa, pstate->tbmiterator);