Skip to content

Commit

Permalink
[CONJ-1116] Avoid unnecessary synchronization on calendar when no cal…
Browse files Browse the repository at this point in the history
…endar parameter
  • Loading branch information
rusher committed Oct 23, 2023
1 parent 0292136 commit 10a1107
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 42 deletions.
35 changes: 29 additions & 6 deletions src/main/java/org/mariadb/jdbc/client/column/DateColumn.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,22 @@ public Date decodeDateText(ReadableByteBuf buf, MutableInt length, Calendar cal)
return null;
}

Calendar c = cal == null ? Calendar.getInstance() : cal;
synchronized (c) {
if (cal == null) {
Calendar c = Calendar.getInstance();
c.clear();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month - 1);
c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
return new Date(c.getTimeInMillis());
} else {
synchronized (cal) {
cal.clear();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month - 1);
cal.set(Calendar.DAY_OF_MONTH, dayOfMonth);
return new Date(cal.getTimeInMillis());
}

}
}

Expand All @@ -205,13 +214,21 @@ public Date decodeDateBinary(ReadableByteBuf buf, MutableInt length, Calendar ca
return null;
}

Calendar c = cal == null ? Calendar.getInstance() : cal;
synchronized (c) {
if (cal == null) {
Calendar c = Calendar.getInstance();
c.clear();
c.set(Calendar.YEAR, buf.readShort());
c.set(Calendar.MONTH, buf.readByte() - 1);
c.set(Calendar.DAY_OF_MONTH, buf.readByte());
return new Date(c.getTimeInMillis());
} else {
synchronized (cal) {
cal.clear();
cal.set(Calendar.YEAR, buf.readShort());
cal.set(Calendar.MONTH, buf.readByte() - 1);
cal.set(Calendar.DAY_OF_MONTH, buf.readByte());
return new Date(cal.getTimeInMillis());
}
}
}

Expand Down Expand Up @@ -260,7 +277,6 @@ public Timestamp decodeTimestampBinary(ReadableByteBuf buf, MutableInt length, C
return null;
}

Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
int year;
int month;
long dayOfMonth;
Expand All @@ -275,10 +291,17 @@ public Timestamp decodeTimestampBinary(ReadableByteBuf buf, MutableInt length, C
}

Timestamp timestamp;
synchronized (cal) {
if (calParam == null) {
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(year, month - 1, (int) dayOfMonth, 0, 0, 0);
timestamp = new Timestamp(cal.getTimeInMillis());
} else {
synchronized (calParam) {
calParam.clear();
calParam.set(year, month - 1, (int) dayOfMonth, 0, 0, 0);
timestamp = new Timestamp(calParam.getTimeInMillis());
}
}
timestamp.setNanos(0);
return timestamp;
Expand Down
60 changes: 45 additions & 15 deletions src/main/java/org/mariadb/jdbc/client/column/StringColumn.java
Original file line number Diff line number Diff line change
Expand Up @@ -259,13 +259,21 @@ public Date decodeDateText(ReadableByteBuf buf, MutableInt length, Calendar cal)
int year = Integer.parseInt(stDatePart[0]);
int month = Integer.parseInt(stDatePart[1]);
int dayOfMonth = Integer.parseInt(stDatePart[2]);
Calendar c = cal == null ? Calendar.getInstance() : cal;
synchronized (c) {
if (cal == null) {
Calendar c = Calendar.getInstance();
c.clear();
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month - 1);
c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
return new Date(c.getTimeInMillis());
} else {
synchronized (cal) {
cal.clear();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month - 1);
cal.set(Calendar.DAY_OF_MONTH, dayOfMonth);
return new Date(cal.getTimeInMillis());
}
}

} catch (NumberFormatException nfe) {
Expand Down Expand Up @@ -296,27 +304,45 @@ public Time decodeTimeText(ReadableByteBuf buf, MutableInt length, Calendar cal)
@Override
public Time decodeTimeBinary(ReadableByteBuf buf, MutableInt length, Calendar calParam)
throws SQLDataException {
Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
int[] parts = LocalTimeCodec.parseTime(buf, length, this);
Time t;

// specific case for TIME, to handle value not in 00:00:00-23:59:59
synchronized (cal) {
if (calParam == null) {
Calendar cal = Calendar.getInstance();
cal.clear();
cal.setLenient(true);
if (parts[0] == -1) {
cal.set(
1970,
Calendar.JANUARY,
1,
parts[0] * parts[1],
parts[0] * parts[2],
parts[0] * parts[3] - 1);
1970,
Calendar.JANUARY,
1,
parts[0] * parts[1],
parts[0] * parts[2],
parts[0] * parts[3] - 1);
t = new Time(cal.getTimeInMillis() + (1000 - parts[4]));
} else {
cal.set(1970, Calendar.JANUARY, 1, parts[1], parts[2], parts[3]);
t = new Time(cal.getTimeInMillis() + parts[4] / 1_000_000);
}
} else {
synchronized (calParam) {
calParam.clear();
calParam.setLenient(true);
if (parts[0] == -1) {
calParam.set(
1970,
Calendar.JANUARY,
1,
parts[0] * parts[1],
parts[0] * parts[2],
parts[0] * parts[3] - 1);
t = new Time(calParam.getTimeInMillis() + (1000 - parts[4]));
} else {
calParam.set(1970, Calendar.JANUARY, 1, parts[1], parts[2], parts[3]);
t = new Time(calParam.getTimeInMillis() + parts[4] / 1_000_000);
}
}
}
return t;
}
Expand Down Expand Up @@ -378,7 +404,6 @@ public Timestamp decodeTimestampText(ReadableByteBuf buf, MutableInt length, Cal
timestampsPart[4],
timestampsPart[5]);
timestamp = new Timestamp(c.getTime().getTime());
timestamp.setNanos(timestampsPart[6] * 1000);
} else {
synchronized (calParam) {
calParam.clear();
Expand All @@ -390,17 +415,15 @@ public Timestamp decodeTimestampText(ReadableByteBuf buf, MutableInt length, Cal
timestampsPart[4],
timestampsPart[5]);
timestamp = new Timestamp(calParam.getTime().getTime());
timestamp.setNanos(timestampsPart[6] * 1000);
}
}
timestamp.setNanos(timestampsPart[6] * 1000);
return timestamp;
}

