diff options
author | Tom Lane | 2007-03-25 19:45:14 +0000 |
---|---|---|
committer | Tom Lane | 2007-03-25 19:45:14 +0000 |
commit | e85a01df678c9621c225200f1309ca8e682338ff (patch) | |
tree | 087e322930b44acbec0764f41c80aa177a25095e /src/include/utils/tqual.h | |
parent | 75c6519ff68dbb97f73b13e9976fb8075bbde7b8 (diff) |
Clean up the representation of special snapshots by including a "method
pointer" in every Snapshot struct. This allows removal of the case-by-case
tests in HeapTupleSatisfiesVisibility, which should make it a bit faster
(I didn't try any performance tests though). More importantly, we are no
longer violating portable C practices by assuming that small integers are
distinct from all pointer values, and HeapTupleSatisfiesDirty no longer
has a non-reentrant API involving side-effects on a global variable.
There were a couple of places calling HeapTupleSatisfiesXXX routines
directly rather than through the HeapTupleSatisfiesVisibility macro.
Since these places had to be changed anyway, I chose to make them go
through the macro for uniformity.
Along the way I renamed HeapTupleSatisfiesSnapshot to HeapTupleSatisfiesMVCC
to emphasize that it's only used with MVCC-type snapshots. I was sorely
tempted to rename HeapTupleSatisfiesVisibility to HeapTupleSatisfiesSnapshot,
but forebore for the moment to avoid confusion and reduce the likelihood that
this patch breaks some of the pending patches. Might want to reconsider
doing that later.
Diffstat (limited to 'src/include/utils/tqual.h')
-rw-r--r-- | src/include/utils/tqual.h | 117 |
1 files changed, 60 insertions, 57 deletions
diff --git a/src/include/utils/tqual.h b/src/include/utils/tqual.h index 0b3ef50ac34..e3596e2d507 100644 --- a/src/include/utils/tqual.h +++ b/src/include/utils/tqual.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/tqual.h,v 1.65 2007/01/05 22:19:59 momjian Exp $ + * $PostgreSQL: pgsql/src/include/utils/tqual.h,v 1.66 2007/03/25 19:45:14 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,23 +20,31 @@ /* - * "Regular" snapshots are pointers to a SnapshotData structure. - * - * We also have some "special" snapshot values that have fixed meanings - * and don't need any backing SnapshotData. These are encoded by small - * integer values, which of course is a gross violation of ANSI C, but - * it works fine on all known platforms. - * - * SnapshotDirty is an even more special case: its semantics are fixed, - * but there is a backing SnapshotData struct for it. That struct is - * actually used as *output* data from tqual.c, not input into it. - * (But hey, SnapshotDirty ought to have a dirty implementation, no? ;-)) + * We use SnapshotData structures to represent both "regular" (MVCC) + * snapshots and "special" snapshots that have non-MVCC semantics. + * The specific semantics of a snapshot are encoded by the "satisfies" + * function. */ +typedef struct SnapshotData *Snapshot; + +typedef bool (*SnapshotSatisfiesFunc) (HeapTupleHeader tuple, + Snapshot snapshot, Buffer buffer); typedef struct SnapshotData { - TransactionId xmin; /* XID < xmin are visible to me */ - TransactionId xmax; /* XID >= xmax are invisible to me */ + SnapshotSatisfiesFunc satisfies; /* tuple test function */ + /* + * The remaining fields are used only for MVCC snapshots, and are + * normally just zeroes in special snapshots. (But xmin and xmax + * are used specially by HeapTupleSatisfiesDirty.) + * + * An MVCC snapshot can never see the effects of XIDs >= xmax. + * It can see the effects of all older XIDs except those listed in + * the snapshot. xmin is stored as an optimization to avoid needing + * to search the XID arrays for most tuples. + */ + TransactionId xmin; /* all XID < xmin are visible to me */ + TransactionId xmax; /* all XID >= xmax are invisible to me */ uint32 xcnt; /* # of xact ids in xip[] */ TransactionId *xip; /* array of xact IDs in progress */ /* note: all ids in xip[] satisfy xmin <= xip[i] < xmax */ @@ -50,24 +58,30 @@ typedef struct SnapshotData CommandId curcid; /* in my xact, CID < curcid are visible */ } SnapshotData; -typedef SnapshotData *Snapshot; +#define InvalidSnapshot ((Snapshot) NULL) -/* Special snapshot values: */ -#define InvalidSnapshot ((Snapshot) 0x0) /* same as NULL */ -#define SnapshotNow ((Snapshot) 0x1) -#define SnapshotSelf ((Snapshot) 0x2) -#define SnapshotAny ((Snapshot) 0x3) -#define SnapshotToast ((Snapshot) 0x4) +/* Static variables representing various special snapshot semantics */ +extern DLLIMPORT SnapshotData SnapshotNowData; +extern DLLIMPORT SnapshotData SnapshotSelfData; +extern DLLIMPORT SnapshotData SnapshotAnyData; +extern DLLIMPORT SnapshotData SnapshotToastData; -extern DLLIMPORT Snapshot SnapshotDirty; +#define SnapshotNow (&SnapshotNowData) +#define SnapshotSelf (&SnapshotSelfData) +#define SnapshotAny (&SnapshotAnyData) +#define SnapshotToast (&SnapshotToastData) + +/* + * We don't provide a static SnapshotDirty variable because it would be + * non-reentrant. Instead, users of that snapshot type should declare a + * local variable of type SnapshotData, and initialize it with this macro. + */ +#define InitDirtySnapshot(snapshotdata) \ + ((snapshotdata).satisfies = HeapTupleSatisfiesDirty) /* This macro encodes the knowledge of which snapshots are MVCC-safe */ #define IsMVCCSnapshot(snapshot) \ - ((snapshot) != SnapshotNow && \ - (snapshot) != SnapshotSelf && \ - (snapshot) != SnapshotAny && \ - (snapshot) != SnapshotToast && \ - (snapshot) != SnapshotDirty) + ((snapshot)->satisfies == HeapTupleSatisfiesMVCC) extern DLLIMPORT Snapshot SerializableSnapshot; @@ -78,7 +92,6 @@ extern TransactionId TransactionXmin; extern TransactionId RecentXmin; extern TransactionId RecentGlobalXmin; - /* * HeapTupleSatisfiesVisibility * True iff heap tuple satisfies a time qual. @@ -86,30 +99,11 @@ extern TransactionId RecentGlobalXmin; * Notes: * Assumes heap tuple is valid. * Beware of multiple evaluations of snapshot argument. - * Hint bits in the HeapTuple's t_infomask may be updated as a side effect. + * Hint bits in the HeapTuple's t_infomask may be updated as a side effect; + * if so, the indicated buffer is marked dirty. */ #define HeapTupleSatisfiesVisibility(tuple, snapshot, buffer) \ -((snapshot) == SnapshotNow ? \ - HeapTupleSatisfiesNow((tuple)->t_data, buffer) \ -: \ - ((snapshot) == SnapshotSelf ? \ - HeapTupleSatisfiesItself((tuple)->t_data, buffer) \ - : \ - ((snapshot) == SnapshotAny ? \ - true \ - : \ - ((snapshot) == SnapshotToast ? \ - HeapTupleSatisfiesToast((tuple)->t_data, buffer) \ - : \ - ((snapshot) == SnapshotDirty ? \ - HeapTupleSatisfiesDirty((tuple)->t_data, buffer) \ - : \ - HeapTupleSatisfiesSnapshot((tuple)->t_data, snapshot, buffer) \ - ) \ - ) \ - ) \ - ) \ -) + ((*(snapshot)->satisfies) ((tuple)->t_data, snapshot, buffer)) /* Result codes for HeapTupleSatisfiesUpdate */ typedef enum @@ -127,16 +121,25 @@ typedef enum HEAPTUPLE_DEAD, /* tuple is dead and deletable */ HEAPTUPLE_LIVE, /* tuple is live (committed, no deleter) */ HEAPTUPLE_RECENTLY_DEAD, /* tuple is dead, but not deletable yet */ - HEAPTUPLE_INSERT_IN_PROGRESS, /* inserting xact is still in progress */ + HEAPTUPLE_INSERT_IN_PROGRESS, /* inserting xact is still in progress */ HEAPTUPLE_DELETE_IN_PROGRESS /* deleting xact is still in progress */ } HTSV_Result; -extern bool HeapTupleSatisfiesItself(HeapTupleHeader tuple, Buffer buffer); -extern bool HeapTupleSatisfiesNow(HeapTupleHeader tuple, Buffer buffer); -extern bool HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Buffer buffer); -extern bool HeapTupleSatisfiesToast(HeapTupleHeader tuple, Buffer buffer); -extern bool HeapTupleSatisfiesSnapshot(HeapTupleHeader tuple, - Snapshot snapshot, Buffer buffer); +/* These are the "satisfies" test routines for the various snapshot types */ +extern bool HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, + Snapshot snapshot, Buffer buffer); +extern bool HeapTupleSatisfiesNow(HeapTupleHeader tuple, + Snapshot snapshot, Buffer buffer); +extern bool HeapTupleSatisfiesSelf(HeapTupleHeader tuple, + Snapshot snapshot, Buffer buffer); +extern bool HeapTupleSatisfiesAny(HeapTupleHeader tuple, + Snapshot snapshot, Buffer buffer); +extern bool HeapTupleSatisfiesToast(HeapTupleHeader tuple, + Snapshot snapshot, Buffer buffer); +extern bool HeapTupleSatisfiesDirty(HeapTupleHeader tuple, + Snapshot snapshot, Buffer buffer); + +/* Special "satisfies" routines with different APIs */ extern HTSU_Result HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid, Buffer buffer); extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, |