@@ -71,7 +71,7 @@ report_invalid_record(XLogReaderState *state, const char *fmt,...)
7171 */
7272XLogReaderState *
7373XLogReaderAllocate (int wal_segment_size , const char * waldir ,
74- XLogPageReadCB pagereadfunc , void * private_data )
74+ XLogReaderRoutine * routine , void * private_data )
7575{
7676 XLogReaderState * state ;
7777
@@ -81,6 +81,9 @@ XLogReaderAllocate(int wal_segment_size, const char *waldir,
8181 if (!state )
8282 return NULL ;
8383
84+ /* initialize caller-provided support functions */
85+ state -> routine = * routine ;
86+
8487 state -> max_block_id = -1 ;
8588
8689 /*
@@ -102,7 +105,6 @@ XLogReaderAllocate(int wal_segment_size, const char *waldir,
102105 WALOpenSegmentInit (& state -> seg , & state -> segcxt , wal_segment_size ,
103106 waldir );
104107
105- state -> read_page = pagereadfunc ;
106108 /* system_identifier initialized to zeroes above */
107109 state -> private_data = private_data ;
108110 /* ReadRecPtr, EndRecPtr and readLen initialized to zeroes above */
@@ -137,7 +139,7 @@ XLogReaderFree(XLogReaderState *state)
137139 int block_id ;
138140
139141 if (state -> seg .ws_file != -1 )
140- close ( state -> seg . ws_file );
142+ state -> routine . segment_close ( state );
141143
142144 for (block_id = 0 ; block_id <= XLR_MAX_BLOCK_ID ; block_id ++ )
143145 {
@@ -250,7 +252,7 @@ XLogBeginRead(XLogReaderState *state, XLogRecPtr RecPtr)
250252 * XLogBeginRead() or XLogFindNextRecord() must be called before the first call
251253 * to XLogReadRecord().
252254 *
253- * If the read_page callback fails to read the requested data, NULL is
255+ * If the page_read callback fails to read the requested data, NULL is
254256 * returned. The callback is expected to have reported the error; errormsg
255257 * is set to NULL.
256258 *
@@ -559,10 +561,10 @@ XLogReadRecord(XLogReaderState *state, char **errormsg)
559561
560562/*
561563 * Read a single xlog page including at least [pageptr, reqLen] of valid data
562- * via the read_page () callback.
564+ * via the page_read () callback.
563565 *
564566 * Returns -1 if the required page cannot be read for some reason; errormsg_buf
565- * is set in that case (unless the error occurs in the read_page callback).
567+ * is set in that case (unless the error occurs in the page_read callback).
566568 *
567569 * We fetch the page from a reader-local cache if we know we have the required
568570 * data and if there hasn't been any error since caching the data.
@@ -589,7 +591,7 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
589591 * Data is not in our buffer.
590592 *
591593 * Every time we actually read the segment, even if we looked at parts of
592- * it before, we need to do verification as the read_page callback might
594+ * it before, we need to do verification as the page_read callback might
593595 * now be rereading data from a different source.
594596 *
595597 * Whenever switching to a new WAL segment, we read the first page of the
@@ -601,9 +603,9 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
601603 {
602604 XLogRecPtr targetSegmentPtr = pageptr - targetPageOff ;
603605
604- readLen = state -> read_page (state , targetSegmentPtr , XLOG_BLCKSZ ,
605- state -> currRecPtr ,
606- state -> readBuf );
606+ readLen = state -> routine . page_read (state , targetSegmentPtr , XLOG_BLCKSZ ,
607+ state -> currRecPtr ,
608+ state -> readBuf );
607609 if (readLen < 0 )
608610 goto err ;
609611
@@ -619,9 +621,9 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
619621 * First, read the requested data length, but at least a short page header
620622 * so that we can validate it.
621623 */
622- readLen = state -> read_page (state , pageptr , Max (reqLen , SizeOfXLogShortPHD ),
623- state -> currRecPtr ,
624- state -> readBuf );
624+ readLen = state -> routine . page_read (state , pageptr , Max (reqLen , SizeOfXLogShortPHD ),
625+ state -> currRecPtr ,
626+ state -> readBuf );
625627 if (readLen < 0 )
626628 goto err ;
627629
@@ -638,9 +640,9 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
638640 /* still not enough */
639641 if (readLen < XLogPageHeaderSize (hdr ))
640642 {
641- readLen = state -> read_page (state , pageptr , XLogPageHeaderSize (hdr ),
642- state -> currRecPtr ,
643- state -> readBuf );
643+ readLen = state -> routine . page_read (state , pageptr , XLogPageHeaderSize (hdr ),
644+ state -> currRecPtr ,
645+ state -> readBuf );
644646 if (readLen < 0 )
645647 goto err ;
646648 }
@@ -1041,11 +1043,14 @@ XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr)
10411043#endif /* FRONTEND */
10421044
10431045/*
1046+ * Helper function to ease writing of XLogRoutine->page_read callbacks.
1047+ * If this function is used, caller must supply an open_segment callback in
1048+ * 'state', as that is used here.
1049+ *
10441050 * Read 'count' bytes into 'buf', starting at location 'startptr', from WAL
10451051 * fetched from timeline 'tli'.
10461052 *
1047- * 'seg/segcxt' identify the last segment used. 'openSegment' is a callback
1048- * to open the next segment, if necessary.
1053+ * 'seg/segcxt' identify the last segment used.
10491054 *
10501055 * Returns true if succeeded, false if an error occurs, in which case
10511056 * 'errinfo' receives error details.
@@ -1054,9 +1059,10 @@ XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr)
10541059 * WAL buffers when possible.
10551060 */
10561061bool
1057- WALRead (char * buf , XLogRecPtr startptr , Size count , TimeLineID tli ,
1062+ WALRead (XLogReaderState * state ,
1063+ char * buf , XLogRecPtr startptr , Size count , TimeLineID tli ,
10581064 WALOpenSegment * seg , WALSegmentContext * segcxt ,
1059- WALSegmentOpen openSegment , WALReadError * errinfo )
1065+ WALReadError * errinfo )
10601066{
10611067 char * p ;
10621068 XLogRecPtr recptr ;
@@ -1086,10 +1092,11 @@ WALRead(char *buf, XLogRecPtr startptr, Size count, TimeLineID tli,
10861092 XLogSegNo nextSegNo ;
10871093
10881094 if (seg -> ws_file >= 0 )
1089- close ( seg -> ws_file );
1095+ state -> routine . segment_close ( state );
10901096
10911097 XLByteToSeg (recptr , nextSegNo , segcxt -> ws_segsize );
1092- seg -> ws_file = openSegment (nextSegNo , segcxt , & tli );
1098+ seg -> ws_file = state -> routine .segment_open (state , nextSegNo ,
1099+ segcxt , & tli );
10931100
10941101 /* Update the current segment info. */
10951102 seg -> ws_tli = tli ;
0 commit comments