nbtree: Simplify _bt_first parallel scan handling.
This new structure relieves _bt_first from having separate calls to _bt_start_array_keys for the serial case and parallel case. This saves code, and seems clearer. Follow-up to work from commits 4e6e375b and b5ee4e52. Author: Peter Geoghegan <pg@bowt.ie> Reviewed-By: Matthias van de Meent <boekewurm+postgres@gmail.com> Discussion: https://postgr.es/m/CAH2-Wz=XjUZjBjHJdhTvuH5MwoJObWGoM2RG2LyFg5WUdWyk=A@mail.gmail.com
This commit is contained in:
parent
2f8b4007db
commit
428a99b589
@ -890,6 +890,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
ScanKeyData notnullkeys[INDEX_MAX_KEYS];
|
ScanKeyData notnullkeys[INDEX_MAX_KEYS];
|
||||||
int keysz = 0;
|
int keysz = 0;
|
||||||
StrategyNumber strat_total;
|
StrategyNumber strat_total;
|
||||||
|
BlockNumber blkno = InvalidBlockNumber,
|
||||||
|
lastcurrblkno;
|
||||||
|
|
||||||
Assert(!BTScanPosIsValid(so->currPos));
|
Assert(!BTScanPosIsValid(so->currPos));
|
||||||
|
|
||||||
@ -905,65 +907,43 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
*/
|
*/
|
||||||
if (!so->qual_ok)
|
if (!so->qual_ok)
|
||||||
{
|
{
|
||||||
|
Assert(!so->needPrimScan);
|
||||||
_bt_parallel_done(scan);
|
_bt_parallel_done(scan);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For parallel scans, get the starting page from shared state. If the
|
* If this is a parallel scan, we must seize the scan. _bt_readfirstpage
|
||||||
* scan has not started, proceed to find out first leaf page in the usual
|
* will likely release the parallel scan later on.
|
||||||
* way while keeping other participating processes waiting. If the scan
|
|
||||||
* has already begun, use the page number from the shared structure.
|
|
||||||
*
|
|
||||||
* When a parallel scan has another primitive index scan scheduled, a
|
|
||||||
* parallel worker will seize the scan for that purpose now. This is
|
|
||||||
* similar to the case where the top-level scan hasn't started.
|
|
||||||
*/
|
*/
|
||||||
if (scan->parallel_scan != NULL)
|
if (scan->parallel_scan != NULL &&
|
||||||
{
|
!_bt_parallel_seize(scan, &blkno, &lastcurrblkno, true))
|
||||||
BlockNumber blkno,
|
|
||||||
lastcurrblkno;
|
|
||||||
|
|
||||||
if (!_bt_parallel_seize(scan, &blkno, &lastcurrblkno, true))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Successfully seized the scan, which _bt_readfirstpage or possibly
|
* Initialize the scan's arrays (if any) for the current scan direction
|
||||||
* _bt_readnextpage will release (unless the scan ends right away, in
|
* (except when they were already set to later values as part of
|
||||||
* which case we'll call _bt_parallel_done directly).
|
* scheduling the primitive index scan that is now underway)
|
||||||
*
|
|
||||||
* Initialize arrays (when _bt_parallel_seize didn't already set up
|
|
||||||
* the next primitive index scan).
|
|
||||||
*/
|
*/
|
||||||
if (so->numArrayKeys && !so->needPrimScan)
|
if (so->numArrayKeys && !so->needPrimScan)
|
||||||
_bt_start_array_keys(scan, dir);
|
_bt_start_array_keys(scan, dir);
|
||||||
|
|
||||||
Assert(blkno != P_NONE);
|
|
||||||
if (blkno != InvalidBlockNumber)
|
if (blkno != InvalidBlockNumber)
|
||||||
{
|
{
|
||||||
Assert(!so->needPrimScan);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We anticipated starting another primitive scan, but some other
|
* We anticipated calling _bt_search, but another worker bet us to it.
|
||||||
* worker bet us to it
|
* _bt_readnextpage releases the scan for us (not _bt_readfirstpage).
|
||||||
*/
|
*/
|
||||||
|
Assert(scan->parallel_scan != NULL);
|
||||||
|
Assert(!so->needPrimScan);
|
||||||
|
Assert(blkno != P_NONE);
|
||||||
|
|
||||||
if (!_bt_readnextpage(scan, blkno, lastcurrblkno, dir, true))
|
if (!_bt_readnextpage(scan, blkno, lastcurrblkno, dir, true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_bt_returnitem(scan, so);
|
_bt_returnitem(scan, so);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (so->numArrayKeys && !so->needPrimScan)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* First _bt_first call (for current btrescan) without parallelism.
|
|
||||||
*
|
|
||||||
* Initialize arrays, and the corresponding scan keys that were just
|
|
||||||
* output by _bt_preprocess_keys.
|
|
||||||
*/
|
|
||||||
_bt_start_array_keys(scan, dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Count an indexscan for stats, now that we know that we'll call
|
* Count an indexscan for stats, now that we know that we'll call
|
||||||
@ -1090,7 +1070,12 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
break;
|
break;
|
||||||
startKeys[keysz++] = chosen;
|
startKeys[keysz++] = chosen;
|
||||||
|
|
||||||
/* Quit if we have stored a > or < key */
|
/*
|
||||||
|
* We can only consider adding more boundary keys when the one
|
||||||
|
* that we just chose to add uses either the = or >= strategy
|
||||||
|
* (during backwards scans we can only do so when the key that
|
||||||
|
* we just added to startKeys[] uses the = or <= strategy)
|
||||||
|
*/
|
||||||
strat_total = chosen->sk_strategy;
|
strat_total = chosen->sk_strategy;
|
||||||
if (strat_total == BTGreaterStrategyNumber ||
|
if (strat_total == BTGreaterStrategyNumber ||
|
||||||
strat_total == BTLessStrategyNumber)
|
strat_total == BTLessStrategyNumber)
|
||||||
@ -1190,6 +1175,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
Assert(subkey->sk_flags & SK_ROW_MEMBER);
|
Assert(subkey->sk_flags & SK_ROW_MEMBER);
|
||||||
if (subkey->sk_flags & SK_ISNULL)
|
if (subkey->sk_flags & SK_ISNULL)
|
||||||
{
|
{
|
||||||
|
Assert(!so->needPrimScan);
|
||||||
_bt_parallel_done(scan);
|
_bt_parallel_done(scan);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1408,6 +1394,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
|
|||||||
|
|
||||||
if (!BufferIsValid(so->currPos.buf))
|
if (!BufferIsValid(so->currPos.buf))
|
||||||
{
|
{
|
||||||
|
Assert(!so->needPrimScan);
|
||||||
_bt_parallel_done(scan);
|
_bt_parallel_done(scan);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2553,6 +2540,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
|
|||||||
OffsetNumber start;
|
OffsetNumber start;
|
||||||
|
|
||||||
Assert(!BTScanPosIsValid(so->currPos));
|
Assert(!BTScanPosIsValid(so->currPos));
|
||||||
|
Assert(!so->needPrimScan);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan down to the leftmost or rightmost leaf page. This is a simplified
|
* Scan down to the leftmost or rightmost leaf page. This is a simplified
|
||||||
|
Loading…
x
Reference in New Issue
Block a user