1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * block.h |
4 | * POSTGRES disk block definitions. |
5 | * |
6 | * |
7 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
8 | * Portions Copyright (c) 1994, Regents of the University of California |
9 | * |
10 | * src/include/storage/block.h |
11 | * |
12 | *------------------------------------------------------------------------- |
13 | */ |
14 | #ifndef BLOCK_H |
15 | #define BLOCK_H |
16 | |
17 | /* |
18 | * BlockNumber: |
19 | * |
20 | * each data file (heap or index) is divided into postgres disk blocks |
21 | * (which may be thought of as the unit of i/o -- a postgres buffer |
22 | * contains exactly one disk block). the blocks are numbered |
23 | * sequentially, 0 to 0xFFFFFFFE. |
24 | * |
25 | * InvalidBlockNumber is the same thing as P_NEW in bufmgr.h. |
26 | * |
27 | * the access methods, the buffer manager and the storage manager are |
28 | * more or less the only pieces of code that should be accessing disk |
29 | * blocks directly. |
30 | */ |
31 | typedef uint32 BlockNumber; |
32 | |
33 | #define InvalidBlockNumber ((BlockNumber) 0xFFFFFFFF) |
34 | |
35 | #define MaxBlockNumber ((BlockNumber) 0xFFFFFFFE) |
36 | |
37 | /* |
38 | * BlockId: |
39 | * |
40 | * this is a storage type for BlockNumber. in other words, this type |
41 | * is used for on-disk structures (e.g., in HeapTupleData) whereas |
42 | * BlockNumber is the type on which calculations are performed (e.g., |
43 | * in access method code). |
44 | * |
45 | * there doesn't appear to be any reason to have separate types except |
46 | * for the fact that BlockIds can be SHORTALIGN'd (and therefore any |
47 | * structures that contains them, such as ItemPointerData, can also be |
48 | * SHORTALIGN'd). this is an important consideration for reducing the |
49 | * space requirements of the line pointer (ItemIdData) array on each |
50 | * page and the header of each heap or index tuple, so it doesn't seem |
51 | * wise to change this without good reason. |
52 | */ |
53 | typedef struct BlockIdData |
54 | { |
55 | uint16 bi_hi; |
56 | uint16 bi_lo; |
57 | } BlockIdData; |
58 | |
59 | typedef BlockIdData *BlockId; /* block identifier */ |
60 | |
61 | /* ---------------- |
62 | * support macros |
63 | * ---------------- |
64 | */ |
65 | |
66 | /* |
67 | * BlockNumberIsValid |
68 | * True iff blockNumber is valid. |
69 | */ |
70 | #define BlockNumberIsValid(blockNumber) \ |
71 | ((bool) ((BlockNumber) (blockNumber) != InvalidBlockNumber)) |
72 | |
73 | /* |
74 | * BlockIdIsValid |
75 | * True iff the block identifier is valid. |
76 | */ |
77 | #define BlockIdIsValid(blockId) \ |
78 | ((bool) PointerIsValid(blockId)) |
79 | |
80 | /* |
81 | * BlockIdSet |
82 | * Sets a block identifier to the specified value. |
83 | */ |
84 | #define BlockIdSet(blockId, blockNumber) \ |
85 | ( \ |
86 | AssertMacro(PointerIsValid(blockId)), \ |
87 | (blockId)->bi_hi = (blockNumber) >> 16, \ |
88 | (blockId)->bi_lo = (blockNumber) & 0xffff \ |
89 | ) |
90 | |
91 | /* |
92 | * BlockIdCopy |
93 | * Copy a block identifier. |
94 | */ |
95 | #define BlockIdCopy(toBlockId, fromBlockId) \ |
96 | ( \ |
97 | AssertMacro(PointerIsValid(toBlockId)), \ |
98 | AssertMacro(PointerIsValid(fromBlockId)), \ |
99 | (toBlockId)->bi_hi = (fromBlockId)->bi_hi, \ |
100 | (toBlockId)->bi_lo = (fromBlockId)->bi_lo \ |
101 | ) |
102 | |
103 | /* |
104 | * BlockIdEquals |
105 | * Check for block number equality. |
106 | */ |
107 | #define BlockIdEquals(blockId1, blockId2) \ |
108 | ((blockId1)->bi_hi == (blockId2)->bi_hi && \ |
109 | (blockId1)->bi_lo == (blockId2)->bi_lo) |
110 | |
111 | /* |
112 | * BlockIdGetBlockNumber |
113 | * Retrieve the block number from a block identifier. |
114 | */ |
115 | #define BlockIdGetBlockNumber(blockId) \ |
116 | ( \ |
117 | AssertMacro(BlockIdIsValid(blockId)), \ |
118 | (BlockNumber) (((blockId)->bi_hi << 16) | ((uint16) (blockId)->bi_lo)) \ |
119 | ) |
120 | |
121 | #endif /* BLOCK_H */ |
122 | |