summaryrefslogtreecommitdiff
path: root/src/include/storage/itemid.h
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-09-12 22:10:26 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-09-12 22:10:26 +0000
commit6889303531187f7867a5dfad5f5b5ba103f7cdd6 (patch)
treeea862682de0eb2dad6cba22fb7d0978d70fd54b2 /src/include/storage/itemid.h
parenteb0a7735ba1ede6a35b80d73f6c371a8b1220552 (diff)
downloadpostgresql-6889303531187f7867a5dfad5f5b5ba103f7cdd6.tar.gz
Redefine the lp_flags field of item pointers as having four states, rather
than two independent bits (one of which was never used in heap pages anyway, or at least hadn't been in a very long time). This gives us flexibility to add the HOT notions of redirected and dead item pointers without requiring anything so klugy as magic values of lp_off and lp_len. The state values are chosen so that for the states currently in use (pre-HOT) there is no change in the physical representation.
Diffstat (limited to 'src/include/storage/itemid.h')
-rw-r--r--src/include/storage/itemid.h142
1 files changed, 114 insertions, 28 deletions
diff --git a/src/include/storage/itemid.h b/src/include/storage/itemid.h
index 63a076550f..2a18f18226 100644
--- a/src/include/storage/itemid.h
+++ b/src/include/storage/itemid.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/storage/itemid.h,v 1.27 2007/01/05 22:19:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/storage/itemid.h,v 1.28 2007/09/12 22:10:26 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,41 +16,36 @@
/*
* 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
-{ /* line pointers */
- unsigned lp_off:15, /* offset to start of tuple */
- lp_flags:2, /* flags for tuple */
- lp_len:15; /* length of tuple */
+{
+ 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 contains these flags:
- */
-#define LP_USED 0x01 /* this line pointer is being used */
-
-#define LP_DELETE 0x02 /* item is to be deleted */
-
-#define ItemIdDeleted(itemId) \
- (((itemId)->lp_flags & LP_DELETE) != 0)
-
-/*
- * This bit may be passed to PageAddItem together with
- * LP_USED & LP_DELETE bits to specify overwrite mode
+ * lp_flags has these possible states. An UNUSED line pointer is available
+ * for immediate re-use, the other states are not.
*/
-#define OverwritePageMode 0x10
+#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 */
/*
- * Item offsets, lengths, and flags are represented by these types when
+ * Item offsets and lengths are represented by these types when
* they're not actually stored in an ItemIdData.
*/
typedef uint16 ItemOffset;
typedef uint16 ItemLength;
-typedef bits16 ItemIdFlags;
-
/* ----------------
* support macros
@@ -76,22 +71,113 @@ typedef bits16 ItemIdFlags;
((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 disk item identifier is valid.
+ * 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 disk item identifier is in use.
- *
- * Note:
- * Assumes disk item identifier is valid.
+ * 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)
+
+/*
+ * 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 \
+)
+
+/*
+ * 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) \
( \
- AssertMacro(ItemIdIsValid(itemId)), \
- (bool) (((itemId)->lp_flags & LP_USED) != 0) \
+ (itemId)->lp_flags = LP_DEAD \
)
#endif /* ITEMID_H */