Skip to content

Commit 656d11b

Browse files
committed
Avoid string formatting during gtid event data deserialization and string parsing when adding the gtid to a GtidSet
1 parent ebcafd2 commit 656d11b

File tree

9 files changed

+190
-49
lines changed

9 files changed

+190
-49
lines changed

src/main/java/com/github/shyiko/mysql/binlog/BinaryLogClient.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public X509Certificate[] getAcceptedIssuers() {
144144
private boolean gtidSetFallbackToPurged;
145145
private boolean gtidEnabled = false;
146146
private boolean useBinlogFilenamePositionInGtidMode;
147-
protected String gtid;
147+
protected Object gtid;
148148
private boolean tx;
149149

150150
private EventDeserializer eventDeserializer = new EventDeserializer();
@@ -1131,7 +1131,7 @@ protected void updateGtidSet(Event event) {
11311131
switch(eventHeader.getEventType()) {
11321132
case GTID:
11331133
GtidEventData gtidEventData = (GtidEventData) EventDataWrapper.internal(event.getData());
1134-
gtid = gtidEventData.getGtid();
1134+
gtid = gtidEventData.getMySqlGtid();
11351135
break;
11361136
case XID:
11371137
commitGtid();
@@ -1183,7 +1183,7 @@ protected void commitGtid(String sql) {
11831183
private void commitGtid() {
11841184
if (gtid != null) {
11851185
synchronized (gtidSetAccessLock) {
1186-
gtidSet.add(gtid);
1186+
gtidSet.addGtid(gtid);
11871187
}
11881188
}
11891189
}

src/main/java/com/github/shyiko/mysql/binlog/GtidSet.java

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,9 @@
1515
*/
1616
package com.github.shyiko.mysql.binlog;
1717

18-
import java.util.ArrayList;
19-
import java.util.Collection;
20-
import java.util.Collections;
21-
import java.util.Iterator;
22-
import java.util.LinkedHashMap;
23-
import java.util.List;
24-
import java.util.Map;
18+
import com.github.shyiko.mysql.binlog.event.MySqlGtid;
19+
20+
import java.util.*;
2521

2622
/**
2723
* GTID set as described in <a href="https://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html">GTID
@@ -38,7 +34,7 @@
3834
*/
3935
public class GtidSet {
4036

41-
private final Map<String, UUIDSet> map = new LinkedHashMap<String, UUIDSet>();
37+
private final Map<UUID, UUIDSet> map = new LinkedHashMap<UUID, UUIDSet>();
4238

4339
public static GtidSet parse(String gtidStr) {
4440
if ( MariadbGtidSet.isMariaGtidSet(gtidStr) ) {
@@ -55,7 +51,7 @@ public GtidSet(String gtidSet) {
5551
gtidSet.replace("\n", "").split(",");
5652
for (String uuidSet : uuidSets) {
5753
int uuidSeparatorIndex = uuidSet.indexOf(":");
58-
String sourceId = uuidSet.substring(0, uuidSeparatorIndex);
54+
UUID sourceId = UUID.fromString(uuidSet.substring(0, uuidSeparatorIndex));
5955
List<Interval> intervals = new ArrayList<Interval>();
6056
String[] rawIntervals = uuidSet.substring(uuidSeparatorIndex + 1).split(":");
6157
for (String interval : rawIntervals) {
@@ -87,7 +83,7 @@ public Collection<UUIDSet> getUUIDSets() {
8783
* @return the {@link UUIDSet} for the identified server, or {@code null} if there are no GTIDs from that server.
8884
*/
8985
public UUIDSet getUUIDSet(String uuid) {
90-
return map.get(uuid);
86+
return map.get(UUID.fromString(uuid));
9187
}
9288

9389
/**
@@ -97,22 +93,33 @@ public UUIDSet getUUIDSet(String uuid) {
9793
* or {@code null} if there are no UUIDSet for the given server.
9894
*/
9995
public UUIDSet putUUIDSet(UUIDSet uuidSet) {
100-
return map.put(uuidSet.getUUID(), uuidSet);
96+
return map.put(uuidSet.getServerId(), uuidSet);
10197
}
10298

10399
/**
104100
* @param gtid GTID ("source_id:transaction_id")
105101
* @return whether or not gtid was added to the set (false if it was already there)
106102
*/
107103
public boolean add(String gtid) {
108-
String[] split = gtid.split(":");
109-
String sourceId = split[0];
110-
long transactionId = Long.parseLong(split[1]);
111-
UUIDSet uuidSet = map.get(sourceId);
104+
return add(MySqlGtid.fromString(gtid));
105+
}
106+
107+
public void addGtid(Object gtid) {
108+
if (gtid instanceof MySqlGtid) {
109+
add((MySqlGtid) gtid);
110+
} else if (gtid instanceof String) {
111+
add((String) gtid);
112+
} else {
113+
throw new IllegalArgumentException(gtid + " not supported");
114+
}
115+
}
116+
117+
private boolean add(MySqlGtid mySqlGtid) {
118+
UUIDSet uuidSet = map.get(mySqlGtid.getServerId());
112119
if (uuidSet == null) {
113-
map.put(sourceId, uuidSet = new UUIDSet(sourceId, new ArrayList<Interval>()));
120+
map.put(mySqlGtid.getServerId(), uuidSet = new UUIDSet(mySqlGtid.getServerId(), new ArrayList<Interval>()));
114121
}
115-
return uuidSet.add(transactionId);
122+
return uuidSet.add(mySqlGtid.getTransactionId());
116123
}
117124

118125
/**
@@ -133,7 +140,7 @@ public boolean isContainedWithin(GtidSet other) {
133140
return true;
134141
}
135142
for (UUIDSet uuidSet : map.values()) {
136-
UUIDSet thatSet = other.getUUIDSet(uuidSet.getUUID());
143+
UUIDSet thatSet = other.map.get(uuidSet.getServerId());
137144
if (!uuidSet.isContainedWithin(thatSet)) {
138145
return false;
139146
}
@@ -162,7 +169,7 @@ public boolean equals(Object obj) {
162169
public String toString() {
163170
List<String> gtids = new ArrayList<String>();
164171
for (UUIDSet uuidSet : map.values()) {
165-
gtids.add(uuidSet.getUUID() + ":" + join(uuidSet.intervals, ":"));
172+
gtids.add(uuidSet.getServerId() + ":" + join(uuidSet.intervals, ":"));
166173
}
167174
return join(gtids, ",");
168175
}
@@ -188,10 +195,14 @@ private static String join(Collection<?> o, String delimiter) {
188195
*/
189196
public static final class UUIDSet {
190197

191-
private String uuid;
192-
private List<Interval> intervals;
198+
private final UUID uuid;
199+
private final List<Interval> intervals;
193200

194201
public UUIDSet(String uuid, List<Interval> intervals) {
202+
this(UUID.fromString(uuid), intervals);
203+
}
204+
205+
public UUIDSet(UUID uuid, List<Interval> intervals) {
195206
this.uuid = uuid;
196207
this.intervals = intervals;
197208
if (intervals.size() > 1) {
@@ -265,10 +276,16 @@ private int findInterval(long v) {
265276
* Get the UUID for the server that generated the GTIDs.
266277
* @return the server's UUID; never null
267278
*/
279+
@Deprecated
268280
public String getUUID() {
281+
return uuid.toString();
282+
}
283+
284+
public UUID getServerId() {
269285
return uuid;
270286
}
271287

288+
272289
/**
273290
* Get the intervals of transaction numbers.
274291
* @return the immutable transaction intervals; never null
@@ -288,7 +305,7 @@ public boolean isContainedWithin(UUIDSet other) {
288305
if (other == null) {
289306
return false;
290307
}
291-
if (!this.getUUID().equalsIgnoreCase(other.getUUID())) {
308+
if (!this.uuid.equals(other.uuid)) {
292309
// not even the same server ...
293310
return false;
294311
}
@@ -326,7 +343,7 @@ public boolean equals(Object obj) {
326343
}
327344
if (obj instanceof UUIDSet) {
328345
UUIDSet that = (UUIDSet) obj;
329-
return this.getUUID().equalsIgnoreCase(that.getUUID()) &&
346+
return this.uuid.equals(that.uuid) &&
330347
this.getIntervals().equals(that.getIntervals());
331348
}
332349
return super.equals(obj);

src/main/java/com/github/shyiko/mysql/binlog/MariadbGtidSet.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.github.shyiko.mysql.binlog;
22

3+
import com.github.shyiko.mysql.binlog.event.MySqlGtid;
4+
35
import java.util.*;
46
import java.util.regex.Pattern;
57

@@ -113,6 +115,16 @@ public boolean add(String gtid) {
113115
return true;
114116
}
115117

118+
public void addGtid(Object gtid) {
119+
if (gtid instanceof MariaGtid) {
120+
add((MariaGtid) gtid);
121+
} else if (gtid instanceof String) {
122+
add((String) gtid);
123+
} else {
124+
throw new IllegalArgumentException(gtid + " not supported");
125+
}
126+
}
127+
116128
public void add(MariaGtid gtid) {
117129
positionMap.put(gtid.getDomainId(), gtid);
118130
addToSeenSet(gtid);

src/main/java/com/github/shyiko/mysql/binlog/event/GtidEventData.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,37 @@ public class GtidEventData implements EventData {
2222

2323
public static final byte COMMIT_FLAG = 1;
2424

25-
private String gtid;
25+
private MySqlGtid gtid;
2626
private byte flags;
2727

28+
@Deprecated
29+
public GtidEventData() {
30+
}
31+
32+
public GtidEventData(MySqlGtid gtid, byte flags) {
33+
this.gtid = gtid;
34+
this.flags = flags;
35+
}
36+
37+
@Deprecated
2838
public String getGtid() {
29-
return gtid;
39+
return gtid.toString();
3040
}
3141

42+
@Deprecated
3243
public void setGtid(String gtid) {
33-
this.gtid = gtid;
44+
this.gtid = MySqlGtid.fromString(gtid);
45+
}
46+
47+
public MySqlGtid getMySqlGtid() {
48+
return gtid;
3449
}
3550

3651
public byte getFlags() {
3752
return flags;
3853
}
3954

55+
@Deprecated
4056
public void setFlags(byte flags) {
4157
this.flags = flags;
4258
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.github.shyiko.mysql.binlog.event;
2+
3+
import java.util.UUID;
4+
5+
public class MySqlGtid {
6+
private final UUID serverId;
7+
private final long transactionId;
8+
9+
public MySqlGtid(UUID serverId, long transactionId) {
10+
this.serverId = serverId;
11+
this.transactionId = transactionId;
12+
}
13+
14+
public static MySqlGtid fromString(String gtid) {
15+
String[] split = gtid.split(":");
16+
String sourceId = split[0];
17+
long transactionId = Long.parseLong(split[1]);
18+
return new MySqlGtid(UUID.fromString(sourceId), transactionId);
19+
}
20+
21+
@Override
22+
public String toString() {
23+
return serverId.toString()+":"+transactionId;
24+
}
25+
26+
public UUID getServerId() {
27+
return serverId;
28+
}
29+
30+
public long getTransactionId() {
31+
return transactionId;
32+
}
33+
}

src/main/java/com/github/shyiko/mysql/binlog/event/deserialization/GtidEventDataDeserializer.java

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
package com.github.shyiko.mysql.binlog.event.deserialization;
1717

1818
import com.github.shyiko.mysql.binlog.event.GtidEventData;
19+
import com.github.shyiko.mysql.binlog.event.MySqlGtid;
1920
import com.github.shyiko.mysql.binlog.io.ByteArrayInputStream;
2021
import java.io.IOException;
22+
import java.util.UUID;
2123

2224
/**
2325
* @author <a href="mailto:pprasse@actindo.de">Patrick Prasse</a>
@@ -26,27 +28,17 @@ public class GtidEventDataDeserializer implements EventDataDeserializer<GtidEven
2628

2729
@Override
2830
public GtidEventData deserialize(ByteArrayInputStream inputStream) throws IOException {
29-
GtidEventData eventData = new GtidEventData();
3031
byte flags = (byte) inputStream.readInteger(1);
31-
byte[] sid = inputStream.read(16);
32-
long gno = inputStream.readLong(8);
33-
eventData.setFlags(flags);
34-
eventData.setGtid(byteArrayToHex(sid, 0, 4) + "-" +
35-
byteArrayToHex(sid, 4, 2) + "-" +
36-
byteArrayToHex(sid, 6, 2) + "-" +
37-
byteArrayToHex(sid, 8, 2) + "-" +
38-
byteArrayToHex(sid, 10, 6) + ":" +
39-
String.format("%d", gno)
40-
);
41-
return eventData;
42-
}
32+
long sourceIdLeastSignificantBits = inputStream.readLong(8);
33+
long sourceIdMostSignificantBits = inputStream.readLong(8);
34+
long transactionId = inputStream.readLong(8);
4335

44-
private String byteArrayToHex(byte[] a, int offset, int len) {
45-
StringBuilder sb = new StringBuilder();
46-
for (int idx = offset; idx < (offset + len) && idx < a.length; idx++) {
47-
sb.append(String.format("%02x", a[idx] & 0xff));
48-
}
49-
return sb.toString();
36+
return new GtidEventData(
37+
new MySqlGtid(
38+
new UUID(sourceIdLeastSignificantBits, sourceIdMostSignificantBits),
39+
transactionId
40+
),
41+
flags
42+
);
5043
}
51-
5244
}

src/test/java/com/github/shyiko/mysql/binlog/GtidSetTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.github.shyiko.mysql.binlog.GtidSet.Interval;
1919
import com.github.shyiko.mysql.binlog.GtidSet.UUIDSet;
20+
import com.github.shyiko.mysql.binlog.event.MySqlGtid;
2021
import org.testng.annotations.Test;
2122

2223
import java.util.LinkedList;
@@ -164,5 +165,23 @@ public void testPutUUIDSet() {
164165
assertEquals(gtidSet, gtidSet2);
165166
}
166167

168+
@Test
169+
public void testAddStringGtid() {
170+
GtidSet gtidSet = new GtidSet("00000000-0000-0000-0000-000000000000:1");
171+
gtidSet.addGtid("00000000-0000-0000-0000-000000000000:2");
172+
assertEquals("00000000-0000-0000-0000-000000000000:1-2", gtidSet.toString());
173+
}
174+
175+
@Test
176+
public void testAddMySqlGtid() {
177+
GtidSet gtidSet = new GtidSet("00000000-0000-0000-0000-000000000000:1");
178+
gtidSet.addGtid(MySqlGtid.fromString("00000000-0000-0000-0000-000000000000:2"));
179+
assertEquals("00000000-0000-0000-0000-000000000000:1-2", gtidSet.toString());
180+
}
167181

182+
@Test(expectedExceptions = IllegalArgumentException.class)
183+
public void testAddAnotherObjectAsGtidFails() {
184+
GtidSet gtidSet = new GtidSet("");
185+
gtidSet.addGtid(MariadbGtidSet.MariaGtid.parse("1-2-3"));
186+
}
168187
}

src/test/java/com/github/shyiko/mysql/binlog/MariadbGtidSetTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.github.shyiko.mysql.binlog;
22

3+
import com.github.shyiko.mysql.binlog.MariadbGtidSet.MariaGtid;
4+
import com.github.shyiko.mysql.binlog.event.MySqlGtid;
35
import org.testng.annotations.Test;
46

57
import static org.junit.Assert.assertFalse;
@@ -43,4 +45,26 @@ public void testMatcher() {
4345
assertTrue(MariadbGtidSet.isMariaGtidSet("0-0-3323, 4-33-12342134, 444-33-13412341233"));
4446
assertFalse(MariadbGtidSet.isMariaGtidSet("07212070-4330-3bc8-8a3a-01e34be47bc3:1-141692942,a0c4a949-fae8-30f3-a4d2-fee56a1a9307:1-1427643460,a16ef643-1d4a-3fd9-a86e-1adeb836eb2d:1-1411988930,b0d822f4-5a84-30d3-a929-61f64740d7ac:1-59364"));
4547
}
48+
49+
@Test
50+
public void testAddStringGtid() {
51+
MariadbGtidSet gtidSet = new MariadbGtidSet();
52+
gtidSet.addGtid("1-2-3");
53+
assertEquals("1-2-3", gtidSet.toString());
54+
}
55+
56+
@Test
57+
public void testAddMariadbGtid() {
58+
MariadbGtidSet gtidSet = new MariadbGtidSet();
59+
gtidSet.addGtid(MariaGtid.parse("1-2-3"));
60+
assertEquals("1-2-3", gtidSet.toString());
61+
}
62+
63+
@Test(expectedExceptions = IllegalArgumentException.class)
64+
public void testAddAnotherObjectAsGtidFails() {
65+
MariadbGtidSet gtidSet = new MariadbGtidSet();
66+
gtidSet.addGtid(MySqlGtid.fromString("00000000-0000-0000-0000-000000000000:2"));
67+
}
68+
69+
4670
}

0 commit comments

Comments
 (0)