@@ -149,19 +149,15 @@ BitmapHeapNext(BitmapHeapScanState *node)
149
149
* multiple processes to iterate jointly.
150
150
*/
151
151
pstate -> tbmiterator = tbm_prepare_shared_iterate (tbm );
152
- #ifdef USE_PREFETCH
153
- node -> n_prefetch_requests = 0 ;
154
- node -> prefetch_request_pos = 0 ;
155
- if (node -> prefetch_maximum > 0 )
156
- {
157
- node -> prefetch_pages = 0 ;
158
- node -> prefetch_target = -1 ;
159
- }
160
- #endif
161
152
162
153
/* We have initialized the shared state so wake up others. */
163
154
BitmapDoneInitializingSharedState (pstate );
164
155
}
156
+ #ifdef USE_PREFETCH
157
+ node -> prefetch_head = 0 ;
158
+ node -> prefetch_pages = 0 ;
159
+ node -> prefetch_target = -1 ;
160
+ #endif
165
161
166
162
/* Allocate a private iterator and attach the shared state to it */
167
163
node -> shared_tbmiterator = shared_tbmiterator =
@@ -184,20 +180,25 @@ BitmapHeapNext(BitmapHeapScanState *node)
184
180
if (tbmres == NULL )
185
181
{
186
182
if (!pstate )
187
- node -> tbmres = tbmres = tbm_iterate (tbmiterator );
183
+ tbmres = tbm_iterate (tbmiterator );
188
184
else
189
185
{
190
- if (node -> n_prefetch_requests != 0 )
186
+ if (node -> prefetch_pages != 0 )
191
187
{
192
- node -> tbmres = tbmres = (TBMIterateResult * )& node -> prefetch_requests [node -> prefetch_request_pos ];
193
- node -> n_prefetch_requests -= 1 ;
194
- node -> prefetch_request_pos = (node -> prefetch_request_pos + 1 ) % MAX_IO_CONCURRENCY ;
195
- if (node -> prefetch_pages != 0 )
196
- node -> prefetch_pages -= 1 ;
188
+ tbmres = (TBMIterateResult * )& node -> prefetch_requests [node -> prefetch_head ];
189
+ node -> prefetch_pages -= 1 ;
190
+ node -> prefetch_head = (node -> prefetch_head + 1 ) % MAX_IO_CONCURRENCY ;
197
191
}
198
192
else
199
- node -> tbmres = tbmres = tbm_shared_iterate (shared_tbmiterator );
193
+ tbmres = tbm_shared_iterate (shared_tbmiterator );
194
+ if (tbmres )
195
+ {
196
+ /* Need to copy result because iterator can be used for prefetch and vocant position in prefetch ring buffer can also be reused */
197
+ memcpy (& node -> tbmres_copy , tbmres , offsetof(TBMIterateResult , offsets ) + sizeof (OffsetNumber )* Max (tbmres -> ntuples , 0 ));
198
+ tbmres = (TBMIterateResult * )& node -> tbmres_copy ;
199
+ }
200
200
}
201
+ node -> tbmres = tbmres ;
201
202
if (tbmres == NULL )
202
203
{
203
204
/* no more entries in the bitmap */
@@ -236,7 +237,6 @@ BitmapHeapNext(BitmapHeapScanState *node)
236
237
/* AM doesn't think this block is valid, skip */
237
238
continue ;
238
239
}
239
-
240
240
if (tbmres -> ntuples >= 0 )
241
241
node -> exact_pages ++ ;
242
242
else
@@ -455,8 +455,7 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
455
455
456
456
if (node -> prefetch_pages < node -> prefetch_target )
457
457
{
458
- Assert (node -> n_prefetch_requests < MAX_IO_CONCURRENCY );
459
- node -> prefetch_pages ++ ;
458
+ Assert (node -> prefetch_pages < MAX_IO_CONCURRENCY );
460
459
do_prefetch = true;
461
460
}
462
461
@@ -466,8 +465,10 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
466
465
tbmpre = tbm_shared_iterate (node -> shared_tbmiterator );
467
466
if (tbmpre != NULL )
468
467
{
469
- memcpy (& node -> prefetch_requests [(node -> prefetch_request_pos + node -> n_prefetch_requests ) % MAX_IO_CONCURRENCY ], tbmpre , sizeof (TBMIteratePrefetchResult ));
470
- node -> n_prefetch_requests += 1 ;
468
+ memcpy (& node -> prefetch_requests [(node -> prefetch_head + node -> prefetch_pages ) % MAX_IO_CONCURRENCY ],
469
+ tbmpre ,
470
+ offsetof(TBMIterateResult , offsets ) + sizeof (OffsetNumber )* Max (tbmpre -> ntuples , 0 ));
471
+ node -> prefetch_pages += 1 ;
471
472
}
472
473
else
473
474
{
@@ -477,7 +478,7 @@ BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan)
477
478
478
479
/* As above, skip prefetch if we expect not to need page */
479
480
skip_fetch = (node -> can_skip_fetch &&
480
- ( node -> tbmres ? ! node -> tbmres -> recheck : false) &&
481
+ ! tbmpre -> recheck &&
481
482
VM_ALL_VISIBLE (node -> ss .ss_currentRelation ,
482
483
tbmpre -> blockno ,
483
484
& node -> pvmbuffer ));
@@ -715,8 +716,7 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
715
716
* Maximum number of prefetches for the tablespace if configured,
716
717
* otherwise the current value of the effective_io_concurrency GUC.
717
718
*/
718
- scanstate -> prefetch_maximum =
719
- get_tablespace_io_concurrency (currentRelation -> rd_rel -> reltablespace );
719
+ scanstate -> prefetch_maximum = get_tablespace_io_concurrency (currentRelation -> rd_rel -> reltablespace );
720
720
721
721
scanstate -> ss .ss_currentRelation = currentRelation ;
722
722
0 commit comments