itemid.h 4.3 KB

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