1 /*
2 * Copyright (C) 2015-2017 Codership Oy <info@codership.com>
3 */
4
5 #ifndef _gu_gtid_hpp_
6 #define _gu_gtid_hpp_
7
8 #include "gu_uuid.hpp"
9 #include "gu_serialize.hpp"
10
11 #include "gu_hash.h"
12 #include <stdint.h>
13
14 namespace gu
15 {
16 class GTID;
17
18 typedef int64_t seqno_t;
19 } /* namespace gu */
20
21 class gu::GTID
22 {
23 public:
24
25 static seqno_t const SEQNO_UNDEFINED = -1;
26
GTID()27 GTID() : uuid_(), seqno_(SEQNO_UNDEFINED) {}
28
GTID(const UUID & u,seqno_t s)29 GTID(const UUID& u, seqno_t s) : uuid_(u), seqno_(s) {}
30
GTID(const gu_uuid_t & u,seqno_t s)31 GTID(const gu_uuid_t& u, seqno_t s) : uuid_(u), seqno_(s) {}
32
GTID(const GTID & g)33 GTID(const GTID& g) : uuid_(g.uuid_), seqno_(g.seqno_) {}
34
GTID(const void * const buf,size_t const buflen)35 GTID(const void* const buf, size_t const buflen)
36 :
37 uuid_ (),
38 seqno_(SEQNO_UNDEFINED)
39 {
40 (void) unserialize(buf, buflen, 0);
41 }
42
43 // this constuftor modifies offset
GTID(const void * const buf,size_t const buflen,size_t & offset)44 GTID(const void* const buf, size_t const buflen, size_t& offset)
45 :
46 uuid_ (),
47 seqno_(SEQNO_UNDEFINED)
48 {
49 offset = unserialize(buf, buflen, offset);
50 }
51
52 GTID& operator=(const GTID& other) = default;
53
uuid() const54 const UUID& uuid() const { return uuid_; }
seqno() const55 seqno_t seqno() const { return seqno_; }
56
set(const gu::UUID & u)57 void set(const gu::UUID& u) { uuid_ = u; }
set(seqno_t const s)58 void set(seqno_t const s) { seqno_ = s; }
59
set(const gu::UUID & u,seqno_t const s)60 void set(const gu::UUID& u, seqno_t const s) { set(u); set(s); }
61
operator ==(const GTID & other) const62 bool operator==(const GTID& other) const
63 {
64 return (seqno_ == other.seqno_ && uuid_ == other.uuid_);
65 }
66
operator !=(const GTID & other) const67 bool operator!=(const GTID& other) const { return !(*this == other); }
68
is_undefined() const69 bool is_undefined() const
70 {
71 static GTID undefined;
72 return *this == undefined;
73 }
74
75 void print(std::ostream& os) const;
76
77 void scan(std::istream& is);
78
serial_size()79 static size_t serial_size() { return UUID::serial_size() +sizeof(int64_t); }
80
serialize(void * const buf,size_t offset) const81 size_t serialize(void* const buf, size_t offset) const
82 {
83 assert(serial_size() == (uuid_.serial_size() + sizeof(int64_t)));
84
85 offset = uuid_.serialize(buf, offset);
86 offset = gu::serialize8(seqno_, buf, offset);
87
88 return offset;
89 }
90
unserialize(const void * const buf,size_t offset)91 size_t unserialize(const void* const buf, size_t offset)
92 {
93 assert(serial_size() == (uuid_.serial_size() + sizeof(seqno_)));
94
95 offset = uuid_.unserialize(buf, offset);
96 offset = gu::unserialize8(buf, offset, seqno_);
97
98 return offset;
99 }
100
unserialize(const void * const buf,const size_t buflen,const size_t offset)101 size_t unserialize(const void* const buf, const size_t buflen,
102 const size_t offset)
103 {
104 gu_trace(gu::check_bounds(offset + serial_size(), buflen));
105 return unserialize(buf, offset);
106 }
107
serialize(void * const buf,const size_t buflen,const size_t offset) const108 size_t serialize (void* const buf, const size_t buflen,
109 const size_t offset) const
110 {
111 gu_trace(gu::check_bounds(offset + serial_size(), buflen));
112 return serialize(buf, offset);
113 }
114
115 class TableHash // for std::map, does not have to be endian independent
116 {
117 public:
operator ()(const GTID & gtid) const118 size_t operator()(const GTID& gtid) const
119 {
120 // UUID is 16 bytes and seqno_t is 8 bytes so all should be
121 // properly aligned into a continuous buffer
122 return gu_table_hash(>id, sizeof(UUID) + sizeof(seqno_t));
123 }
124 };
125
126 private:
127
128 UUID uuid_;
129 seqno_t seqno_;
130
131 }; /* class GTID */
132
133 namespace gu
134 {
operator <<(std::ostream & os,const GTID & gtid)135 inline std::ostream& operator<< (std::ostream& os, const GTID& gtid)
136 {
137 gtid.print(os); return os;
138 }
139
operator >>(std::istream & is,GTID & gtid)140 inline std::istream& operator>> (std::istream& is, GTID& gtid)
141 {
142 gtid.scan(is); return is;
143 }
144 } /* namespace gu */
145
146 #endif /* _gu_gtid_hpp_ */
147