diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-09-12 22:10:26 +0000 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-09-12 22:10:26 +0000 |
| commit | 6889303531187f7867a5dfad5f5b5ba103f7cdd6 (patch) | |
| tree | ea862682de0eb2dad6cba22fb7d0978d70fd54b2 /src/include/storage/itemid.h | |
| parent | eb0a7735ba1ede6a35b80d73f6c371a8b1220552 (diff) | |
| download | postgresql-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.h | 142 |
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 */ |
