/src/mysql-server/libs/mysql/gtid/tsid.h
Line | Count | Source |
1 | | // Copyright (c) 2023, 2025, Oracle and/or its affiliates. |
2 | | // |
3 | | // This program is free software; you can redistribute it and/or modify |
4 | | // it under the terms of the GNU General Public License, version 2.0, |
5 | | // as published by the Free Software Foundation. |
6 | | // |
7 | | // This program is designed to work with certain software (including |
8 | | // but not limited to OpenSSL) that is licensed under separate terms, |
9 | | // as designated in a particular file or component or in included license |
10 | | // documentation. The authors of MySQL hereby grant you an additional |
11 | | // permission to link the program and your derivative works with the |
12 | | // separately licensed software that they have either included with |
13 | | // the program or referenced in the documentation. |
14 | | // |
15 | | // This program is distributed in the hope that it will be useful, |
16 | | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | | // GNU General Public License, version 2.0, for more details. |
19 | | // |
20 | | // You should have received a copy of the GNU General Public License |
21 | | // along with this program; if not, write to the Free Software |
22 | | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
23 | | |
24 | | #ifndef MYSQL_GTID_TSID_H |
25 | | #define MYSQL_GTID_TSID_H |
26 | | |
27 | | #include "mysql/gtid/gtid_constants.h" |
28 | | #include "mysql/gtid/gtid_format.h" |
29 | | #include "mysql/gtid/tag.h" |
30 | | #include "mysql/gtid/uuid.h" |
31 | | |
32 | | /// @addtogroup GroupLibsMysqlGtid |
33 | | /// @{ |
34 | | |
35 | | namespace mysql::gtid { |
36 | | |
37 | | /// @brief Maximum TSID text length (without null character) |
38 | | inline constexpr auto tsid_max_length = Uuid::TEXT_LENGTH + 1 + tag_max_length; |
39 | | |
40 | | struct Tsid_plain; |
41 | | |
42 | | /// @brief Represents Transaction Source Identifier which is composed of source |
43 | | /// UUID and transaction tag. Transaction tag may be empty. |
44 | | class Tsid { |
45 | | public: |
46 | | /// @brief Constructs TSID from a given uuid and a tag |
47 | | /// @param[in] uuid UUID component |
48 | | /// @param[in] tag Tag component |
49 | | Tsid(const Uuid &uuid, const Tag &tag); |
50 | | |
51 | | /// @brief Constructs TSID from a given uuid, tag is empty |
52 | | /// @param[in] uuid UUID component |
53 | | Tsid(const Uuid &uuid); |
54 | | |
55 | | /// @brief Construct from Tsid_plain object |
56 | | /// @param arg Source to copy from |
57 | | explicit Tsid(const Tsid_plain &arg); |
58 | | |
59 | | /// @brief Constructs empty TSID |
60 | | Tsid() = default; |
61 | | Tsid(Tsid const &) = default; |
62 | | Tsid(Tsid &&) = default; |
63 | | Tsid &operator=(Tsid const &) = default; |
64 | | Tsid &operator=(Tsid &&) = default; |
65 | | |
66 | | /// @brief Returns textual representation of Transaction Source Identifier |
67 | | std::string to_string() const; |
68 | | |
69 | | /// @brief Obtains textual representation of TSID and writes it to out |
70 | | /// @param [out] out Output string |
71 | | /// @returns Number of characters written to out |
72 | | std::size_t to_string(char *out) const; |
73 | | |
74 | | /// @brief Obtains textual representation of TSID and writes it to out |
75 | | /// @details version with a custom tag-sid separator |
76 | | /// @param [out] out Output string |
77 | | /// @param [in] tag_sid_separator Tag-sid separator |
78 | | /// @returns Number of characters written to out |
79 | | std::size_t to_string(char *out, const char *tag_sid_separator) const; |
80 | | |
81 | | /// @brief Fills Tsid with data from text |
82 | | /// @param[in] text Encoded TSID representation terminated with null sign, |
83 | | /// GTID separator or UUID set separator if part of the GTID set encoding |
84 | | /// @return The number of bytes read, or 0 on error |
85 | | [[nodiscard]] std::size_t from_cstring(const char *text); |
86 | | |
87 | | /// @brief Default TSID separator |
88 | | static constexpr auto tsid_separator = ":"; |
89 | | |
90 | | /// @brief Operator == |
91 | | /// @param other pattern to compare against |
92 | | /// @return Result of comparison == |
93 | | bool operator==(const Tsid &other) const; |
94 | | |
95 | | /// @brief Operator != |
96 | | /// @param other pattern to compare against |
97 | | /// @return Result of comparison != |
98 | | bool operator!=(const Tsid &other) const; |
99 | | |
100 | | /// @brief Operator < |
101 | | /// @details Compares uuid first. If uuids are equal, compares tags |
102 | | /// @param other pattern to compare against |
103 | | /// @return Result of comparison this < other |
104 | | bool operator<(const Tsid &other) const; |
105 | | |
106 | | /// @brief Tag accessor |
107 | | /// @return Const reference to Tag object |
108 | 0 | const Tag &get_tag() const { return m_tag; } |
109 | | |
110 | | /// @brief Tag accessor, non const (serialization) |
111 | | /// @return Non-const Reference to Tag object |
112 | 0 | Tag &get_tag_ref() { return m_tag; } |
113 | | |
114 | | /// @brief Sets internal tag to a given tag object |
115 | | /// @param tag Source to copy from |
116 | 0 | void set_tag(const Tag &tag) { m_tag = tag; } |
117 | | |
118 | | /// @brief UUID accessor |
119 | | /// @return Const reference to UUID component of TSID |
120 | 0 | const Uuid &get_uuid() const { return m_uuid; } |
121 | | |
122 | | /// @brief Non const getter is needed in some functions (copy data) |
123 | | /// @returns Reference to internal UUID |
124 | 0 | Uuid &get_uuid() { return m_uuid; } |
125 | | |
126 | | /// @brief Checks whether this TSID contains tag |
127 | | /// @retval true This TSID contains tag |
128 | | /// @retval false This TSID contains empty tag |
129 | 0 | bool is_tagged() const { return m_tag.is_defined(); } |
130 | | |
131 | | /// @brief Structure to compute hash function of a given Tag object |
132 | | struct Hash { |
133 | | /// @brief Computes hash of a given Tsid object |
134 | | /// @param arg Object handle for which hash will be calculated |
135 | 0 | size_t operator()(const Tsid &arg) const { |
136 | 0 | return Uuid_hash{}(arg.m_uuid) ^ Tag::Hash{}(arg.m_tag); |
137 | 0 | } |
138 | | }; |
139 | | friend struct Hash; |
140 | | |
141 | | /// @brief Clears data - uuid and tag |
142 | | void clear(); |
143 | | |
144 | | /// @brief Obtains maximum length of encoded TSID (compile time) |
145 | | /// @return Maximum length of encoded tag in bytes |
146 | 0 | static constexpr std::size_t get_max_encoded_length() { |
147 | 0 | return Uuid::BYTE_LENGTH + Tag::get_max_encoded_length(); |
148 | 0 | } |
149 | | |
150 | | /// @brief stores TSID in buffer |
151 | | /// @param buf Buffer to store bytes |
152 | | /// @return the number of bytes written into the buf |
153 | | /// @param gtid_format Format of encoded GTID. If tag is not defined for this |
154 | | /// GTID and tagged format is used, 0 will be encoded as length of the string. |
155 | | /// In case "untagged" format is requested, function won't encode additional |
156 | | /// tag information for untagged GTIDs. When using |
157 | | /// untagged, tag is required to be empty. |
158 | | std::size_t encode_tsid(unsigned char *buf, |
159 | | const Gtid_format >id_format) const; |
160 | | |
161 | | /// @brief reads TSID from the buffer |
162 | | /// @param stream Stream to read tsid from |
163 | | /// @param stream_len Length of the stream |
164 | | /// @param gtid_format Gtid format expected in the stream |
165 | | /// @return The number of bytes read or 0. 0 means that an error occurred |
166 | | /// (e.g. not enough bytes in the buffer to read the |
167 | | /// tsid - corrupted bytes in the buffer). |
168 | | [[nodiscard]] std::size_t decode_tsid(const unsigned char *stream, |
169 | | std::size_t stream_len, |
170 | | const Gtid_format >id_format); |
171 | | |
172 | | private: |
173 | | Uuid m_uuid = {0}; ///< GTID UUID |
174 | | Tag m_tag; ///< GTID Tag |
175 | | }; |
176 | | |
177 | | } // namespace mysql::gtid |
178 | | |
179 | | /// @} |
180 | | |
181 | | #endif // MYSQL_GTID_TSID_H |