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-2025, 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 391902 : MultiXactIdToOffsetPage(MultiXactId multi) 36 : { 37 391902 : return multi / MULTIXACT_OFFSETS_PER_PAGE; 38 : } 39 : 40 : static inline int 41 400538 : MultiXactIdToOffsetEntry(MultiXactId multi) 42 : { 43 400538 : 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 3665580 : MXOffsetToMemberPage(MultiXactOffset offset) 83 : { 84 3665580 : 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 7335960 : MXOffsetToFlagsOffset(MultiXactOffset offset) 96 : { 97 7335960 : MultiXactOffset group = offset / MULTIXACT_MEMBERS_PER_MEMBERGROUP; 98 7335960 : int grouponpg = group % MULTIXACT_MEMBERGROUPS_PER_PAGE; 99 7335960 : int byteoff = grouponpg * MULTIXACT_MEMBERGROUP_SIZE; 100 : 101 7335960 : return byteoff; 102 : } 103 : 104 : static inline int 105 3672398 : MXOffsetToFlagsBitShift(MultiXactOffset offset) 106 : { 107 3672398 : int member_in_group = offset % MULTIXACT_MEMBERS_PER_MEMBERGROUP; 108 3672398 : int bshift = member_in_group * MXACT_MEMBER_BITS_PER_XACT; 109 : 110 3672398 : return bshift; 111 : } 112 : 113 : /* Location (byte offset within page) of TransactionId of given member */ 114 : static inline int 115 3661740 : MXOffsetToMemberOffset(MultiXactOffset offset) 116 : { 117 3661740 : int member_in_group = offset % MULTIXACT_MEMBERS_PER_MEMBERGROUP; 118 : 119 3661740 : return MXOffsetToFlagsOffset(offset) + 120 3661740 : MULTIXACT_FLAGBYTES_PER_GROUP + 121 : member_in_group * sizeof(TransactionId); 122 : } 123 : 124 : #endif /* MULTIXACT_INTERNAL_H */