summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2008-10-28 15:51:03 +0000
committerTom Lane2008-10-28 15:51:03 +0000
commit5230c754b8e4022e5c0608fc212bdab2cd06f652 (patch)
tree32c66fe23981c00ec7b6e028a1f59238ee4a6c67
parentc83d9efb3356bd4c7d307d93ac2e5265a2965177 (diff)
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.
-rw-r--r--src/backend/utils/sort/tuplesort.c26
-rw-r--r--src/backend/utils/sort/tuplestore.c26
-rw-r--r--src/include/access/htup.h6
3 files changed, 39 insertions, 19 deletions
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index 6b7c8868cc..ce00d77dd9 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -2632,18 +2632,20 @@ copytup_heap(Tuplesortstate *state, SortTuple *stup, void *tup)
&stup->isnull1);
}
-/*
- * Since MinimalTuple already has length in its first word, we don't need
- * to write that separately.
- */
static void
writetup_heap(Tuplesortstate *state, int tapenum, SortTuple *stup)
{
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,
- (void *) tuple, tuplen);
+ (void *) &tuplen, sizeof(tuplen));
+ LogicalTapeWrite(state->tapeset, tapenum,
+ (void *) tupbody, tupbodylen);
if (state->randomAccess) /* need trailing length word? */
LogicalTapeWrite(state->tapeset, tapenum,
(void *) &tuplen, sizeof(tuplen));
@@ -2656,16 +2658,18 @@ static void
readtup_heap(Tuplesortstate *state, SortTuple *stup,
int tapenum, unsigned int len)
{
- MinimalTuple tuple = (MinimalTuple) palloc(len);
- unsigned int tuplen;
+ unsigned int tupbodylen = len - sizeof(int);
+ unsigned int tuplen = tupbodylen + MINIMAL_TUPLE_DATA_OFFSET;
+ MinimalTuple tuple = (MinimalTuple) palloc(tuplen);
+ char *tupbody = (char *) tuple + MINIMAL_TUPLE_DATA_OFFSET;
HeapTupleData htup;
USEMEM(state, GetMemoryChunkSpace(tuple));
/* read in the tuple proper */
- tuple->t_len = len;
+ tuple->t_len = tuplen;
if (LogicalTapeRead(state->tapeset, tapenum,
- (void *) ((char *) tuple + sizeof(int)),
- len - sizeof(int)) != (size_t) (len - sizeof(int)))
+ (void *) tupbody,
+ tupbodylen) != (size_t) tupbodylen)
elog(ERROR, "unexpected end of data");
if (state->randomAccess) /* need trailing length word? */
if (LogicalTapeRead(state->tapeset, tapenum, (void *) &tuplen,
diff --git a/src/backend/utils/sort/tuplestore.c b/src/backend/utils/sort/tuplestore.c
index d2eff7ba3c..bd3d4ab8ed 100644
--- a/src/backend/utils/sort/tuplestore.c
+++ b/src/backend/utils/sort/tuplestore.c
@@ -1173,9 +1173,17 @@ static void
writetup_heap(Tuplestorestate *state, void *tup)
{
MinimalTuple tuple = (MinimalTuple) tup;
- unsigned int tuplen = tuple->t_len;
-
- if (BufFileWrite(state->myfile, (void *) tuple, tuplen) != (size_t) tuplen)
+ /* 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 *) &tuplen,
+ sizeof(tuplen)) != sizeof(tuplen))
+ elog(ERROR, "write failed");
+ if (BufFileWrite(state->myfile, (void *) tupbody,
+ tupbodylen) != (size_t) tupbodylen)
elog(ERROR, "write failed");
if (state->backward) /* need trailing length word? */
if (BufFileWrite(state->myfile, (void *) &tuplen,
@@ -1189,14 +1197,16 @@ writetup_heap(Tuplestorestate *state, void *tup)
static void *
readtup_heap(Tuplestorestate *state, unsigned int len)
{
- MinimalTuple tuple = (MinimalTuple) palloc(len);
- unsigned int tuplen;
+ unsigned int tupbodylen = len - sizeof(int);
+ 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));
/* read in the tuple proper */
- tuple->t_len = len;
- if (BufFileRead(state->myfile, (void *) ((char *) tuple + sizeof(int)),
- len - sizeof(int)) != (size_t) (len - sizeof(int)))
+ tuple->t_len = tuplen;
+ if (BufFileRead(state->myfile, (void *) tupbody,
+ tupbodylen) != (size_t) tupbodylen)
elog(ERROR, "unexpected end of data");
if (state->backward) /* need trailing length word? */
if (BufFileRead(state->myfile, (void *) &tuplen,
diff --git a/src/include/access/htup.h b/src/include/access/htup.h
index 0c80361414..2a49ad54ca 100644
--- a/src/include/access/htup.h
+++ b/src/include/access/htup.h
@@ -420,11 +420,17 @@ do { \
*
* 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.
+ *
+ * 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 \
((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) / MAXIMUM_ALIGNOF * MAXIMUM_ALIGNOF)
#define MINIMAL_TUPLE_PADDING \
((offsetof(HeapTupleHeaderData, t_infomask2) - sizeof(uint32)) % MAXIMUM_ALIGNOF)
+#define MINIMAL_TUPLE_DATA_OFFSET \
+ offsetof(MinimalTupleData, t_infomask2)
typedef struct MinimalTupleData
{