@@ -117,13 +117,10 @@ struct ReadStream
117
117
bool advice_enabled ;
118
118
119
119
/*
120
- * Small buffer of block numbers, useful for 'ungetting' to resolve flow
121
- * control problems when I/Os are split. Also useful for batch-loading
122
- * block numbers in the fast path.
120
+ * One-block buffer to support 'ungetting' a block number, to resolve flow
121
+ * control problems when I/Os are split.
123
122
*/
124
- BlockNumber blocknums [16 ];
125
- int16 blocknums_count ;
126
- int16 blocknums_next ;
123
+ BlockNumber buffered_blocknum ;
127
124
128
125
/*
129
126
* The callback that will tell us which block numbers to read, and an
@@ -167,23 +164,23 @@ get_per_buffer_data(ReadStream *stream, int16 buffer_index)
167
164
}
168
165
169
166
/*
170
- * Ask the callback which block it would like us to read next, with a small
171
- * buffer in front to allow read_stream_unget_block() to work and to allow the
172
- * fast path to skip this function and work directly from the array.
167
+ * Ask the callback which block it would like us to read next, with a one block
168
+ * buffer in front to allow read_stream_unget_block() to work.
173
169
*/
174
170
static inline BlockNumber
175
171
read_stream_get_block (ReadStream * stream , void * per_buffer_data )
176
172
{
177
- if (stream -> blocknums_next < stream -> blocknums_count )
178
- return stream -> blocknums [stream -> blocknums_next ++ ];
173
+ BlockNumber blocknum ;
179
174
180
- /*
181
- * We only bother to fetch one at a time here (but see the fast path which
182
- * uses more).
183
- */
184
- return stream -> callback (stream ,
185
- stream -> callback_private_data ,
186
- per_buffer_data );
175
+ blocknum = stream -> buffered_blocknum ;
176
+ if (blocknum != InvalidBlockNumber )
177
+ stream -> buffered_blocknum = InvalidBlockNumber ;
178
+ else
179
+ blocknum = stream -> callback (stream ,
180
+ stream -> callback_private_data ,
181
+ per_buffer_data );
182
+
183
+ return blocknum ;
187
184
}
188
185
189
186
/*
@@ -193,42 +190,12 @@ read_stream_get_block(ReadStream *stream, void *per_buffer_data)
193
190
static inline void
194
191
read_stream_unget_block (ReadStream * stream , BlockNumber blocknum )
195
192
{
196
- if (stream -> blocknums_next == stream -> blocknums_count )
197
- {
198
- /* Never initialized or entirely consumed. Re-initialize. */
199
- stream -> blocknums [0 ] = blocknum ;
200
- stream -> blocknums_count = 1 ;
201
- stream -> blocknums_next = 0 ;
202
- }
203
- else
204
- {
205
- /* Must be the last value return from blocknums array. */
206
- Assert (stream -> blocknums_next > 0 );
207
- stream -> blocknums_next -- ;
208
- Assert (stream -> blocknums [stream -> blocknums_next ] == blocknum );
209
- }
193
+ /* We shouldn't ever unget more than one block. */
194
+ Assert (stream -> buffered_blocknum == InvalidBlockNumber );
195
+ Assert (blocknum != InvalidBlockNumber );
196
+ stream -> buffered_blocknum = blocknum ;
210
197
}
211
198
212
- #ifndef READ_STREAM_DISABLE_FAST_PATH
213
- static void
214
- read_stream_fill_blocknums (ReadStream * stream )
215
- {
216
- BlockNumber blocknum ;
217
- int i = 0 ;
218
-
219
- do
220
- {
221
- blocknum = stream -> callback (stream ,
222
- stream -> callback_private_data ,
223
- NULL );
224
- stream -> blocknums [i ++ ] = blocknum ;
225
- } while (i < lengthof (stream -> blocknums ) &&
226
- blocknum != InvalidBlockNumber );
227
- stream -> blocknums_count = i ;
228
- stream -> blocknums_next = 0 ;
229
- }
230
- #endif
231
-
232
199
static void
233
200
read_stream_start_pending_read (ReadStream * stream , bool suppress_advice )
234
201
{
@@ -531,6 +498,7 @@ read_stream_begin_relation(int flags,
531
498
stream -> queue_size = queue_size ;
532
499
stream -> callback = callback ;
533
500
stream -> callback_private_data = callback_private_data ;
501
+ stream -> buffered_blocknum = InvalidBlockNumber ;
534
502
535
503
/*
536
504
* Skip the initial ramp-up phase if the caller says we're going to be
@@ -601,9 +569,7 @@ read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
601
569
Assert (buffer != InvalidBuffer );
602
570
603
571
/* Choose the next block to pin. */
604
- if (unlikely (stream -> blocknums_next == stream -> blocknums_count ))
605
- read_stream_fill_blocknums (stream );
606
- next_blocknum = stream -> blocknums [stream -> blocknums_next ++ ];
572
+ next_blocknum = read_stream_get_block (stream , NULL );
607
573
608
574
if (likely (next_blocknum != InvalidBlockNumber ))
609
575
{
@@ -779,9 +745,8 @@ read_stream_reset(ReadStream *stream)
779
745
/* Stop looking ahead. */
780
746
stream -> distance = 0 ;
781
747
782
- /* Forget buffered block numbers and fast path state. */
783
- stream -> blocknums_next = 0 ;
784
- stream -> blocknums_count = 0 ;
748
+ /* Forget buffered block number and fast path state. */
749
+ stream -> buffered_blocknum = InvalidBlockNumber ;
785
750
stream -> fast_path = false;
786
751
787
752
/* Unpin anything that wasn't consumed. */
0 commit comments