1 /*-------------------------------------------------------------------------
2  *
3  * itemptr.h
4  *	  POSTGRES disk item pointer definitions.
5  *
6  *
7  * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * src/include/storage/itemptr.h
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef ITEMPTR_H
15 #define ITEMPTR_H
16 
17 #include "storage/block.h"
18 #include "storage/off.h"
19 
20 /*
21  * ItemPointer:
22  *
23  * This is a pointer to an item within a disk page of a known file
24  * (for example, a cross-link from an index to its parent table).
25  * blkid tells us which block, posid tells us which entry in the linp
26  * (ItemIdData) array we want.
27  *
28  * Note: because there is an item pointer in each tuple header and index
29  * tuple header on disk, it's very important not to waste space with
30  * structure padding bytes.  The struct is designed to be six bytes long
31  * (it contains three int16 fields) but a few compilers will pad it to
32  * eight bytes unless coerced.  We apply appropriate persuasion where
33  * possible, and to cope with unpersuadable compilers, we try to use
34  * "SizeOfIptrData" rather than "sizeof(ItemPointerData)" when computing
35  * on-disk sizes.
36  */
37 typedef struct ItemPointerData
38 {
39 	BlockIdData ip_blkid;
40 	OffsetNumber ip_posid;
41 }
42 /* If compiler understands packed and aligned pragmas, use those */
43 #if defined(pg_attribute_packed) && defined(pg_attribute_aligned)
44 pg_attribute_packed()
45 pg_attribute_aligned(2)
46 #endif
47 ItemPointerData;
48 
49 #define SizeOfIptrData	\
50 	(offsetof(ItemPointerData, ip_posid) + sizeof(OffsetNumber))
51 
52 typedef ItemPointerData *ItemPointer;
53 
54 /* ----------------
55  *		support macros
56  * ----------------
57  */
58 
59 /*
60  * ItemPointerIsValid
61  *		True iff the disk item pointer is not NULL.
62  */
63 #define ItemPointerIsValid(pointer) \
64 	((bool) (PointerIsValid(pointer) && ((pointer)->ip_posid != 0)))
65 
66 /*
67  * ItemPointerGetBlockNumber
68  *		Returns the block number of a disk item pointer.
69  */
70 #define ItemPointerGetBlockNumber(pointer) \
71 ( \
72 	AssertMacro(ItemPointerIsValid(pointer)), \
73 	BlockIdGetBlockNumber(&(pointer)->ip_blkid) \
74 )
75 
76 /*
77  * ItemPointerGetOffsetNumber
78  *		Returns the offset number of a disk item pointer.
79  */
80 #define ItemPointerGetOffsetNumber(pointer) \
81 ( \
82 	AssertMacro(ItemPointerIsValid(pointer)), \
83 	(pointer)->ip_posid \
84 )
85 
86 /*
87  * ItemPointerSet
88  *		Sets a disk item pointer to the specified block and offset.
89  */
90 #define ItemPointerSet(pointer, blockNumber, offNum) \
91 ( \
92 	AssertMacro(PointerIsValid(pointer)), \
93 	BlockIdSet(&((pointer)->ip_blkid), blockNumber), \
94 	(pointer)->ip_posid = offNum \
95 )
96 
97 /*
98  * ItemPointerSetBlockNumber
99  *		Sets a disk item pointer to the specified block.
100  */
101 #define ItemPointerSetBlockNumber(pointer, blockNumber) \
102 ( \
103 	AssertMacro(PointerIsValid(pointer)), \
104 	BlockIdSet(&((pointer)->ip_blkid), blockNumber) \
105 )
106 
107 /*
108  * ItemPointerSetOffsetNumber
109  *		Sets a disk item pointer to the specified offset.
110  */
111 #define ItemPointerSetOffsetNumber(pointer, offsetNumber) \
112 ( \
113 	AssertMacro(PointerIsValid(pointer)), \
114 	(pointer)->ip_posid = (offsetNumber) \
115 )
116 
117 /*
118  * ItemPointerCopy
119  *		Copies the contents of one disk item pointer to another.
120  *
121  * Should there ever be padding in an ItemPointer this would need to be handled
122  * differently as it's used as hash key.
123  */
124 #define ItemPointerCopy(fromPointer, toPointer) \
125 ( \
126 	AssertMacro(PointerIsValid(toPointer)), \
127 	AssertMacro(PointerIsValid(fromPointer)), \
128 	*(toPointer) = *(fromPointer) \
129 )
130 
131 /*
132  * ItemPointerSetInvalid
133  *		Sets a disk item pointer to be invalid.
134  */
135 #define ItemPointerSetInvalid(pointer) \
136 ( \
137 	AssertMacro(PointerIsValid(pointer)), \
138 	BlockIdSet(&((pointer)->ip_blkid), InvalidBlockNumber), \
139 	(pointer)->ip_posid = InvalidOffsetNumber \
140 )
141 
142 /* ----------------
143  *		externs
144  * ----------------
145  */
146 
147 extern bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2);
148 extern int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2);
149 
150 #endif   /* ITEMPTR_H */
151