1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
/*-------------------------------------------------------------------------
*
* blkreftable.h
* Block reference tables.
*
* A block reference table is used to keep track of which blocks have
* been modified by WAL records within a certain LSN range.
*
* For each relation fork, there is a "limit block number". All existing
* blocks greater than or equal to the limit block number must be
* considered modified; for those less than the limit block number,
* we maintain a bitmap. When a relation fork is created or dropped,
* the limit block number should be set to 0. When it's truncated,
* the limit block number should be set to the length in blocks to
* which it was truncated.
*
* Portions Copyright (c) 2010-2025, PostgreSQL Global Development Group
*
* src/include/common/blkreftable.h
*
*-------------------------------------------------------------------------
*/
#ifndef BLKREFTABLE_H
#define BLKREFTABLE_H
#include "storage/block.h"
#include "storage/relfilelocator.h"
/* Magic number for serialization file format. */
#define BLOCKREFTABLE_MAGIC 0x652b137b
typedef struct BlockRefTable BlockRefTable;
typedef struct BlockRefTableEntry BlockRefTableEntry;
typedef struct BlockRefTableReader BlockRefTableReader;
typedef struct BlockRefTableWriter BlockRefTableWriter;
/*
* The return value of io_callback_fn should be the number of bytes read
* or written. If an error occurs, the functions should report it and
* not return. When used as a write callback, short writes should be retried
* or treated as errors, so that if the callback returns, the return value
* is always the request length.
*
* report_error_fn should not return.
*/
typedef int (*io_callback_fn) (void *callback_arg, void *data, int length);
typedef void (*report_error_fn) (void *callback_arg, char *msg,...) pg_attribute_printf(2, 3);
/*
* Functions for manipulating an entire in-memory block reference table.
*/
extern BlockRefTable *CreateEmptyBlockRefTable(void);
extern void BlockRefTableSetLimitBlock(BlockRefTable *brtab,
const RelFileLocator *rlocator,
ForkNumber forknum,
BlockNumber limit_block);
extern void BlockRefTableMarkBlockModified(BlockRefTable *brtab,
const RelFileLocator *rlocator,
ForkNumber forknum,
BlockNumber blknum);
extern void WriteBlockRefTable(BlockRefTable *brtab,
io_callback_fn write_callback,
void *write_callback_arg);
extern BlockRefTableEntry *BlockRefTableGetEntry(BlockRefTable *brtab,
const RelFileLocator *rlocator,
ForkNumber forknum,
BlockNumber *limit_block);
extern int BlockRefTableEntryGetBlocks(BlockRefTableEntry *entry,
BlockNumber start_blkno,
BlockNumber stop_blkno,
BlockNumber *blocks,
int nblocks);
/*
* Functions for reading a block reference table incrementally from disk.
*/
extern BlockRefTableReader *CreateBlockRefTableReader(io_callback_fn read_callback,
void *read_callback_arg,
char *error_filename,
report_error_fn error_callback,
void *error_callback_arg);
extern bool BlockRefTableReaderNextRelation(BlockRefTableReader *reader,
RelFileLocator *rlocator,
ForkNumber *forknum,
BlockNumber *limit_block);
extern unsigned BlockRefTableReaderGetBlocks(BlockRefTableReader *reader,
BlockNumber *blocks,
int nblocks);
extern void DestroyBlockRefTableReader(BlockRefTableReader *reader);
/*
* Functions for writing a block reference table incrementally to disk.
*
* Note that entries must be written in the proper order, that is, sorted by
* database, then tablespace, then relfilenumber, then fork number. Caller
* is responsible for supplying data in the correct order. If that seems hard,
* use an in-memory BlockRefTable instead.
*/
extern BlockRefTableWriter *CreateBlockRefTableWriter(io_callback_fn write_callback,
void *write_callback_arg);
extern void BlockRefTableWriteEntry(BlockRefTableWriter *writer,
BlockRefTableEntry *entry);
extern void DestroyBlockRefTableWriter(BlockRefTableWriter *writer);
extern BlockRefTableEntry *CreateBlockRefTableEntry(RelFileLocator rlocator,
ForkNumber forknum);
extern void BlockRefTableEntrySetLimitBlock(BlockRefTableEntry *entry,
BlockNumber limit_block);
extern void BlockRefTableEntryMarkBlockModified(BlockRefTableEntry *entry,
ForkNumber forknum,
BlockNumber blknum);
extern void BlockRefTableFreeEntry(BlockRefTableEntry *entry);
#endif /* BLKREFTABLE_H */
|