@Override
public Timestamp decodeTimestampBinary(ReadableByteBuf buf, MutableInt length, Calendar calParam)
throws SQLDataException {
Calendar cal = calParam == null ? Calendar.getInstance() : calParam;

String val = buf.readString(length.get());
try {
int[] parts = LocalDateTimeCodec.parseTimestamp(val);
Expand All @@ -416,10 +439,17 @@ public Timestamp decodeTimestampBinary(ReadableByteBuf buf, MutableInt length, C
int seconds = parts[5];
int microseconds = parts[6] / 1000;
Timestamp timestamp;
synchronized (cal) {
if (calParam == null) {
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(year, month - 1, dayOfMonth, hour, minutes, seconds);
timestamp = new Timestamp(cal.getTimeInMillis());
} else {
synchronized (calParam) {
calParam.clear();
calParam.set(year, month - 1, dayOfMonth, hour, minutes, seconds);
timestamp = new Timestamp(calParam.getTimeInMillis());
}
}
timestamp.setNanos(microseconds * 1000);
return timestamp;
Expand Down
24 changes: 22 additions & 2 deletions src/main/java/org/mariadb/jdbc/client/column/TimeColumn.java
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,8 @@ public Timestamp decodeTimestampText(ReadableByteBuf buf, MutableInt length, Cal
Timestamp t;

// specific case for TIME, to handle value not in 00:00:00-23:59:59
Calendar cal = calParam == null ? Calendar.getInstance() : calParam;
synchronized (cal) {
if (calParam == null) {
Calendar cal = Calendar.getInstance();
cal.clear();
cal.setLenient(true);
if (parts[0] == -1) {
Expand All @@ -335,6 +335,26 @@ public Timestamp decodeTimestampText(ReadableByteBuf buf, MutableInt length, Cal
t = new Timestamp(cal.getTimeInMillis());
t.setNanos(parts[4]);
}
} else {
synchronized (calParam) {
calParam.clear();
calParam.setLenient(true);
if (parts[0] == -1) {
calParam.set(
1970,
Calendar.JANUARY,
1,
parts[0] * parts[1],
parts[0] * parts[2],
parts[0] * parts[3] - 1);
t = new Timestamp(calParam.getTimeInMillis());
t.setNanos(1_000_000_000 - parts[4]);
} else {
calParam.set(1970, Calendar.JANUARY, 1, parts[1], parts[2], parts[3]);
t = new Timestamp(calParam.getTimeInMillis());
t.setNanos(parts[4]);
}
}
}
return t;
}
Expand Down
31 changes: 24 additions & 7 deletions src/main/java/org/mariadb/jdbc/client/column/TimestampColumn.java
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,6 @@ public Date decodeDateText(ReadableByteBuf buf, MutableInt length, Calendar cal)
@Override
public Date decodeDateBinary(ReadableByteBuf buf, MutableInt length, Calendar calParam)
throws SQLDataException {
Calendar cal = calParam == null ? Calendar.getInstance() : calParam;

if (length.get() == 0) {
length.set(NULL_LENGTH);
return null;
Expand Down Expand Up @@ -333,10 +331,17 @@ public Date decodeDateBinary(ReadableByteBuf buf, MutableInt length, Calendar ca
}

Timestamp timestamp;
synchronized (cal) {
if (calParam == null) {
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(year, month - 1, dayOfMonth, hour, minutes, seconds);
timestamp = new Timestamp(cal.getTimeInMillis());
} else {
synchronized (calParam) {
calParam.clear();
calParam.set(year, month - 1, dayOfMonth, hour, minutes, seconds);
timestamp = new Timestamp(calParam.getTimeInMillis());
}
}
timestamp.setNanos((int) (microseconds * 1000));
String st = timestamp.toString();
Expand All @@ -361,7 +366,6 @@ public Time decodeTimeBinary(ReadableByteBuf buf, MutableInt length, Calendar ca
length.set(NULL_LENGTH);
return null;
}
Calendar cal = calParam == null ? Calendar.getInstance() : calParam;

int year = buf.readUnsignedShort();
int month = buf.readByte();
Expand All @@ -387,10 +391,17 @@ public Time decodeTimeBinary(ReadableByteBuf buf, MutableInt length, Calendar ca
return null;
}

synchronized (cal) {
if (calParam == null) {
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(1970, Calendar.JANUARY, 1, hour, minutes, seconds);
return new Time(cal.getTimeInMillis() + microseconds / 1_000);
} else {
synchronized (calParam) {
calParam.clear();
calParam.set(1970, Calendar.JANUARY, 1, hour, minutes, seconds);
return new Time(calParam.getTimeInMillis() + microseconds / 1_000);
}
}
}

Expand Down Expand Up @@ -476,7 +487,6 @@ public Timestamp decodeTimestampBinary(ReadableByteBuf buf, MutableInt length, C
length.set(NULL_LENGTH);
return null;
}
Calendar cal = calParam == null ? Calendar.getInstance() : calParam;

int year = buf.readUnsignedShort();
int month = buf.readByte();
Expand Down Expand Up @@ -508,10 +518,17 @@ public Timestamp decodeTimestampBinary(ReadableByteBuf buf, MutableInt length, C
return null;
}
Timestamp timestamp;
synchronized (cal) {
if (calParam == null) {
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(year, month - 1, dayOfMonth, hour, minutes, seconds);
timestamp = new Timestamp(cal.getTimeInMillis());
} else {
synchronized (calParam) {
calParam.clear();
calParam.set(year, month - 1, dayOfMonth, hour, minutes, seconds);
timestamp = new Timestamp(calParam.getTimeInMillis());
}
}
timestamp.setNanos((int) (microseconds * 1000));
return timestamp;
Expand Down
23 changes: 17 additions & 6 deletions src/main/java/org/mariadb/jdbc/client/column/YearColumn.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,30 +121,41 @@ public Date decodeDateBinary(ReadableByteBuf buf, MutableInt length, Calendar ca
@Override
public Timestamp decodeTimestampText(ReadableByteBuf buf, MutableInt length, Calendar calParam)
throws SQLDataException {
Calendar cal1 = calParam == null ? Calendar.getInstance() : calParam;

int year = Integer.parseInt(buf.readAscii(length.get()));
if (columnLength <= 2) year += year >= 70 ? 1900 : 2000;
synchronized (cal1) {

if (calParam == null) {
Calendar cal1 = Calendar.getInstance();
cal1.clear();
cal1.set(year, Calendar.JANUARY, 1);
return new Timestamp(cal1.getTimeInMillis());
} else {
synchronized (calParam) {
calParam.clear();
calParam.set(year, Calendar.JANUARY, 1);
return new Timestamp(calParam.getTimeInMillis());
}
}
}

@Override
public Timestamp decodeTimestampBinary(ReadableByteBuf buf, MutableInt length, Calendar calParam)
throws SQLDataException {
Calendar cal = calParam == null ? Calendar.getInstance() : calParam;

int year = buf.readUnsignedShort();
if (columnLength <= 2) year += year >= 70 ? 1900 : 2000;

Timestamp timestamp;
synchronized (cal) {
if (calParam == null) {
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(year, 0, 1, 0, 0, 0);
timestamp = new Timestamp(cal.getTimeInMillis());
} else {
synchronized (calParam) {
calParam.clear();
calParam.set(year, 0, 1, 0, 0, 0);
timestamp = new Timestamp(calParam.getTimeInMillis());
}
}
timestamp.setNanos(0);
return timestamp;
Expand Down
13 changes: 11 additions & 2 deletions src/main/java/org/mariadb/jdbc/plugin/codec/DateCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,23 @@ public void encodeText(
@Override
public void encodeBinary(Writer encoder, Object value, Calendar providedCal, Long maxLength)
throws IOException {
Calendar cal = providedCal == null ? Calendar.getInstance() : providedCal;
synchronized (cal) {
if (providedCal == null) {
Calendar cal = Calendar.getInstance();
cal.clear();
cal.setTimeInMillis(((java.util.Date) value).getTime());
encoder.writeByte(4); // length
encoder.writeShort((short) cal.get(Calendar.YEAR));
encoder.writeByte(((cal.get(Calendar.MONTH) + 1) & 0xff));
encoder.writeByte((cal.get(Calendar.DAY_OF_MONTH) & 0xff));
} else {
synchronized (providedCal) {
providedCal.clear();
providedCal.setTimeInMillis(((java.util.Date) value).getTime());
encoder.writeByte(4); // length
encoder.writeShort((short) providedCal.get(Calendar.YEAR));
encoder.writeByte(((providedCal.get(Calendar.MONTH) + 1) & 0xff));
encoder.writeByte((providedCal.get(Calendar.DAY_OF_MONTH) & 0xff));
}
}
}

Expand Down

0 comments on commit 10a1107

Please sign in to comment.