]> granicus.if.org Git - postgresql/blob - src/include/storage/itemid.h
Centralize definition of integer limits.
[postgresql] / src / include / storage / itemid.h
1 /*-------------------------------------------------------------------------
2  *
3  * itemid.h
4  *        Standard POSTGRES buffer page item identifier definitions.
5  *
6  *
7  * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
8  * Portions Copyright (c) 1994, Regents of the University of California
9  *
10  * src/include/storage/itemid.h
11  *
12  *-------------------------------------------------------------------------
13  */
14 #ifndef ITEMID_H
15 #define ITEMID_H
16
17 /*
18  * An item pointer (also called line pointer) on a buffer page
19  *
20  * In some cases an item pointer is "in use" but does not have any associated
21  * storage on the page.  By convention, lp_len == 0 in every item pointer
22  * that does not have storage, independently of its lp_flags state.
23  */
24 typedef struct ItemIdData
25 {
26         unsigned        lp_off:15,              /* offset to tuple (from start of page) */
27                                 lp_flags:2,             /* state of item pointer, see below */
28                                 lp_len:15;              /* byte length of tuple */
29 } ItemIdData;
30
31 typedef ItemIdData *ItemId;
32
33 /*
34  * lp_flags has these possible states.  An UNUSED line pointer is available
35  * for immediate re-use, the other states are not.
36  */
37 #define LP_UNUSED               0               /* unused (should always have lp_len=0) */
38 #define LP_NORMAL               1               /* used (should always have lp_len>0) */
39 #define LP_REDIRECT             2               /* HOT redirect (should have lp_len=0) */
40 #define LP_DEAD                 3               /* dead, may or may not have storage */
41
42 /*
43  * Item offsets and lengths are represented by these types when
44  * they're not actually stored in an ItemIdData.
45  */
46 typedef uint16 ItemOffset;
47 typedef uint16 ItemLength;
48
49
50 /* ----------------
51  *              support macros
52  * ----------------
53  */
54
55 /*
56  *              ItemIdGetLength
57  */
58 #define ItemIdGetLength(itemId) \
59    ((itemId)->lp_len)
60
61 /*
62  *              ItemIdGetOffset
63  */
64 #define ItemIdGetOffset(itemId) \
65    ((itemId)->lp_off)
66
67 /*
68  *              ItemIdGetFlags
69  */
70 #define ItemIdGetFlags(itemId) \
71    ((itemId)->lp_flags)
72
73 /*
74  *              ItemIdGetRedirect
75  * In a REDIRECT pointer, lp_off holds the link to the next item pointer
76  */
77 #define ItemIdGetRedirect(itemId) \
78    ((itemId)->lp_off)
79
80 /*
81  * ItemIdIsValid
82  *              True iff item identifier is valid.
83  *              This is a pretty weak test, probably useful only in Asserts.
84  */
85 #define ItemIdIsValid(itemId)   PointerIsValid(itemId)
86
87 /*
88  * ItemIdIsUsed
89  *              True iff item identifier is in use.
90  */
91 #define ItemIdIsUsed(itemId) \
92         ((itemId)->lp_flags != LP_UNUSED)
93
94 /*
95  * ItemIdIsNormal
96  *              True iff item identifier is in state NORMAL.
97  */
98 #define ItemIdIsNormal(itemId) \
99         ((itemId)->lp_flags == LP_NORMAL)
100
101 /*
102  * ItemIdIsRedirected
103  *              True iff item identifier is in state REDIRECT.
104  */
105 #define ItemIdIsRedirected(itemId) \
106         ((itemId)->lp_flags == LP_REDIRECT)
107
108 /*
109  * ItemIdIsDead
110  *              True iff item identifier is in state DEAD.
111  */
112 #define ItemIdIsDead(itemId) \
113         ((itemId)->lp_flags == LP_DEAD)
114
115 /*
116  * ItemIdHasStorage
117  *              True iff item identifier has associated storage.
118  */
119 #define ItemIdHasStorage(itemId) \
120         ((itemId)->lp_len != 0)
121
122 /*
123  * ItemIdSetUnused
124  *              Set the item identifier to be UNUSED, with no storage.
125  *              Beware of multiple evaluations of itemId!
126  */
127 #define ItemIdSetUnused(itemId) \
128 ( \
129         (itemId)->lp_flags = LP_UNUSED, \
130         (itemId)->lp_off = 0, \
131         (itemId)->lp_len = 0 \
132 )
133
134 /*
135  * ItemIdSetNormal
136  *              Set the item identifier to be NORMAL, with the specified storage.
137  *              Beware of multiple evaluations of itemId!
138  */
139 #define ItemIdSetNormal(itemId, off, len) \
140 ( \
141         (itemId)->lp_flags = LP_NORMAL, \
142         (itemId)->lp_off = (off), \
143         (itemId)->lp_len = (len) \
144 )
145
146 /*
147  * ItemIdSetRedirect
148  *              Set the item identifier to be REDIRECT, with the specified link.
149  *              Beware of multiple evaluations of itemId!
150  */
151 #define ItemIdSetRedirect(itemId, link) \
152 ( \
153         (itemId)->lp_flags = LP_REDIRECT, \
154         (itemId)->lp_off = (link), \
155         (itemId)->lp_len = 0 \
156 )
157
158 /*
159  * ItemIdSetDead
160  *              Set the item identifier to be DEAD, with no storage.
161  *              Beware of multiple evaluations of itemId!
162  */
163 #define ItemIdSetDead(itemId) \
164 ( \
165         (itemId)->lp_flags = LP_DEAD, \
166         (itemId)->lp_off = 0, \
167         (itemId)->lp_len = 0 \
168 )
169
170 /*
171  * ItemIdMarkDead
172  *              Set the item identifier to be DEAD, keeping its existing storage.
173  *
174  * Note: in indexes, this is used as if it were a hint-bit mechanism;
175  * we trust that multiple processors can do this in parallel and get
176  * the same result.
177  */
178 #define ItemIdMarkDead(itemId) \
179 ( \
180         (itemId)->lp_flags = LP_DEAD \
181 )
182
183 #endif   /* ITEMID_H */