24#ifndef MYSQL_GTIDS_STRCONV_GTID_BINARY_FORMAT_CONV_H
25#define MYSQL_GTIDS_STRCONV_GTID_BINARY_FORMAT_CONV_H
51 switch (
format.m_version_policy) {
58 target.write(
format, tag.string_view());
65 if (
format.m_version_policy ==
79 [[maybe_unused]]
auto ret =
90 string_target.concat(
format, tsid.uuid(), tsid.tag());
106 string_target.write(
format, gtid.tsid());
107 string_target.write(
Binary_format{}, gtid.get_sequence_number());
116 auto check_sequence_number =
Checker([&] {
124 [[maybe_unused]]
auto ret = gtid.set_sequence_number(sequence_number);
135template <std::
integral Int_t = u
int64_t>
140 return (Int_t(1) <<
n) - Int_t(1);
179 case Version::v0_tagless:
182 case Version::v1_tags:
183 case Version::v2_tags_compact: {
186 code = (version_byte << Gtid_set_header::version_shift0) |
187 (version_byte << Gtid_set_header::version_shift1) |
188 (header.
m_tsid_count << Gtid_set_header::tsid_count_shift1);
200 uint64_t header_word;
203 auto check_version =
Checker([&] {
204 auto version_byte0 = int((header_word >> Gtid_set_header::version_shift0) &
205 Gtid_set_header::version_mask);
208 mysql::utils::to_enumeration<Version>(version_byte0);
211 "Unknown (future?) GTID set format version number in GTID encoding");
214 if (version0 != Version::v0_tagless) {
217 int((header_word >> Gtid_set_header::version_shift1) &
218 Gtid_set_header::version_mask);
220 if (version_byte0 != version_byte1) {
222 "Inconsistent GTID set format version numbers in GTID encoding");
228 if (
format.m_version_policy != Version_policy::automatic &&
229 format.m_version_policy !=
232 "Disallowed GTID set format version number in GTID encoding");
244 auto tsid_shift = (
version == Version::v0_tagless)
245 ? Gtid_set_header::tsid_count_shift0
246 : Gtid_set_header::tsid_count_shift1;
248 (header_word >> tsid_shift) & Gtid_set_header::tsid_count_mask;
257 for (
const auto &[tsid, interval_set] : gtid_set) {
258 string_target.write(
format, tsid);
267 if (gtid_set.empty())
return;
270 using Tag_map = std::map<mysql::gtids::Tag, std::size_t>;
273 for (
const auto &[tsid, interval_set] : gtid_set) {
279 string_target.write(
format, tag_map.size());
281 std::size_t tag_index = 0;
282 for (
auto &[tag, number] : tag_map) {
283 string_target.write(
format, tag);
291 std::optional<mysql::uuids::Uuid> last_uuid;
292 for (
const auto &[tsid, interval_set] : gtid_set) {
293 bool is_new_uuid = !last_uuid.has_value() || *last_uuid != tsid.uuid();
294 uint64_t code = tag_map[tsid.tag()] << 1;
295 if (is_new_uuid) code |= 1;
296 string_target.write(
format, code);
298 string_target.write(
format, tsid.uuid());
300 string_target.write(
format, interval_set);
301 last_uuid = tsid.uuid();
314 auto size = gtid_set.size();
315 switch (
format.m_version_policy) {
316 case Version_policy::v0_tagless:
317 string_target.write(
format, Header{Version::v0_tagless,
size});
320 case Version_policy::v1_tags:
321 string_target.write(
format, Header{Version::v1_tags,
size});
324 case Version_policy::v2_tags_compact:
325 string_target.write(
format, Header{Version::v2_tags_compact,
size});
328 case Version_policy::automatic:
334 : Version::v0_tagless;
338 string_target, gtid_set);
347 std::size_t tsid_count) {
351 fluent.call_exact(tsid_count, [&] {
354 .check_prev_token([&] {
355 if (gtid_set.inplace_union(tsid, std::move(interval_set)) !=
363 interval_set.
clear();
370 std::size_t tsid_count) {
374 if (tsid_count == 0)
return;
376 std::size_t tag_count{0};
377 std::vector<mysql::gtids::Tag> tags;
379 bool is_first_tsid{
true};
384 .check_prev_token([&] {
386 tags.reserve(tag_count);
387 }
catch (std::bad_alloc &) {
396 tags.emplace_back(tag);
399 .call_exact(tsid_count, [&] {
402 std::size_t tag_index{0};
403 bool new_uuid{
false};
404 auto check_code =
Checker([&] {
405 tag_index = std::size_t(code >> 1);
406 if (tag_index >= tags.size()) {
407 parser.set_parse_error(
"Tag index out of range");
409 new_uuid = ((code & 1) != 0);
410 if (is_first_tsid && !new_uuid) {
411 parser.set_parse_error(
"No UUID given for first Tsid");
414 is_first_tsid =
false;
420 tsid.
tag().assign(tags[tag_index]);
429 auto check_interval_set =
Checker([&] {
430 if (gtid_set.inplace_union(tsid, std::move(interval_set)) !=
435 if (
parser.read(Binary_format{} | check_interval_set, interval_set) !=
450 Gtid_binary_format::to_version_policy(header.
m_version)};
452 case Version::v0_tagless:
453 case Version::v1_tags:
457 case Version::v2_tags_compact:
Class representing a version.
Definition: designator.h:45
Class that defines the Interval set type used for Gtid intervals.
Definition: gtid_set.h:123
Class representing a tag by storing the characters in a member array.
Definition: tag.h:353
static bool is_valid(const std::string_view &sv)
Return true if the given string is a valid tag.
Definition: tag.h:148
const auto & tag() const
Definition: tsid.h:75
const mysql::uuids::Uuid & uuid() const
Definition: tsid.h:72
void clear() noexcept
Make this container empty.
Definition: interval_container.h:188
Class holding a checker function, used to check the validity of a parsed value.
Definition: checker.h:57
Object used to parse strings.
Definition: parser.h:69
Return_status_t read(const Is_parse_options auto &opt, Object_t &obj)
Parse into the given object.
Definition: parser.h:225
void set_parse_error(const std::string_view &message)
Store a result representing that the requested object could not be parsed because the string is wrong...
Definition: parser.h:94
True for all Gtid set types.
Definition: gtid_set.h:178
True if Test is one of the tag classes.
Definition: tag.h:192
Concept that holds for String_counter and String_writer.
Definition: string_target.h:111
uint16_t value_type
Definition: vt100.h:184
Definition: fts0fts.cc:236
constexpr auto low_bits(int n)
Return a value of the given integer type having the low N bits set to 1.
Definition: gtid_binary_format_conv.h:136
uint64_t Sequence_number
The type of the sequence number component of a GTID.
Definition: sequence_number.h:39
constexpr bool is_valid_sequence_number(Sequence_number sequence_number)
Return true if the given Sequence_number is in the allowed range.
Definition: sequence_number.h:53
bool has_tags(const Is_tag auto &tag)
Definition: has_tags.h:41
void decode_v2(const Gtid_binary_format &format, Parser &parser, mysql::gtids::Is_gtid_set auto >id_set, std::size_t tsid_count)
Definition: gtid_binary_format_conv.h:368
void decode_v0_v1(const Gtid_binary_format &format, Parser &parser, mysql::gtids::Is_gtid_set auto >id_set, std::size_t tsid_count)
Definition: gtid_binary_format_conv.h:345
void encode_v0_v1(const Gtid_binary_format &format, Is_string_target auto &string_target, const mysql::gtids::Is_gtid_set auto >id_set)
Definition: gtid_binary_format_conv.h:254
void encode_v2(const Gtid_binary_format &format, Is_string_target auto &string_target, const mysql::gtids::Is_gtid_set auto >id_set)
Definition: gtid_binary_format_conv.h:263
Definition: gtid_binary_format.h:41
void decode_impl(const Gtid_binary_format &format, Parser &parser, mysql::gtids::Is_gtid_set auto >id_set)
Definition: gtid_binary_format_conv.h:443
void decode_impl(const Gtid_binary_format &format, Parser &parser, mysql::gtids::Is_tag auto &tag)
Definition: gtid_binary_format_conv.h:63
void encode_impl(const Gtid_binary_format &format, Is_string_target auto &target, const mysql::gtids::Is_tag auto &tag)
Definition: gtid_binary_format_conv.h:48
Return_status
Simple, strongly-typed enumeration to indicate internal status: ok, error.
Definition: return_status.h:40
Return_t void_to_ok(const Func_t &func, Args_t &&...args)
Helper that calls the given function and returns its result, or returns Return_status::ok if the func...
Definition: return_status.h:113
constexpr decltype(auto) to_underlying(Enum_type enum_value)
Helper function that converts enum type to underlying integer type.
Definition: enumeration_utils.h:51
size_t size(const char *const c)
Definition: base64.h:46
required uint32 status
Definition: replication_asynchronous_connection_failover.proto:61
required uint64 version
Definition: replication_group_member_actions.proto:41
static const char digits[]
Definition: stacktrace.cc:644
int n
Definition: xcom_base.cc:509