Commit d26bf23f authored by Tom Lane's avatar Tom Lane

Arrange to squeeze out the MINIMAL_TUPLE_PADDING in the tuple representation

written to temp files by tuplesort.c and tuplestore.c.  This saves 2 bytes per
row for 32-bit machines, and 6 bytes per row for 64-bit machines, which seems
worth the slight additional uglification of the tuple read/write routines.
parent 8ecd5351
...@@ -91,7 +91,7 @@ ...@@ -91,7 +91,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.87 2008/09/15 18:43:41 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/sort/tuplesort.c,v 1.88 2008/10/28 15:51:03 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -2632,18 +2632,20 @@ copytup_heap(Tuplesortstate *state, SortTuple *stup, void *tup) ...@@ -2632,18 +2632,20 @@ copytup_heap(Tuplesortstate *state, SortTuple *stup, void *tup)
&stup->isnull1); &stup->isnull1);
} }
/*
* Since MinimalTuple already has length in its first word, we don't need
* to write that separately.
*/
static void static void
writetup_heap(Tuplesortstate *state, int tapenum, SortTuple *stup) writetup_heap(Tuplesortstate *state, int tapenum, SortTuple *stup)
{ {
MinimalTuple tuple = (MinimalTuple) stup->tuple; MinimalTuple tuple = (MinimalTuple) stup->tuple;
unsigned int tuplen = tuple->t_len; /* the part of the MinimalTuple we'll write: */
char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
unsigned int tupbodylen = tuple->t_len - MINIMAL_TUPLE_DATA_OFFSET;
/* total on-disk footprint: */
unsigned int tuplen = tupbodylen + sizeof(int);
LogicalTapeWrite(state->tapeset, tapenum, LogicalTapeWrite(state->tapeset, tapenum,
(void *) tuple, tuplen); (void *) &tuplen, sizeof(tuplen));
LogicalTapeWrite(state->tapeset, tapenum,
(void *) tupbody, tupbodylen);
if (state->randomAccess) /* need trailing length word? */ if (state->randomAccess) /* need trailing length word? */
LogicalTapeWrite(state->tapeset, tapenum, LogicalTapeWrite(state->tapeset, tapenum,
(void *) &tuplen, sizeof(tuplen)); (void *) &tuplen, sizeof(tuplen));
...@@ -2656,16 +2658,18 @@ static void ...@@ -2656,16 +2658,18 @@ static void
readtup_heap(Tuplesortstate *state, SortTuple *stup, readtup_heap(Tuplesortstate *state, SortTuple *stup,
int tapenum, unsigned int len) int tapenum, unsigned int len)
{ {
MinimalTuple tuple = (MinimalTuple) palloc(len); unsigned int tupbodylen = len - sizeof(int);
unsigned int tuplen; unsigned int tuplen = tupbodylen + MINIMAL_TUPLE_DATA_OFFSET;
MinimalTuple tuple = (MinimalTuple) palloc(tuplen);
char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
HeapTupleData htup; HeapTupleData htup;
USEMEM(state, GetMemoryChunkSpace(tuple)); USEMEM(state, GetMemoryChunkSpace(tuple));
/* read in the tuple proper */ /* read in the tuple proper */
tuple->t_len = len; tuple->t_len = tuplen;
if (LogicalTapeRead(state->tapeset, tapenum, if (LogicalTapeRead(state->tapeset, tapenum,
(void *) ((char *) tuple + sizeof(int)), (void *) tupbody,
len - sizeof(int)) != (size_t) (len - sizeof(int))) tupbodylen) != (size_t) tupbodylen)
elog(ERROR, "unexpected end of data"); elog(ERROR, "unexpected end of data");
if (state->randomAccess) /* need trailing length word? */ if (state->randomAccess) /* need trailing length word? */
if (LogicalTapeRead(state->tapeset, tapenum, (void *) &tuplen, if (LogicalTapeRead(state->tapeset, tapenum, (void *) &tuplen,
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.42 2008/10/07 00:05:55 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/sort/tuplestore.c,v 1.43 2008/10/28 15:51:03 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1173,9 +1173,17 @@ static void ...@@ -1173,9 +1173,17 @@ static void
writetup_heap(Tuplestorestate *state, void *tup) writetup_heap(Tuplestorestate *state, void *tup)
{ {
MinimalTuple tuple = (MinimalTuple) tup; MinimalTuple tuple = (MinimalTuple) tup;
unsigned int tuplen = tuple->t_len; /* the part of the MinimalTuple we'll write: */
char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
unsigned int tupbodylen = tuple->t_len - MINIMAL_TUPLE_DATA_OFFSET;
/* total on-disk footprint: */
unsigned int tuplen = tupbodylen + sizeof(int);
if (BufFileWrite(state->myfile, (void *) tuple, tuplen) != (size_t) tuplen) if (BufFileWrite(state->myfile, (void *) &tuplen,
sizeof(tuplen)) != sizeof(tuplen))
elog(ERROR, "write failed");
if (BufFileWrite(state->myfile, (void *) tupbody,
tupbodylen) != (size_t) tupbodylen)
elog(ERROR, "write failed"); elog(ERROR, "write failed");
if (state->backward) /* need trailing length word? */ if (state->backward) /* need trailing length word? */
if (BufFileWrite(state->myfile, (void *) &tuplen, if (BufFileWrite(state->myfile, (void *) &tuplen,
...@@ -1189,14 +1197,16 @@ writetup_heap(Tuplestorestate *state, void *tup) ...@@ -1189,14 +1197,16 @@ writetup_heap(Tuplestorestate *state, void *tup)
static void * static void *
readtup_heap(Tuplestorestate *state, unsigned int len) readtup_heap(Tuplestorestate *state, unsigned int len)
{ {
MinimalTuple tuple = (MinimalTuple) palloc(len); unsigned int tupbodylen = len - sizeof(int);
unsigned int tuplen; unsigned int tuplen = tupbodylen + MINIMAL_TUPLE_DATA_OFFSET;
MinimalTuple tuple = (MinimalTuple) palloc(tuplen);
char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
USEMEM(state, GetMemoryChunkSpace(tuple)); USEMEM(state, GetMemoryChunkSpace(tuple));
/* read in the tuple proper */ /* read in the tuple proper */
tuple->t_len = len; tuple->t_len = tuplen;
if (BufFileRead(state->myfile, (void *) ((char *) tuple + sizeof(int)), if (BufFileRead(state->myfile, (void *) tupbody,
len - sizeof(int)) != (size_t) (len - sizeof(int))) tupbodylen) != (size_t) tupbodylen)
elog(ERROR, "unexpected end of data"); elog(ERROR, "unexpected end of data");
if (state->backward) /* need trailing length word? */ if (state->backward) /* need trailing length word? */
if (BufFileRead(state->myfile, (void *) &tuplen, if (BufFileRead(state->myfile, (void *) &tuplen,
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/access/htup.h,v 1.101 2008/08/11 11:05:11 heikki Exp $ * $PostgreSQL: pgsql/src/include/access/htup.h,v 1.102 2008/10/28 15:51:03 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -420,11 +420,17 @@ do { \ ...@@ -420,11 +420,17 @@ do { \
* *
* Note that t_hoff is computed the same as in a full tuple, hence it includes * Note that t_hoff is computed the same as in a full tuple, hence it includes
* the MINIMAL_TUPLE_OFFSET distance. t_len does not include that, however. * the MINIMAL_TUPLE_OFFSET distance. t_len does not include that, however.
*
* MINIMAL_TUPLE_DATA_OFFSET is the offset to the first useful (non-pad) data
* other than the length word. tuplesort.c and tuplestore.c use this to avoid
* writing the padding to disk.
*/ */
#define MINIMAL_TUPLE_OFFSET \ #define MINIMAL_TUPLE_OFFSET \
((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) / MAXIMUM_ALIGNOF * MAXIMUM_ALIGNOF) ((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) / MAXIMUM_ALIGNOF * MAXIMUM_ALIGNOF)
#define MINIMAL_TUPLE_PADDING \ #define MINIMAL_TUPLE_PADDING \
((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) % MAXIMUM_ALIGNOF) ((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) % MAXIMUM_ALIGNOF)
#define MINIMAL_TUPLE_DATA_OFFSET \
offsetof(MinimalTupleData, t_infomask2)
typedef struct MinimalTupleData typedef struct MinimalTupleData
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment