Skip to content

Commit 2c94e21

Browse files
committed
do not align pass-by-value type in additional info. It saves ~30% size of index
1 parent 4e9c501 commit 2c94e21

File tree

2 files changed

+75
-5
lines changed

2 files changed

+75
-5
lines changed

rum.h

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -851,9 +851,47 @@ rumDataPageLeafRead(Pointer ptr, OffsetNumber attnum, ItemPointer iptr,
851851
if (!isNull)
852852
{
853853
attr = rumstate->addAttrs[attnum - 1];
854-
ptr = (Pointer) att_align_pointer(ptr, attr->attalign, attr->attlen, ptr);
855-
if (addInfo)
856-
*addInfo = fetch_att(ptr, attr->attbyval, attr->attlen);
854+
855+
if (attr->attbyval)
856+
{
857+
/* do not use aligment for pass-by-value types */
858+
if (addInfo)
859+
{
860+
union {
861+
int16 i16;
862+
int32 i32;
863+
} u;
864+
865+
switch(attr->attlen)
866+
{
867+
case sizeof(char):
868+
*addInfo = Int8GetDatum(*ptr);
869+
break;
870+
case sizeof(int16):
871+
memcpy(&u.i16, ptr, sizeof(int16));
872+
*addInfo = Int16GetDatum(u.i16);
873+
break;
874+
case sizeof(int32):
875+
memcpy(&u.i32, ptr, sizeof(int32));
876+
*addInfo = Int32GetDatum(u.i32);
877+
break;
878+
#if SIZEOF_DATUM == 8
879+
case sizeof(Datum):
880+
memcpy(addInfo, ptr, sizeof(Datum));
881+
break;
882+
#endif
883+
default:
884+
elog(ERROR, "unsupported byval length: %d", (int) (attr->attlen));
885+
}
886+
}
887+
}
888+
else
889+
{
890+
ptr = (Pointer) att_align_pointer(ptr, attr->attalign, attr->attlen, ptr);
891+
if (addInfo)
892+
*addInfo = fetch_att(ptr, attr->attbyval, attr->attlen);
893+
}
894+
857895
ptr = (Pointer) att_addlength_pointer(ptr, attr->attlen, ptr);
858896
}
859897
return ptr;

rumdatapage.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ rumComputeDatumSize(Size data_length, Datum val, bool typbyval, char typalign,
3636
*/
3737
data_length += VARATT_CONVERTED_SHORT_SIZE(DatumGetPointer(val));
3838
}
39+
else if (typbyval)
40+
{
41+
/* do not align type pass-by-value because anyway we
42+
* will copy Datum */
43+
data_length = att_addlength_datum(data_length, typlen, val);
44+
}
3945
else
4046
{
4147
data_length = att_align_datum(data_length, typalign, typlen, val);
@@ -60,8 +66,34 @@ rumDatumWrite(Pointer ptr, Datum datum, bool typbyval, char typalign,
6066
if (typbyval)
6167
{
6268
/* pass-by-value */
63-
ptr = (char *) att_align_nominal(ptr, typalign);
64-
store_att_byval(ptr, datum, typlen);
69+
union {
70+
int16 i16;
71+
int32 i32;
72+
} u;
73+
74+
/* align-safe version of store_att_byval(ptr, datum, typlen); */
75+
switch(typlen)
76+
{
77+
case sizeof(char):
78+
*ptr = DatumGetChar(datum);
79+
break;
80+
case sizeof(int16):
81+
u.i16 = DatumGetInt16(datum);
82+
memcpy(ptr, &u.i16, sizeof(int16));
83+
break;
84+
case sizeof(int32):
85+
u.i32 = DatumGetInt32(datum);
86+
memcpy(ptr, &u.i32, sizeof(int32));
87+
break;
88+
#if SIZEOF_DATUM == 8
89+
case sizeof(Datum):
90+
memcpy(ptr, &datum, sizeof(Datum));
91+
break;
92+
#endif
93+
default:
94+
elog(ERROR, "unsupported byval length: %d", (int) (typlen));
95+
}
96+
6597
data_length = typlen;
6698
}
6799
else if (typlen == -1)

0 commit comments

Comments
 (0)