mirror of
https://github.com/postgres/postgres.git
synced 2026-03-22 10:30:21 -04:00
Reduce size of CompactAttribute struct to 8 bytes
Previously, this was 16 bytes. With the use of some bitflags and by reducing the attcacheoff field size to a 16-bit type, we can halve the size of the struct. It's unlikely that caching the offsets for offsets larger than what will fit in a 16-bit int will help much as the tuple is very likely to have some non-fixed-width types anyway, the offsets of which we cannot cache. Shrinking this down to 8 bytes helps by accessing fewer cachelines when performing tuple deformation. The fields used there are all fully fledged fields, which don't require any bitmasking to extract the value of. It also helps to more efficiently calculate the address of a compact_attrs[] element in TupleDesc as the x86 LEA instruction can work with 8 byte offsets, which allows the element address to be calculated from the TupleDesc's address in a single instruction using LEA's concurrent shift and add. Author: David Rowley <dgrowleyml@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de> Discussion: https://postgr.es/m/CAApHDvodSVBj3ypOYbYUCJX%2BNWL%3DVZs63RNBQ_FxB_F%2B6QXF-A%40mail.gmail.com
This commit is contained in:
parent
d927b4bd97
commit
d8a859d22b
3 changed files with 31 additions and 14 deletions
|
|
@ -530,7 +530,17 @@ TupleDescFinalize(TupleDesc tupdesc)
|
|||
|
||||
off = att_nominal_alignby(off, cattr->attalignby);
|
||||
|
||||
cattr->attcacheoff = off;
|
||||
/*
|
||||
* attcacheoff is an int16, so don't try to cache any offsets larger
|
||||
* than will fit in that type. Any attributes which are offset more
|
||||
* than 2^15 are likely due to variable-length attributes. Since we
|
||||
* don't cache offsets for or beyond variable-length attributes, using
|
||||
* an int16 rather than an int32 here is unlikely to cost us anything.
|
||||
*/
|
||||
if (off > PG_INT16_MAX)
|
||||
break;
|
||||
|
||||
cattr->attcacheoff = (int16) off;
|
||||
|
||||
off += cattr->attlen;
|
||||
firstNonCachedOffsetAttr = i + 1;
|
||||
|
|
|
|||
|
|
@ -1013,6 +1013,7 @@ static pg_attribute_always_inline void
|
|||
slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp,
|
||||
int reqnatts)
|
||||
{
|
||||
CompactAttribute *cattrs;
|
||||
CompactAttribute *cattr;
|
||||
TupleDesc tupleDesc = slot->tts_tupleDescriptor;
|
||||
HeapTupleHeader tup = tuple->t_data;
|
||||
|
|
@ -1095,6 +1096,13 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp,
|
|||
values = slot->tts_values;
|
||||
slot->tts_nvalid = reqnatts;
|
||||
|
||||
/*
|
||||
* We store the tupleDesc's CompactAttribute array in 'cattrs' as gcc
|
||||
* seems to be unwilling to optimize accessing the CompactAttribute
|
||||
* element efficiently when accessing it via TupleDescCompactAttr().
|
||||
*/
|
||||
cattrs = tupleDesc->compact_attrs;
|
||||
|
||||
/* Ensure we calculated tp correctly */
|
||||
Assert(tp == (char *) tup + tup->t_hoff);
|
||||
|
||||
|
|
@ -1105,7 +1113,7 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp,
|
|||
do
|
||||
{
|
||||
isnull[attnum] = false;
|
||||
cattr = TupleDescCompactAttr(tupleDesc, attnum);
|
||||
cattr = &cattrs[attnum];
|
||||
attlen = cattr->attlen;
|
||||
|
||||
/* We don't expect any non-byval types */
|
||||
|
|
@ -1150,9 +1158,8 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp,
|
|||
do
|
||||
{
|
||||
isnull[attnum] = false;
|
||||
cattr = TupleDescCompactAttr(tupleDesc, attnum);
|
||||
cattr = &cattrs[attnum];
|
||||
attlen = cattr->attlen;
|
||||
|
||||
off = cattr->attcacheoff;
|
||||
values[attnum] = fetch_att_noerr(tp + off,
|
||||
cattr->attbyval,
|
||||
|
|
@ -1179,7 +1186,7 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp,
|
|||
int attlen;
|
||||
|
||||
isnull[attnum] = false;
|
||||
cattr = TupleDescCompactAttr(tupleDesc, attnum);
|
||||
cattr = &cattrs[attnum];
|
||||
attlen = cattr->attlen;
|
||||
|
||||
/*
|
||||
|
|
@ -1212,7 +1219,7 @@ slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp,
|
|||
continue;
|
||||
}
|
||||
|
||||
cattr = TupleDescCompactAttr(tupleDesc, attnum);
|
||||
cattr = &cattrs[attnum];
|
||||
attlen = cattr->attlen;
|
||||
|
||||
/* As above, we don't expect cstrings */
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ typedef struct TupleConstr
|
|||
* directly after the FormData_pg_attribute struct is populated or
|
||||
* altered in any way.
|
||||
*
|
||||
* Currently, this struct is 16 bytes. Any code changes which enlarge this
|
||||
* Currently, this struct is 8 bytes. Any code changes which enlarge this
|
||||
* struct should be considered very carefully.
|
||||
*
|
||||
* Code which must access a TupleDesc's attribute data should always make use
|
||||
|
|
@ -67,17 +67,17 @@ typedef struct TupleConstr
|
|||
*/
|
||||
typedef struct CompactAttribute
|
||||
{
|
||||
int32 attcacheoff; /* fixed offset into tuple, if known, or -1 */
|
||||
int16 attcacheoff; /* fixed offset into tuple, if known, or -1 */
|
||||
int16 attlen; /* attr len in bytes or -1 = varlen, -2 =
|
||||
* cstring */
|
||||
bool attbyval; /* as FormData_pg_attribute.attbyval */
|
||||
bool attispackable; /* FormData_pg_attribute.attstorage !=
|
||||
* TYPSTORAGE_PLAIN */
|
||||
bool atthasmissing; /* as FormData_pg_attribute.atthasmissing */
|
||||
bool attisdropped; /* as FormData_pg_attribute.attisdropped */
|
||||
bool attgenerated; /* FormData_pg_attribute.attgenerated != '\0' */
|
||||
char attnullability; /* status of not-null constraint, see below */
|
||||
uint8 attalignby; /* alignment requirement in bytes */
|
||||
bool attispackable:1; /* FormData_pg_attribute.attstorage !=
|
||||
* TYPSTORAGE_PLAIN */
|
||||
bool atthasmissing:1; /* as FormData_pg_attribute.atthasmissing */
|
||||
bool attisdropped:1; /* as FormData_pg_attribute.attisdropped */
|
||||
bool attgenerated:1; /* FormData_pg_attribute.attgenerated != '\0' */
|
||||
char attnullability; /* status of not-null constraint, see below */
|
||||
} CompactAttribute;
|
||||
|
||||
/* Valid values for CompactAttribute->attnullability */
|
||||
|
|
|
|||
Loading…
Reference in a new issue