00001 /*------------------------------------------------------------------------- 00002 * 00003 * itemid.h 00004 * Standard POSTGRES buffer page item identifier 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/itemid.h 00011 * 00012 *------------------------------------------------------------------------- 00013 */ 00014 #ifndef ITEMID_H 00015 #define ITEMID_H 00016 00017 /* 00018 * An item pointer (also called line pointer) on a buffer page 00019 * 00020 * In some cases an item pointer is "in use" but does not have any associated 00021 * storage on the page. By convention, lp_len == 0 in every item pointer 00022 * that does not have storage, independently of its lp_flags state. 00023 */ 00024 typedef struct ItemIdData 00025 { 00026 unsigned lp_off:15, /* offset to tuple (from start of page) */ 00027 lp_flags:2, /* state of item pointer, see below */ 00028 lp_len:15; /* byte length of tuple */ 00029 } ItemIdData; 00030 00031 typedef ItemIdData *ItemId; 00032 00033 /* 00034 * lp_flags has these possible states. An UNUSED line pointer is available 00035 * for immediate re-use, the other states are not. 00036 */ 00037 #define LP_UNUSED 0 /* unused (should always have lp_len=0) */ 00038 #define LP_NORMAL 1 /* used (should always have lp_len>0) */ 00039 #define LP_REDIRECT 2 /* HOT redirect (should have lp_len=0) */ 00040 #define LP_DEAD 3 /* dead, may or may not have storage */ 00041 00042 /* 00043 * Item offsets and lengths are represented by these types when 00044 * they're not actually stored in an ItemIdData. 00045 */ 00046 typedef uint16 ItemOffset; 00047 typedef uint16 ItemLength; 00048 00049 00050 /* ---------------- 00051 * support macros 00052 * ---------------- 00053 */ 00054 00055 /* 00056 * ItemIdGetLength 00057 */ 00058 #define ItemIdGetLength(itemId) \ 00059 ((itemId)->lp_len) 00060 00061 /* 00062 * ItemIdGetOffset 00063 */ 00064 #define ItemIdGetOffset(itemId) \ 00065 ((itemId)->lp_off) 00066 00067 /* 00068 * ItemIdGetFlags 00069 */ 00070 #define ItemIdGetFlags(itemId) \ 00071 ((itemId)->lp_flags) 00072 00073 /* 00074 * ItemIdGetRedirect 00075 * In a REDIRECT pointer, lp_off holds the link to the next item pointer 00076 */ 00077 #define ItemIdGetRedirect(itemId) \ 00078 ((itemId)->lp_off) 00079 00080 /* 00081 * ItemIdIsValid 00082 * True iff item identifier is valid. 00083 * This is a pretty weak test, probably useful only in Asserts. 00084 */ 00085 #define ItemIdIsValid(itemId) PointerIsValid(itemId) 00086 00087 /* 00088 * ItemIdIsUsed 00089 * True iff item identifier is in use. 00090 */ 00091 #define ItemIdIsUsed(itemId) \ 00092 ((itemId)->lp_flags != LP_UNUSED) 00093 00094 /* 00095 * ItemIdIsNormal 00096 * True iff item identifier is in state NORMAL. 00097 */ 00098 #define ItemIdIsNormal(itemId) \ 00099 ((itemId)->lp_flags == LP_NORMAL) 00100 00101 /* 00102 * ItemIdIsRedirected 00103 * True iff item identifier is in state REDIRECT. 00104 */ 00105 #define ItemIdIsRedirected(itemId) \ 00106 ((itemId)->lp_flags == LP_REDIRECT) 00107 00108 /* 00109 * ItemIdIsDead 00110 * True iff item identifier is in state DEAD. 00111 */ 00112 #define ItemIdIsDead(itemId) \ 00113 ((itemId)->lp_flags == LP_DEAD) 00114 00115 /* 00116 * ItemIdHasStorage 00117 * True iff item identifier has associated storage. 00118 */ 00119 #define ItemIdHasStorage(itemId) \ 00120 ((itemId)->lp_len != 0) 00121 00122 /* 00123 * ItemIdSetUnused 00124 * Set the item identifier to be UNUSED, with no storage. 00125 * Beware of multiple evaluations of itemId! 00126 */ 00127 #define ItemIdSetUnused(itemId) \ 00128 ( \ 00129 (itemId)->lp_flags = LP_UNUSED, \ 00130 (itemId)->lp_off = 0, \ 00131 (itemId)->lp_len = 0 \ 00132 ) 00133 00134 /* 00135 * ItemIdSetNormal 00136 * Set the item identifier to be NORMAL, with the specified storage. 00137 * Beware of multiple evaluations of itemId! 00138 */ 00139 #define ItemIdSetNormal(itemId, off, len) \ 00140 ( \ 00141 (itemId)->lp_flags = LP_NORMAL, \ 00142 (itemId)->lp_off = (off), \ 00143 (itemId)->lp_len = (len) \ 00144 ) 00145 00146 /* 00147 * ItemIdSetRedirect 00148 * Set the item identifier to be REDIRECT, with the specified link. 00149 * Beware of multiple evaluations of itemId! 00150 */ 00151 #define ItemIdSetRedirect(itemId, link) \ 00152 ( \ 00153 (itemId)->lp_flags = LP_REDIRECT, \ 00154 (itemId)->lp_off = (link), \ 00155 (itemId)->lp_len = 0 \ 00156 ) 00157 00158 /* 00159 * ItemIdSetDead 00160 * Set the item identifier to be DEAD, with no storage. 00161 * Beware of multiple evaluations of itemId! 00162 */ 00163 #define ItemIdSetDead(itemId) \ 00164 ( \ 00165 (itemId)->lp_flags = LP_DEAD, \ 00166 (itemId)->lp_off = 0, \ 00167 (itemId)->lp_len = 0 \ 00168 ) 00169 00170 /* 00171 * ItemIdMarkDead 00172 * Set the item identifier to be DEAD, keeping its existing storage. 00173 * 00174 * Note: in indexes, this is used as if it were a hint-bit mechanism; 00175 * we trust that multiple processors can do this in parallel and get 00176 * the same result. 00177 */ 00178 #define ItemIdMarkDead(itemId) \ 00179 ( \ 00180 (itemId)->lp_flags = LP_DEAD \ 00181 ) 00182 00183 #endif /* ITEMID_H */