]> granicus.if.org Git - postgresql/commitdiff
Arrange to squeeze out the MINIMAL_TUPLE_PADDING in the tuple representation
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 28 Oct 2008 15:51:03 +0000 (15:51 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 28 Oct 2008 15:51:03 +0000 (15:51 +0000)
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.

src/backend/utils/sort/tuplesort.c
src/backend/utils/sort/tuplestore.c
src/include/access/htup.h

index 29a076e1384624bf97664505d83b10996a264aa7..02aee0f8b405c48a2c20777964dc844ec0df5e5d 100644 (file)
@@ -91,7 +91,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * 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)
                                                                &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,
index b5bd67c1b4e6fa870154246749ee576809479f12..a99386fa936770937943b80c3f3def056861e88a 100644 (file)
@@ -46,7 +46,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * 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
 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,
index 85271c26c3ac80bf941cefc0d338826fc78fa19c..0803c1b2c77cbd587245809f989963b0ae0c8b49 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
  * 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 { \
  *
  * 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
 {