#ifndef XLOGREADER_H
#define XLOGREADER_H
#ifndef FRONTEND
#include "access/transam.h"
#endif
#include "access/xlogrecord.h"
typedef struct WALOpenSegment
{
int ws_file;
XLogSegNo ws_segno;
TimeLineID ws_tli;
} WALOpenSegment;
typedef struct WALSegmentContext
{
char ws_dir[MAXPGPATH];
int ws_segsize;
} WALSegmentContext;
typedef struct XLogReaderState XLogReaderState;
typedef int (*XLogPageReadCB) (XLogReaderState *xlogreader,
XLogRecPtr targetPagePtr,
int reqLen,
XLogRecPtr targetRecPtr,
char *readBuf);
typedef void (*WALSegmentOpenCB) (XLogReaderState *xlogreader,
XLogSegNo nextSegNo,
TimeLineID *tli_p);
typedef void (*WALSegmentCloseCB) (XLogReaderState *xlogreader);
typedef struct XLogReaderRoutine
{
XLogPageReadCB page_read;
WALSegmentOpenCB segment_open;
WALSegmentCloseCB segment_close;
} XLogReaderRoutine;
#define XL_ROUTINE(...) &(XLogReaderRoutine){__VA_ARGS__}
typedef struct
{
bool in_use;
RelFileNode rnode;
ForkNumber forknum;
BlockNumber blkno;
uint8 flags;
bool has_image;
bool apply_image;
char *bkp_image;
uint16 hole_offset;
uint16 hole_length;
uint16 bimg_len;
uint8 bimg_info;
bool has_data;
char *data;
uint16 data_len;
uint16 data_bufsz;
} DecodedBkpBlock;
struct XLogReaderState
{
XLogReaderRoutine routine;
uint64 system_identifier;
void *private_data;
XLogRecPtr ReadRecPtr;
XLogRecPtr EndRecPtr;
XLogRecord *decoded_record;
char *main_data;
uint32 main_data_len;
uint32 main_data_bufsz;
RepOriginId record_origin;
DecodedBkpBlock blocks[XLR_MAX_BLOCK_ID + 1];
int max_block_id;
char *readBuf;
uint32 readLen;
WALSegmentContext segcxt;
WALOpenSegment seg;
uint32 segoff;
XLogRecPtr latestPagePtr;
TimeLineID latestPageTLI;
XLogRecPtr currRecPtr;
TimeLineID currTLI;
XLogRecPtr currTLIValidUntil;
TimeLineID nextTLI;
char *readRecordBuf;
uint32 readRecordBufSize;
char *errormsg_buf;
};
extern XLogReaderState *XLogReaderAllocate(int wal_segment_size,
const char *waldir,
XLogReaderRoutine *routine,
void *private_data);
extern XLogReaderRoutine *LocalXLogReaderRoutine(void);
extern void XLogReaderFree(XLogReaderState *state);
extern void XLogBeginRead(XLogReaderState *state, XLogRecPtr RecPtr);
#ifdef FRONTEND
extern XLogRecPtr XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr);
#endif
extern struct XLogRecord *XLogReadRecord(XLogReaderState *state,
char **errormsg);
extern bool XLogReaderValidatePageHeader(XLogReaderState *state,
XLogRecPtr recptr, char *phdr);
typedef struct WALReadError
{
int wre_errno;
int wre_off;
int wre_req;
int wre_read;
WALOpenSegment wre_seg;
} WALReadError;
extern bool WALRead(XLogReaderState *state,
char *buf, XLogRecPtr startptr, Size count,
TimeLineID tli, WALReadError *errinfo);
extern bool DecodeXLogRecord(XLogReaderState *state, XLogRecord *record,
char **errmsg);
#define XLogRecGetTotalLen(decoder) ((decoder)->decoded_record->xl_tot_len)
#define XLogRecGetPrev(decoder) ((decoder)->decoded_record->xl_prev)
#define XLogRecGetInfo(decoder) ((decoder)->decoded_record->xl_info)
#define XLogRecGetRmid(decoder) ((decoder)->decoded_record->xl_rmid)
#define XLogRecGetXid(decoder) ((decoder)->decoded_record->xl_xid)
#define XLogRecGetOrigin(decoder) ((decoder)->record_origin)
#define XLogRecGetData(decoder) ((decoder)->main_data)
#define XLogRecGetDataLen(decoder) ((decoder)->main_data_len)
#define XLogRecHasAnyBlockRefs(decoder) ((decoder)->max_block_id >= 0)
#define XLogRecHasBlockRef(decoder, block_id) \
((decoder)->blocks[block_id].in_use)
#define XLogRecHasBlockImage(decoder, block_id) \
((decoder)->blocks[block_id].has_image)
#define XLogRecBlockImageApply(decoder, block_id) \
((decoder)->blocks[block_id].apply_image)
#ifndef FRONTEND
extern FullTransactionId XLogRecGetFullXid(XLogReaderState *record);
#endif
extern bool RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page);
extern char *XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len);
extern bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id,
RelFileNode *rnode, ForkNumber *forknum,
BlockNumber *blknum);
#endif