1919#include "fmgr.h"
2020#include "miscadmin.h"
2121#include "storage/bufmgr.h"
22+ #include "storage/read_stream.h"
2223#include "storage/smgr.h"
2324#include "utils/acl.h"
2425#include "utils/builtins.h"
@@ -38,6 +39,25 @@ typedef enum
3839
3940static PGIOAlignedBlock blockbuffer ;
4041
42+ struct pg_prewarm_read_stream_private
43+ {
44+ BlockNumber blocknum ;
45+ int64 last_block ;
46+ };
47+
48+ static BlockNumber
49+ pg_prewarm_read_stream_next_block (ReadStream * stream ,
50+ void * callback_private_data ,
51+ void * per_buffer_data )
52+ {
53+ struct pg_prewarm_read_stream_private * p = callback_private_data ;
54+
55+ if (p -> blocknum <= p -> last_block )
56+ return p -> blocknum ++ ;
57+
58+ return InvalidBlockNumber ;
59+ }
60+
4161/*
4262 * pg_prewarm(regclass, mode text, fork text,
4363 * first_block int8, last_block int8)
@@ -183,18 +203,36 @@ pg_prewarm(PG_FUNCTION_ARGS)
183203 }
184204 else if (ptype == PREWARM_BUFFER )
185205 {
206+ struct pg_prewarm_read_stream_private p ;
207+ ReadStream * stream ;
208+
186209 /*
187210 * In buffer mode, we actually pull the data into shared_buffers.
188211 */
212+
213+ /* Set up the private state for our streaming buffer read callback. */
214+ p .blocknum = first_block ;
215+ p .last_block = last_block ;
216+
217+ stream = read_stream_begin_relation (READ_STREAM_FULL ,
218+ NULL ,
219+ rel ,
220+ forkNumber ,
221+ pg_prewarm_read_stream_next_block ,
222+ & p ,
223+ 0 );
224+
189225 for (block = first_block ; block <= last_block ; ++ block )
190226 {
191227 Buffer buf ;
192228
193229 CHECK_FOR_INTERRUPTS ();
194- buf = ReadBufferExtended ( rel , forkNumber , block , RBM_NORMAL , NULL );
230+ buf = read_stream_next_buffer ( stream , NULL );
195231 ReleaseBuffer (buf );
196232 ++ blocks_done ;
197233 }
234+ Assert (read_stream_next_buffer (stream , NULL ) == InvalidBuffer );
235+ read_stream_end (stream );
198236 }
199237
200238 /* Close relation, release lock. */
0 commit comments