@@ -269,7 +269,7 @@ bool GTID_Server_Data::gtid_exists(char *gtid_uuid, uint64_t gtid_trxid) {
269269 return false ;
270270 }
271271 for (auto itr = it->second .begin (); itr != it->second .end (); ++itr) {
272- if (( int64_t )gtid_trxid >= itr->first && ( int64_t )gtid_trxid <= itr-> second ) {
272+ if (itr->contains (( int64_t )gtid_trxid) ) {
273273// fprintf(stderr,"YES\n");
274274 return true ;
275275 }
@@ -412,12 +412,7 @@ std::string gtid_executed_to_string(gtid_set_t& gtid_executed) {
412412 s.insert (23 ," -" );
413413 s = s + " :" ;
414414 for (auto itr = it->second .begin (); itr != it->second .end (); ++itr) {
415- std::string s2 = s;
416- s2 = s2 + std::to_string (itr->first );
417- s2 = s2 + " -" ;
418- s2 = s2 + std::to_string (itr->second );
419- s2 = s2 + " ," ;
420- gtid_set = gtid_set + s2;
415+ gtid_set += s + itr->to_string () + " ," ;
421416 }
422417 }
423418 // Extract latest comma only in case 'gtid_executed' isn't empty
@@ -428,52 +423,52 @@ std::string gtid_executed_to_string(gtid_set_t& gtid_executed) {
428423}
429424
430425
431-
432- void addGtid (const gtid_t & gtid, gtid_set_t & gtid_executed) {
433- auto it = gtid_executed.find (gtid.first );
434- if (it == gtid_executed.end ())
435- {
436- gtid_executed[gtid.first ].emplace_back (gtid.second , gtid.second );
437- return ;
426+ // Merges a GTID interval into a GTID set instance.
427+ // Returns true if the GTID set was modified, false otherwise.
428+ bool addGtid (const std::string& uuid, const gtid_interval_t &iv, gtid_set_t & gtid_executed) {
429+ auto it = gtid_executed.find (uuid);
430+ if (it == gtid_executed.end ()) {
431+ // new UUID entry
432+ gtid_executed[uuid].emplace_back (iv);
433+ return true ;
438434 }
439435
440- bool flag = true ;
441- for (auto itr = it->second .begin (); itr != it->second .end (); ++itr)
442- {
443- if (gtid.second >= itr->first && gtid.second <= itr->second )
444- return ;
445- if (gtid.second + 1 == itr->first )
446- {
447- --itr->first ;
448- flag = false ;
449- break ;
436+ // insert/merge GTID interval
437+ auto pos = it->second .begin ();
438+ for (; pos != it->second .end (); ++pos) {
439+ if (pos->contains (iv)) {
440+ // nothing to do
441+ return false ;
450442 }
451- else if (gtid.second == itr->second + 1 )
452- {
453- ++itr->second ;
454- flag = false ;
443+ if (pos->merge (iv))
455444 break ;
456- }
457- else if (gtid.second < itr->first )
458- {
459- it->second .emplace (itr, gtid.second , gtid.second );
460- return ;
461- }
445+ }
446+ if (pos == it->second .end ()) {
447+ it->second .emplace_back (iv);
462448 }
463449
464- if (flag)
465- it->second .emplace_back (gtid.second , gtid.second );
466-
467- for (auto itr = it->second .begin (); itr != it->second .end (); ++itr)
468- {
469- auto next_itr = std::next (itr);
470- if (next_itr != it->second .end () && itr->second + 1 == next_itr->first )
471- {
472- itr->second = next_itr->second ;
473- it->second .erase (next_itr);
450+ // merge overlapping GTID ranges, if any
451+ it->second .sort ();
452+ auto a = it->second .begin ();
453+ while (a != it->second .end ()) {
454+ auto b = std::next (a);
455+ if (b == it->second .end ()) {
474456 break ;
475457 }
458+ if (a->merge (*b)) {
459+ it->second .erase (b);
460+ continue ;
461+ }
462+ a++;
476463 }
464+
465+ return true ;
466+ }
467+
468+ // Merges a single GTID into a gitd_executed instance.
469+ inline bool addGtid (const gtid_t & gtid, gtid_set_t & gtid_executed) {
470+ gtid_interval_t iv = Gtid_Interval (gtid.second , gtid.second );
471+ return addGtid (gtid.first , iv, gtid_executed);
477472}
478473
479474/* *
@@ -499,41 +494,9 @@ void addGtid(const gtid_t& gtid, gtid_set_t& gtid_executed) {
499494 * @note This function is critical for maintaining accurate GTID metrics across
500495 * binlog reader reconnections and preventing events_count resets.
501496 */
502- bool addGtidInterval (gtid_set_t & gtid_executed, std::string server_uuid, int64_t txid_start, int64_t txid_end) {
503- bool updated = true ;
504-
505- auto it = gtid_executed.find (server_uuid);
506- if (it == gtid_executed.end ()) {
507- gtid_executed[server_uuid].emplace_back (txid_start, txid_end);
508- return updated;
509- }
510-
511- bool insert = true ;
512-
513- // When ProxySQL reconnects with binlog reader, it might
514- // receive updated txid intervals in the bootstrap message.
515- // For example,
516- // before disconnection -> server_UUID:1-10
517- // after reconnection -> server_UUID:1-19
518- auto &txid_intervals = it->second ;
519- for (auto &interval : txid_intervals) {
520- if (interval.first == txid_start) {
521- if (interval.second == txid_end) {
522- updated = false ;
523- } else {
524- interval.second = txid_end;
525- }
526- insert = false ;
527- break ;
528- }
529- }
530-
531- if (insert) {
532- txid_intervals.emplace_back (txid_start, txid_end);
533-
534- }
535-
536- return updated;
497+ inline bool addGtidInterval (gtid_set_t & gtid_executed, std::string server_uuid, int64_t txid_start, int64_t txid_end) {
498+ gtid_interval_t iv = Gtid_Interval (txid_start, txid_end);
499+ return addGtid (server_uuid, iv, gtid_executed);
537500}
538501
539502void * GTID_syncer_run () {
0 commit comments