Branch data 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 : 12 : MultiXactIdToOffsetPage(MultiXactId multi)
36 : : {
37 : 12 : return multi / MULTIXACT_OFFSETS_PER_PAGE;
38 : : }
39 : :
40 : : static inline int
41 : 10 : MultiXactIdToOffsetEntry(MultiXactId multi)
42 : : {
43 : 10 : 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 : 12 : MXOffsetToMemberPage(MultiXactOffset offset)
83 : : {
84 : 12 : 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 : 14 : MXOffsetToFlagsOffset(MultiXactOffset offset)
96 : : {
97 : 14 : MultiXactOffset group = offset / MULTIXACT_MEMBERS_PER_MEMBERGROUP;
98 : 14 : int grouponpg = group % MULTIXACT_MEMBERGROUPS_PER_PAGE;
99 : 14 : int byteoff = grouponpg * MULTIXACT_MEMBERGROUP_SIZE;
100 : :
101 : 28 : return byteoff;
102 : 14 : }
103 : :
104 : : static inline int
105 : 6 : MXOffsetToFlagsBitShift(MultiXactOffset offset)
106 : : {
107 : 6 : int member_in_group = offset % MULTIXACT_MEMBERS_PER_MEMBERGROUP;
108 : 6 : int bshift = member_in_group * MXACT_MEMBER_BITS_PER_XACT;
109 : :
110 : 12 : return bshift;
111 : 6 : }
112 : :
113 : : /* Location (byte offset within page) of TransactionId of given member */
114 : : static inline int
115 : 4 : MXOffsetToMemberOffset(MultiXactOffset offset)
116 : : {
117 : 4 : int member_in_group = offset % MULTIXACT_MEMBERS_PER_MEMBERGROUP;
118 : :
119 : 12 : return MXOffsetToFlagsOffset(offset) +
120 : 4 : MULTIXACT_FLAGBYTES_PER_GROUP +
121 : 4 : member_in_group * sizeof(TransactionId);
122 : 4 : }
123 : :
124 : : /* Storage space consumed by a range of offsets, in bytes */
125 : : static inline uint64
126 : 3 : MultiXactOffsetStorageSize(MultiXactOffset new_offset,
127 : : MultiXactOffset old_offset)
128 : : {
129 [ + - ]: 3 : Assert(new_offset >= old_offset);
130 : 3 : return (uint64) ((new_offset - old_offset) / MULTIXACT_MEMBERS_PER_MEMBERGROUP) *
131 : : MULTIXACT_MEMBERGROUP_SIZE;
132 : : }
133 : :
134 : : #endif /* MULTIXACT_INTERNAL_H */
|