Hi, hackers

While reviewing patch [1], I noticed that we can reduce padding in both
WALOpenSegment and XLogReaderState by reordering a few fields.

Current layout:
---------------

    (gdb) ptype/o WALOpenSegment
    type = struct WALOpenSegment {
    /*      0      |       4 */    int ws_file;
    /* XXX  4-byte hole      */
    /*      8      |       8 */    XLogSegNo ws_segno;
    /*     16      |       4 */    TimeLineID ws_tli;
    /* XXX  4-byte padding   */
    
                                   /* total size (bytes):   24 */
                                 }
    
    (gdb) ptype/o XLogReaderState
    type = struct XLogReaderState {
    /*      0      |      24 */    XLogReaderRoutine routine;
    /*     24      |       8 */    uint64 system_identifier;
    /*     32      |       8 */    void *private_data;
    /*     40      |       8 */    XLogRecPtr ReadRecPtr;
    /*     48      |       8 */    XLogRecPtr EndRecPtr;
    /*     56      |       8 */    XLogRecPtr abortedRecPtr;
    /*     64      |       8 */    XLogRecPtr missingContrecPtr;
    /*     72      |       8 */    XLogRecPtr overwrittenRecPtr;
    /*     80      |       8 */    XLogRecPtr DecodeRecPtr;
    /*     88      |       8 */    XLogRecPtr NextRecPtr;
    /*     96      |       8 */    XLogRecPtr PrevRecPtr;
    /*    104      |       8 */    DecodedXLogRecord *record;
    /*    112      |       8 */    char *decode_buffer;
    /*    120      |       8 */    size_t decode_buffer_size;
    /*    128      |       1 */    _Bool free_decode_buffer;
    /* XXX  7-byte hole      */
    /*    136      |       8 */    char *decode_buffer_head;
    /*    144      |       8 */    char *decode_buffer_tail;
    /*    152      |       8 */    DecodedXLogRecord *decode_queue_head;
    /*    160      |       8 */    DecodedXLogRecord *decode_queue_tail;
    /*    168      |       8 */    char *readBuf;
    /*    176      |       4 */    uint32 readLen;
    /*    180      |    1028 */    WALSegmentContext segcxt;
    /*   1208      |      24 */    WALOpenSegment seg;
    /*   1232      |       4 */    uint32 segoff;
    /* XXX  4-byte hole      */
    /*   1240      |       8 */    XLogRecPtr latestPagePtr;
    /*   1248      |       4 */    TimeLineID latestPageTLI;
    /* XXX  4-byte hole      */
    /*   1256      |       8 */    XLogRecPtr currRecPtr;
    /*   1264      |       4 */    TimeLineID currTLI;
    /* XXX  4-byte hole      */
    /*   1272      |       8 */    XLogRecPtr currTLIValidUntil;
    /*   1280      |       4 */    TimeLineID nextTLI;
    /* XXX  4-byte hole      */
    /*   1288      |       8 */    char *readRecordBuf;
    /*   1296      |       4 */    uint32 readRecordBufSize;
    /* XXX  4-byte hole      */
    /*   1304      |       8 */    char *errormsg_buf;
    /*   1312      |       1 */    _Bool errormsg_deferred;
    /*   1313      |       1 */    _Bool nonblocking;
    /* XXX  6-byte padding   */
    
                                   /* total size (bytes): 1320 */
                                 }

The proposed change as follows:
-------------------------------

diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h
index 4a9a687e879..6a52ed819cf 100644
--- a/src/include/access/xlogreader.h
+++ b/src/include/access/xlogreader.h
@@ -45,8 +45,8 @@
 typedef struct WALOpenSegment
 {
        int                     ws_file;                /* segment file 
descriptor */
-       XLogSegNo       ws_segno;               /* segment number */
        TimeLineID      ws_tli;                 /* timeline ID of the currently 
open file */
+       XLogSegNo       ws_segno;               /* segment number */
 } WALOpenSegment;
 
 /* WALSegmentContext carries context information about WAL segments to read */
@@ -267,9 +267,9 @@ struct XLogReaderState
        uint32          readLen;
 
        /* last read XLOG position for data currently in readBuf */
+       uint32          segoff;
        WALSegmentContext segcxt;
        WALOpenSegment seg;
