/* ------------------------------------------------------------------------- * * itemid.h * Standard openGauss buffer page item identifier definitions. * * * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/item/itemid.h * * ------------------------------------------------------------------------- */ #ifndef ITEMID_H #define ITEMID_H /* * An item pointer (also called line pointer) on a buffer page * * In some cases an item pointer is "in use" but does not have any associated * storage on the page. By convention, lp_len == 0 in every item pointer * that does not have storage, independently of its lp_flags state. */ typedef struct ItemIdData { unsigned lp_off : 15, /* offset to tuple (from start of page) */ lp_flags : 2, /* state of item pointer, see below */ lp_len : 15; /* byte length of tuple */ } ItemIdData; typedef ItemIdData* ItemId; /* * lp_flags has these possible states. An UNUSED line pointer is available * for immediate re-use, the other states are not. */ #define LP_UNUSED 0 /* unused (should always have lp_len=0) */ #define LP_NORMAL 1 /* used (should always have lp_len>0) */ #define LP_REDIRECT 2 /* HOT redirect (should have lp_len=0) */ #define LP_DEAD 3 /* dead, may or may not have storage */ #define LP_INDEX_FROZEN 2 /* index tuple's xmin is frozen (used for multi-version btree index only) */ /* * Item offsets and lengths are represented by these types when * they're not actually stored in an ItemIdData. */ typedef uint16 ItemOffset; typedef uint16 ItemLength; /* ---------------- * support macros * ---------------- */ /* * ItemIdGetLength */ #define ItemIdGetLength(itemId) ((itemId)->lp_len) /* * ItemIdGetOffset */ #define ItemIdGetOffset(itemId) ((itemId)->lp_off) /* * ItemIdGetFlags */ #define ItemIdGetFlags(itemId) ((itemId)->lp_flags) /* * ItemIdGetRedirect * In a REDIRECT pointer, lp_off holds the link to the next item pointer */ #define ItemIdGetRedirect(itemId) ((itemId)->lp_off) /* * ItemIdIsValid * True iff item identifier is valid. * This is a pretty weak test, probably useful only in Asserts. */ #define ItemIdIsValid(itemId) PointerIsValid(itemId) /* * ItemIdIsUsed * True iff item identifier is in use. */ #define ItemIdIsUsed(itemId) ((itemId)->lp_flags != LP_UNUSED) /* * ItemIdIsNormal * True iff item identifier is in state NORMAL. */ #define ItemIdIsNormal(itemId) ((itemId)->lp_flags == LP_NORMAL) /* * ItemIdIsRedirected * True iff item identifier is in state REDIRECT. */ #define ItemIdIsRedirected(itemId) ((itemId)->lp_flags == LP_REDIRECT) /* * IndexItemIdIsFrozen * True iff item identifier is in state INDEX_FROZEN. */ #define IndexItemIdIsFrozen(itemId) ((itemId)->lp_flags == LP_INDEX_FROZEN) /* * ItemIdIsDead * True iff item identifier is in state DEAD. */ #define ItemIdIsDead(itemId) ((itemId)->lp_flags == LP_DEAD) /* * ItemIdHasStorage * True iff item identifier has associated storage. */ #define ItemIdHasStorage(itemId) ((itemId)->lp_len != 0) /* * ItemIdSetUnused * Set the item identifier to be UNUSED, with no storage. * Beware of multiple evaluations of itemId! */ #define ItemIdSetUnused(itemId) ((itemId)->lp_flags = LP_UNUSED, (itemId)->lp_off = 0, (itemId)->lp_len = 0) /* * ItemIdSetNormal * Set the item identifier to be NORMAL, with the specified storage. * Beware of multiple evaluations of itemId! */ #define ItemIdSetNormal(itemId, off, len) \ ((itemId)->lp_flags = LP_NORMAL, (itemId)->lp_off = (off), (itemId)->lp_len = (len)) /* * ItemIdSetRedirect * Set the item identifier to be REDIRECT, with the specified link. * Beware of multiple evaluations of itemId! */ #define ItemIdSetRedirect(itemId, link) \ ((itemId)->lp_flags = LP_REDIRECT, (itemId)->lp_off = (link), (itemId)->lp_len = 0) /* * IndexItemIdSetFrozen * Set the item identifier to be INDEX_FROZEN. */ #define IndexItemIdSetFrozen(itemId) ((itemId)->lp_flags = LP_INDEX_FROZEN) /* * ItemIdIsDeleted * True iff item identifier is in state REDIRECT. */ #define ItemIdIsDeleted(itemId) \ ((itemId)->lp_flags == LP_REDIRECT) /* * ItemIdSetDead * Set the item identifier to be DEAD, with no storage. * Beware of multiple evaluations of itemId! */ #define ItemIdSetDead(itemId) ((itemId)->lp_flags = LP_DEAD, (itemId)->lp_off = 0, (itemId)->lp_len = 0) /* * ItemIdMarkDead * Set the item identifier to be DEAD, keeping its existing storage. * * Note: in indexes, this is used as if it were a hint-bit mechanism; * we trust that multiple processors can do this in parallel and get * the same result. */ #define ItemIdMarkDead(itemId) ((itemId)->lp_flags = LP_DEAD) #endif /* ITEMID_H */