LCOV - code coverage report
Current view: top level - src/include/access - multixact_internal.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 84.0 % 25 21
Test Date: 2026-02-28 14:14:49 Functions: 77.8 % 9 7
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*
       2              :  * multixact_internal.h
       3              :  *
       4              :  * PostgreSQL multi-transaction-log manager internal declarations
       5              :  *
       6              :  * These functions and definitions are for dealing with pg_multixact SLRU
       7              :  * pages.  They are internal to multixact.c, but they are exported here to
       8              :  * allow pg_upgrade to write pg_multixact files directly.
       9              :  *
      10              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
      11              :  * Portions Copyright (c) 1994, Regents of the University of California
      12              :  *
      13              :  * src/include/access/multixact_internal.h
      14              :  */
      15              : #ifndef MULTIXACT_INTERNAL_H
      16              : 
      17              : /*
      18              :  * Note: This is not only to prevent including this file twice.
      19              :  * MULTIXACT_INTERNAL_H is checked explicitly in multixact_read_v18.c.
      20              :  */
      21              : #define MULTIXACT_INTERNAL_H
      22              : 
      23              : #include "access/multixact.h"
      24              : 
      25              : 
      26              : /*
      27              :  * Defines for MultiXactOffset page sizes.  A page is the same BLCKSZ as is
      28              :  * used everywhere else in Postgres.
      29              :  */
      30              : 
      31              : /* We need 8 bytes per offset */
      32              : #define MULTIXACT_OFFSETS_PER_PAGE (BLCKSZ / sizeof(MultiXactOffset))
      33              : 
      34              : static inline int64
      35       196094 : MultiXactIdToOffsetPage(MultiXactId multi)
      36              : {
      37       196094 :     return multi / MULTIXACT_OFFSETS_PER_PAGE;
      38              : }
      39              : 
      40              : static inline int
      41       200406 : MultiXactIdToOffsetEntry(MultiXactId multi)
      42              : {
      43       200406 :     return multi % MULTIXACT_OFFSETS_PER_PAGE;
      44              : }
      45              : 
      46              : static inline int64
      47            0 : MultiXactIdToOffsetSegment(MultiXactId multi)
      48              : {
      49            0 :     return MultiXactIdToOffsetPage(multi) / SLRU_PAGES_PER_SEGMENT;
      50              : }
      51              : 
      52              : /*
      53              :  * The situation for members is a bit more complex: we store one byte of
      54              :  * additional flag bits for each TransactionId.  To do this without getting
      55              :  * into alignment issues, we store four bytes of flags, and then the
      56              :  * corresponding 4 Xids.  Each such 5-word (20-byte) set we call a "group", and
      57              :  * are stored as a whole in pages.  Thus, with 8kB BLCKSZ, we keep 409 groups
      58              :  * per page.  This wastes 12 bytes per page, but that's OK -- simplicity (and
      59              :  * performance) trumps space efficiency here.
      60              :  *
      61              :  * Note that the "offset" macros work with byte offset, not array indexes, so
      62              :  * arithmetic must be done using "char *" pointers.
      63              :  */
      64              : /* We need eight bits per xact, so one xact fits in a byte */
      65              : #define MXACT_MEMBER_BITS_PER_XACT          8
      66              : #define MXACT_MEMBER_FLAGS_PER_BYTE         1
      67              : #define MXACT_MEMBER_XACT_BITMASK   ((1 << MXACT_MEMBER_BITS_PER_XACT) - 1)
      68              : 
      69              : /* how many full bytes of flags are there in a group? */
      70              : #define MULTIXACT_FLAGBYTES_PER_GROUP       4
      71              : #define MULTIXACT_MEMBERS_PER_MEMBERGROUP   \
      72              :     (MULTIXACT_FLAGBYTES_PER_GROUP * MXACT_MEMBER_FLAGS_PER_BYTE)
      73              : /* size in bytes of a complete group */
      74              : #define MULTIXACT_MEMBERGROUP_SIZE \
      75              :     (sizeof(TransactionId) * MULTIXACT_MEMBERS_PER_MEMBERGROUP + MULTIXACT_FLAGBYTES_PER_GROUP)
      76              : #define MULTIXACT_MEMBERGROUPS_PER_PAGE (BLCKSZ / MULTIXACT_MEMBERGROUP_SIZE)
      77              : #define MULTIXACT_MEMBERS_PER_PAGE  \
      78              :     (MULTIXACT_MEMBERGROUPS_PER_PAGE * MULTIXACT_MEMBERS_PER_MEMBERGROUP)
      79              : 
      80              : /* page in which a member is to be found */
      81              : static inline int64
      82      1832963 : MXOffsetToMemberPage(MultiXactOffset offset)
      83              : {
      84      1832963 :     return offset / MULTIXACT_MEMBERS_PER_PAGE;
      85              : }
      86              : 
      87              : static inline int64
      88            0 : MXOffsetToMemberSegment(MultiXactOffset offset)
      89              : {
      90            0 :     return MXOffsetToMemberPage(offset) / SLRU_PAGES_PER_SEGMENT;
      91              : }
      92              : 
      93              : /* Location (byte offset within page) of flag word for a given member */
      94              : static inline int
      95      3668257 : MXOffsetToFlagsOffset(MultiXactOffset offset)
      96              : {
      97      3668257 :     MultiXactOffset group = offset / MULTIXACT_MEMBERS_PER_MEMBERGROUP;
      98      3668257 :     int         grouponpg = group % MULTIXACT_MEMBERGROUPS_PER_PAGE;
      99      3668257 :     int         byteoff = grouponpg * MULTIXACT_MEMBERGROUP_SIZE;
     100              : 
     101      3668257 :     return byteoff;
     102              : }
     103              : 
     104              : static inline int
     105      1836336 : MXOffsetToFlagsBitShift(MultiXactOffset offset)
     106              : {
     107      1836336 :     int         member_in_group = offset % MULTIXACT_MEMBERS_PER_MEMBERGROUP;
     108      1836336 :     int         bshift = member_in_group * MXACT_MEMBER_BITS_PER_XACT;
     109              : 
     110      1836336 :     return bshift;
     111              : }
     112              : 
     113              : /* Location (byte offset within page) of TransactionId of given member */
     114              : static inline int
     115      1830980 : MXOffsetToMemberOffset(MultiXactOffset offset)
     116              : {
     117      1830980 :     int         member_in_group = offset % MULTIXACT_MEMBERS_PER_MEMBERGROUP;
     118              : 
     119      1830980 :     return MXOffsetToFlagsOffset(offset) +
     120      1830980 :         MULTIXACT_FLAGBYTES_PER_GROUP +
     121              :         member_in_group * sizeof(TransactionId);
     122              : }
     123              : 
     124              : /* Storage space consumed by a range of offsets, in bytes */
     125              : static inline uint64
     126           12 : MultiXactOffsetStorageSize(MultiXactOffset new_offset,
     127              :                            MultiXactOffset old_offset)
     128              : {
     129              :     Assert(new_offset >= old_offset);
     130           12 :     return (uint64) ((new_offset - old_offset) / MULTIXACT_MEMBERS_PER_MEMBERGROUP) *
     131              :         MULTIXACT_MEMBERGROUP_SIZE;
     132              : }
     133              : 
     134              : #endif                          /* MULTIXACT_INTERNAL_H */
        

Generated by: LCOV version 2.0-1