-       uint32          segoff;
 
        /*
         * beginning of prior page read, and its TLI.  Doesn't necessarily
@@ -278,10 +278,10 @@ struct XLogReaderState
        XLogRecPtr      latestPagePtr;
        TimeLineID      latestPageTLI;
 
-       /* beginning of the WAL record being read. */
-       XLogRecPtr      currRecPtr;
        /* timeline to read it from, 0 if a lookup is required */
        TimeLineID      currTLI;
+       /* beginning of the WAL record being read. */
+       XLogRecPtr      currRecPtr;
 
        /*
         * Safe point to read to in currTLI if current TLI is historical
@@ -303,8 +303,8 @@ struct XLogReaderState
         * Buffer for current ReadRecord result (expandable), used when a record
         * crosses a page boundary.
         */
-       char       *readRecordBuf;
        uint32          readRecordBufSize;
+       char       *readRecordBuf;
 
        /* Buffer to hold error message */
        char       *errormsg_buf;

With this reordering, the sizes shrink as follows:

  - WALOpenSegment: 24 → 16 bytes
  - XLogReaderState: 1320 → 1296 bytes

New layout:
-----------

    (gdb) ptype/o WALOpenSegment
    type = struct WALOpenSegment {
    /*      0      |       4 */    int ws_file;
    /*      4      |       4 */    TimeLineID ws_tli;
    /*      8      |       8 */    XLogSegNo ws_segno;
    
                                   /* total size (bytes):   16 */
                                 }
    
    (gdb) ptype/o XLogReaderState
    type = struct XLogReaderState {
    /*      0      |      24 */    XLogReaderRoutine routine;
    /*     24      |       8 */    uint64 system_identifier;
    /*     32      |       8 */    void *private_data;
    /*     40      |       8 */    XLogRecPtr ReadRecPtr;
    /*     48      |       8 */    XLogRecPtr EndRecPtr;
    /*     56      |       8 */    XLogRecPtr abortedRecPtr;
    /*     64      |       8 */    XLogRecPtr missingContrecPtr;
    /*     72      |       8 */    XLogRecPtr overwrittenRecPtr;
    /*     80      |       8 */    XLogRecPtr DecodeRecPtr;
    /*     88      |       8 */    XLogRecPtr NextRecPtr;
    /*     96      |       8 */    XLogRecPtr PrevRecPtr;
    /*    104      |       8 */    DecodedXLogRecord *record;
    /*    112      |       8 */    char *decode_buffer;
    /*    120      |       8 */    size_t decode_buffer_size;
    /*    128      |       1 */    _Bool free_decode_buffer;
    /* XXX  7-byte hole      */
    /*    136      |       8 */    char *decode_buffer_head;
    /*    144      |       8 */    char *decode_buffer_tail;
    /*    152      |       8 */    DecodedXLogRecord *decode_queue_head;
    /*    160      |       8 */    DecodedXLogRecord *decode_queue_tail;
    /*    168      |       8 */    char *readBuf;
    /*    176      |       4 */    uint32 readLen;
    /*    180      |       4 */    uint32 segoff;
    /*    184      |    1028 */    WALSegmentContext segcxt;
    /* XXX  4-byte hole      */
    /*   1216      |      16 */    WALOpenSegment seg;
    /*   1232      |       8 */    XLogRecPtr latestPagePtr;
    /*   1240      |       4 */    TimeLineID latestPageTLI;
    /*   1244      |       4 */    TimeLineID currTLI;
    /*   1248      |       8 */    XLogRecPtr currRecPtr;
    /*   1256      |       8 */    XLogRecPtr currTLIValidUntil;
    /*   1264      |       4 */    TimeLineID nextTLI;
    /*   1268      |       4 */    uint32 readRecordBufSize;
    /*   1272      |       8 */    char *readRecordBuf;
    /*   1280      |       8 */    char *errormsg_buf;
    /*   1288      |       1 */    _Bool errormsg_deferred;
    /*   1289      |       1 */    _Bool nonblocking;
    /* XXX  6-byte padding   */
    
                                   /* total size (bytes): 1296 */
                                 }

Any thoughts?

[1] https://postgr.es/m/[email protected]
-- 
Regards,
Japin Li
ChengDu WenWu Information Technology Co., Ltd.


Reply via email to