diff options
| author | Andres Freund | 2018-10-15 22:24:33 +0000 |
|---|---|---|
| committer | Andres Freund | 2018-10-16 01:23:25 +0000 |
| commit | c5257345ef61922468cd9abd887c3cb6c38792cb (patch) | |
| tree | c510b809c925fba6eb0b778b53b2345ea9168e50 /src/include | |
| parent | 9d906f1119de893a4ca533c5e7b97207a3aa963b (diff) | |
Move TupleTableSlots boolean member into one flag variable.
There's several reasons for this change:
1) It reduces the total size of TupleTableSlot / reduces alignment
padding, making the commonly accessed members fit into a single
cacheline (but we currently do not force proper alignment, so
that's not yet guaranteed to be helpful)
2) Combining the booleans into a flag allows to combine read/writes
from memory.
3) With the upcoming slot abstraction changes, it allows to have core
and extended flags, in a memory efficient way.
Author: Ashutosh Bapat and Andres Freund
Discussion: https://postgr.es/m/[email protected]
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/executor/executor.h | 2 | ||||
| -rw-r--r-- | src/include/executor/tuptable.h | 66 |
2 files changed, 43 insertions, 25 deletions
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index c9ed1988c5f..edf538365be 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -340,7 +340,7 @@ ExecProject(ProjectionInfo *projInfo) * Successfully formed a result row. Mark the result slot as containing a * valid virtual tuple (inlined version of ExecStoreVirtualTuple()). */ - slot->tts_isempty = false; + slot->tts_flags &= ~TTS_FLAG_EMPTY; slot->tts_nvalid = slot->tts_tupleDescriptor->natts; return slot; diff --git a/src/include/executor/tuptable.h b/src/include/executor/tuptable.h index 3c8d57f3776..b41b400ef18 100644 --- a/src/include/executor/tuptable.h +++ b/src/include/executor/tuptable.h @@ -65,11 +65,11 @@ * ie, only as needed. This serves to avoid repeated extraction of data * from the physical tuple. * - * A TupleTableSlot can also be "empty", holding no valid data. This is - * the only valid state for a freshly-created slot that has not yet had a - * tuple descriptor assigned to it. In this state, tts_isempty must be - * true, tts_shouldFree false, tts_tuple NULL, tts_buffer InvalidBuffer, - * and tts_nvalid zero. + * A TupleTableSlot can also be "empty", indicated by flag TTS_EMPTY set in + * tts_flags, holding no valid data. This is the only valid state for a + * freshly-created slot that has not yet had a tuple descriptor assigned to it. + * In this state, TTS_SHOULDFREE should not be set in tts_flag, tts_tuple must + * be NULL, tts_buffer InvalidBuffer, and tts_nvalid zero. * * The tupleDescriptor is simply referenced, not copied, by the TupleTableSlot * code. The caller of ExecSetSlotDescriptor() is responsible for providing @@ -79,8 +79,9 @@ * mechanism to do more. However, the slot will increment the tupdesc * reference count if a reference-counted tupdesc is supplied.) * - * When tts_shouldFree is true, the physical tuple is "owned" by the slot - * and should be freed when the slot's reference to the tuple is dropped. + * When TTS_SHOULDFREE is set in tts_flags, the physical tuple is "owned" by + * the slot and should be freed when the slot's reference to the tuple is + * dropped. * * If tts_buffer is not InvalidBuffer, then the slot is holding a pin * on the indicated buffer page; drop the pin when we release the @@ -106,35 +107,52 @@ * MINIMAL_TUPLE_OFFSET bytes before tts_mintuple. This allows column * extraction to treat the case identically to regular physical tuples. * - * tts_slow/tts_off are saved state for slot_deform_tuple, and should not - * be touched by any other code. + * TTS_SLOW flag in tts_flags and tts_off are saved state for + * slot_deform_tuple, and should not be touched by any other code. *---------- */ + +/* true = slot is empty */ +#define TTS_FLAG_EMPTY (1 << 1) +#define TTS_EMPTY(slot) (((slot)->tts_flags & TTS_FLAG_EMPTY) != 0) + +/* should pfree tts_tuple? */ +#define TTS_FLAG_SHOULDFREE (1 << 2) +#define TTS_SHOULDFREE(slot) (((slot)->tts_flags & TTS_FLAG_SHOULDFREE) != 0) + +/* should pfree tts_mintuple? */ +#define TTS_FLAG_SHOULDFREEMIN (1 << 3) +#define TTS_SHOULDFREEMIN(slot) (((slot)->tts_flags & TTS_FLAG_SHOULDFREEMIN) != 0) + +/* saved state for slot_deform_tuple */ +#define TTS_FLAG_SLOW (1 << 4) +#define TTS_SLOW(slot) (((slot)->tts_flags & TTS_FLAG_SLOW) != 0) + +/* fixed tuple descriptor */ +#define TTS_FLAG_FIXED (1 << 5) +#define TTS_FIXED(slot) (((slot)->tts_flags & TTS_FLAG_FIXED) != 0) + typedef struct TupleTableSlot { NodeTag type; - bool tts_isempty; /* true = slot is empty */ - bool tts_shouldFree; /* should pfree tts_tuple? */ - bool tts_shouldFreeMin; /* should pfree tts_mintuple? */ -#define FIELDNO_TUPLETABLESLOT_SLOW 4 - bool tts_slow; /* saved state for slot_deform_tuple */ -#define FIELDNO_TUPLETABLESLOT_TUPLE 5 +#define FIELDNO_TUPLETABLESLOT_FLAGS 1 + uint16 tts_flags; /* Boolean states */ +#define FIELDNO_TUPLETABLESLOT_NVALID 2 + AttrNumber tts_nvalid; /* # of valid values in tts_values */ +#define FIELDNO_TUPLETABLESLOT_TUPLE 3 HeapTuple tts_tuple; /* physical tuple, or NULL if virtual */ -#define FIELDNO_TUPLETABLESLOT_TUPLEDESCRIPTOR 6 +#define FIELDNO_TUPLETABLESLOT_TUPLEDESCRIPTOR 4 TupleDesc tts_tupleDescriptor; /* slot's tuple descriptor */ MemoryContext tts_mcxt; /* slot itself is in this context */ Buffer tts_buffer; /* tuple's buffer, or InvalidBuffer */ -#define FIELDNO_TUPLETABLESLOT_NVALID 9 - AttrNumber tts_nvalid; /* # of valid values in tts_values */ -#define FIELDNO_TUPLETABLESLOT_VALUES 10 +#define FIELDNO_TUPLETABLESLOT_OFF 7 + uint32 tts_off; /* saved state for slot_deform_tuple */ +#define FIELDNO_TUPLETABLESLOT_VALUES 8 Datum *tts_values; /* current per-attribute values */ -#define FIELDNO_TUPLETABLESLOT_ISNULL 11 +#define FIELDNO_TUPLETABLESLOT_ISNULL 9 bool *tts_isnull; /* current per-attribute isnull flags */ MinimalTuple tts_mintuple; /* minimal tuple, or NULL if none */ HeapTupleData tts_minhdr; /* workspace for minimal-tuple-only case */ -#define FIELDNO_TUPLETABLESLOT_OFF 14 - uint32 tts_off; /* saved state for slot_deform_tuple */ - bool tts_fixedTupleDescriptor; /* descriptor can't be changed */ } TupleTableSlot; #define TTS_HAS_PHYSICAL_TUPLE(slot) \ @@ -144,7 +162,7 @@ typedef struct TupleTableSlot * TupIsNull -- is a TupleTableSlot empty? */ #define TupIsNull(slot) \ - ((slot) == NULL || (slot)->tts_isempty) + ((slot) == NULL || TTS_EMPTY(slot)) /* in executor/execTuples.c */ extern TupleTableSlot *MakeTupleTableSlot(TupleDesc desc); |
