00001 /*------------------------------------------------------------------------- 00002 * 00003 * block.h 00004 * POSTGRES disk block definitions. 00005 * 00006 * 00007 * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group 00008 * Portions Copyright (c) 1994, Regents of the University of California 00009 * 00010 * src/include/storage/block.h 00011 * 00012 *------------------------------------------------------------------------- 00013 */ 00014 #ifndef BLOCK_H 00015 #define BLOCK_H 00016 00017 /* 00018 * BlockNumber: 00019 * 00020 * each data file (heap or index) is divided into postgres disk blocks 00021 * (which may be thought of as the unit of i/o -- a postgres buffer 00022 * contains exactly one disk block). the blocks are numbered 00023 * sequentially, 0 to 0xFFFFFFFE. 00024 * 00025 * InvalidBlockNumber is the same thing as P_NEW in buf.h. 00026 * 00027 * the access methods, the buffer manager and the storage manager are 00028 * more or less the only pieces of code that should be accessing disk 00029 * blocks directly. 00030 */ 00031 typedef uint32 BlockNumber; 00032 00033 #define InvalidBlockNumber ((BlockNumber) 0xFFFFFFFF) 00034 00035 #define MaxBlockNumber ((BlockNumber) 0xFFFFFFFE) 00036 00037 /* 00038 * BlockId: 00039 * 00040 * this is a storage type for BlockNumber. in other words, this type 00041 * is used for on-disk structures (e.g., in HeapTupleData) whereas 00042 * BlockNumber is the type on which calculations are performed (e.g., 00043 * in access method code). 00044 * 00045 * there doesn't appear to be any reason to have separate types except 00046 * for the fact that BlockIds can be SHORTALIGN'd (and therefore any 00047 * structures that contains them, such as ItemPointerData, can also be 00048 * SHORTALIGN'd). this is an important consideration for reducing the 00049 * space requirements of the line pointer (ItemIdData) array on each 00050 * page and the header of each heap or index tuple, so it doesn't seem 00051 * wise to change this without good reason. 00052 */ 00053 typedef struct BlockIdData 00054 { 00055 uint16 bi_hi; 00056 uint16 bi_lo; 00057 } BlockIdData; 00058 00059 typedef BlockIdData *BlockId; /* block identifier */ 00060 00061 /* ---------------- 00062 * support macros 00063 * ---------------- 00064 */ 00065 00066 /* 00067 * BlockNumberIsValid 00068 * True iff blockNumber is valid. 00069 */ 00070 #define BlockNumberIsValid(blockNumber) \ 00071 ((bool) ((BlockNumber) (blockNumber) != InvalidBlockNumber)) 00072 00073 /* 00074 * BlockIdIsValid 00075 * True iff the block identifier is valid. 00076 */ 00077 #define BlockIdIsValid(blockId) \ 00078 ((bool) PointerIsValid(blockId)) 00079 00080 /* 00081 * BlockIdSet 00082 * Sets a block identifier to the specified value. 00083 */ 00084 #define BlockIdSet(blockId, blockNumber) \ 00085 ( \ 00086 AssertMacro(PointerIsValid(blockId)), \ 00087 (blockId)->bi_hi = (blockNumber) >> 16, \ 00088 (blockId)->bi_lo = (blockNumber) & 0xffff \ 00089 ) 00090 00091 /* 00092 * BlockIdCopy 00093 * Copy a block identifier. 00094 */ 00095 #define BlockIdCopy(toBlockId, fromBlockId) \ 00096 ( \ 00097 AssertMacro(PointerIsValid(toBlockId)), \ 00098 AssertMacro(PointerIsValid(fromBlockId)), \ 00099 (toBlockId)->bi_hi = (fromBlockId)->bi_hi, \ 00100 (toBlockId)->bi_lo = (fromBlockId)->bi_lo \ 00101 ) 00102 00103 /* 00104 * BlockIdEquals 00105 * Check for block number equality. 00106 */ 00107 #define BlockIdEquals(blockId1, blockId2) \ 00108 ((blockId1)->bi_hi == (blockId2)->bi_hi && \ 00109 (blockId1)->bi_lo == (blockId2)->bi_lo) 00110 00111 /* 00112 * BlockIdGetBlockNumber 00113 * Retrieve the block number from a block identifier. 00114 */ 00115 #define BlockIdGetBlockNumber(blockId) \ 00116 ( \ 00117 AssertMacro(BlockIdIsValid(blockId)), \ 00118 (BlockNumber) (((blockId)->bi_hi << 16) | ((uint16) (blockId)->bi_lo)) \ 00119 ) 00120 00121 #endif /* BLOCK_H */