1 /*------------------------------------------------------------------------- 2 * 3 * block.h 4 * POSTGRES disk block definitions. 5 * 6 * 7 * Portions Copyright (c) 1996-2020, 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