Mercurial > hg > monetdb-java
changeset 316:d479475888e3
Replace StringBuilder methods sb.delete(0, sb.length()) with faster sb.setLength(0).
In MonetBlob create(hexString) optimized the conversion by eliminating the creation of many 2 char substrings.
Small enhancements and optimizations and added/updated comments.
author | Martin van Dinther <martin.van.dinther@monetdbsolutions.com> |
---|---|
date | Thu, 29 Aug 2019 20:22:10 +0200 (2019-08-29) |
parents | 4793f9b80bb3 |
children | b80d92601b4b |
files | src/main/java/nl/cwi/monetdb/client/JdbcClient.java src/main/java/nl/cwi/monetdb/jdbc/MonetBlob.java src/main/java/nl/cwi/monetdb/jdbc/MonetClob.java src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java src/main/java/nl/cwi/monetdb/mcl/parser/TupleLineParser.java tests/Test_Clargequery.java |
diffstat | 6 files changed, 51 insertions(+), 52 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/nl/cwi/monetdb/client/JdbcClient.java +++ b/src/main/java/nl/cwi/monetdb/client/JdbcClient.java @@ -878,7 +878,7 @@ public final class JdbcClient { * @throws IOException if an IO exception occurs. */ public static void processBatch(final int batchSize) throws IOException { - final StringBuilder query = new StringBuilder(); + final StringBuilder query = new StringBuilder(2048); int i = 0; try { String curLine; @@ -889,7 +889,7 @@ public final class JdbcClient { // lousy check for end of statement, but in batch mode it // is not very important to catch all end of statements... stmt.addBatch(query.toString()); - query.delete(0, query.length()); + query.setLength(0); // clear the buffer } else { query.append('\n'); }
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetBlob.java +++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetBlob.java @@ -34,20 +34,20 @@ public final class MonetBlob implements buf = data; } - final static MonetBlob create(final String in) { + static final MonetBlob create(final String hexString) { // unpack the HEX (BLOB) notation to real bytes - final int len = in.length() / 2; + final int len = hexString.length() / 2; final byte[] buf = new byte[len]; - int offset; for (int i = 0; i < len; i++) { - offset = 2 * i; - buf[i] = (byte)Integer.parseInt(in.substring(offset, offset + 2), 16); +// was buf[i] = (byte)Integer.parseInt(hexString.substring(2 * i, (2 * i) + 2), 16); + buf[i] = (byte) ((Character.digit(hexString.charAt(2 * i), 16) << 4) + + Character.digit(hexString.charAt((2 * i) +1), 16)); } return new MonetBlob(buf); } /* internal utility method */ - final private void checkBufIsNotNull() throws SQLException { + private final void checkBufIsNotNull() throws SQLException { if (buf == null) throw new SQLException("This MonetBlob has been freed", "M1M20"); } @@ -106,7 +106,6 @@ public final class MonetBlob implements if (length < 0 || pos - 1 + length > buf.length) { throw new SQLException("Invalid length value: " + length, "M1M05"); } - return new ByteArrayInputStream(buf, (int) pos - 1, (int) length); } @@ -196,14 +195,15 @@ public final class MonetBlob implements } try { final int patternLength = pattern.length; - final int bufLength = buf.length; - for (int i = (int)(start - 1); i < bufLength - patternLength; i++) { + final int maxPos = buf.length - patternLength; + for (int i = (int)(start - 1); i < maxPos; i++) { int j; for (j = 0; j < patternLength; j++) { if (buf[i + j] != pattern[j]) break; } if (j == patternLength) + // found a match return i; } } catch (IndexOutOfBoundsException e) { @@ -248,11 +248,9 @@ public final class MonetBlob implements */ @Override public int setBytes(final long pos, final byte[] bytes) throws SQLException { - if (bytes == null) { - throw new SQLException("Missing bytes[] object", "M1M05"); - } - // buf and input argument pos will be checked in method setBytes(long, byte{}, int, int) - return setBytes(pos, bytes, 1, bytes.length); + // buf and input arguments will be checked in method setBytes(long, byte{}, int, int) + final int len = (bytes != null) ? bytes.length : 0; + return setBytes(pos, bytes, 1, len); } /** @@ -272,14 +270,14 @@ public final class MonetBlob implements * BLOB value or if pos is less than 1 */ @Override - public int setBytes(final long pos, final byte[] bytes, final int offset, final int len) + public int setBytes(final long pos, final byte[] bytes, int offset, final int len) throws SQLException { checkBufIsNotNull(); if (bytes == null) { throw new SQLException("Missing bytes[] object", "M1M05"); } - if (pos < 1 || pos > Integer.MAX_VALUE) { + if (pos < 1 || pos > buf.length) { throw new SQLException("Invalid pos value: " + pos, "M1M05"); } if (len < 0 || pos + len > buf.length) { @@ -290,9 +288,10 @@ public final class MonetBlob implements } try { + offset--; /* transactions? what are you talking about? */ for (int i = (int)pos; i < len; i++) - buf[i] = bytes[offset - 1 + i]; + buf[i] = bytes[offset + i]; } catch (IndexOutOfBoundsException e) { throw new SQLException(e.getMessage(), "M0M10"); } @@ -314,10 +313,7 @@ public final class MonetBlob implements throw new SQLException("Invalid len value: " + len, "M1M05"); } if (buf.length > len) { - final byte[] newbuf = new byte[(int)len]; - for (int i = 0; i < len; i++) - newbuf[i] = buf[i]; - buf = newbuf; + buf = java.util.Arrays.copyOf(buf, (int)len); } } }
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetClob.java +++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetClob.java @@ -35,7 +35,7 @@ public final class MonetClob implements } /* internal utility method */ - final private void checkBufIsNotNull() throws SQLException { + private final void checkBufIsNotNull() throws SQLException { if (buf == null) throw new SQLException("This MonetClob has been freed", "M1M20"); } @@ -98,10 +98,11 @@ public final class MonetClob implements */ @Override public Reader getCharacterStream(final long pos, final long length) throws SQLException { - // buf and input argument pos will be checked in method getSubString(long, int) + // as length will be casted to int, check it for too big value first if (length < 0 || length > Integer.MAX_VALUE) { throw new SQLException("Invalid length value: " + length, "M1M05"); } + // buf and input argument pos will be checked in method getSubString(long, int) return new StringReader(getSubString(pos, (int)length)); } @@ -164,10 +165,10 @@ public final class MonetClob implements */ @Override public long position(final Clob searchstr, final long start) throws SQLException { - // buf and input argument start will be checked in method position(String, long) if (searchstr == null) { throw new SQLException("Missing searchstr object", "M1M05"); } + // buf and input argument start will be checked in method position(String, long) return position(searchstr.toString(), start); } @@ -250,11 +251,9 @@ public final class MonetClob implements */ @Override public int setString(final long pos, final String str) throws SQLException { - // buf will be checked in method setString(long, String, int, int) - if (str == null) { - throw new SQLException("Missing str object", "M1M05"); - } - return setString(pos, str, 0, str.length()); + // buf and input arguments will be checked in method setString(long, String, int, int) + final int len = (str != null) ? str.length() : 0; + return setString(pos, str, 0, len); } /** @@ -287,12 +286,11 @@ public final class MonetClob implements if (len < 1 || (offset + len) > str.length()) { throw new SQLException("Invalid len value: " + len, "M1M05"); } - - final int ipos = (int) pos; - if ((ipos + len) > buf.capacity()) { - buf.ensureCapacity(ipos + len); + if (((int) pos + len) > buf.capacity()) { + // enlarge the buffer before filling it + buf.ensureCapacity((int) pos + len); } - buf.replace(ipos - 1, ipos + len, str.substring(offset, (offset + len))); + buf.replace((int) pos - 1, (int) pos + len, str.substring(offset, (offset + len))); return len; } @@ -310,8 +308,8 @@ public final class MonetClob implements if (len < 0 || len > buf.length()) { throw new SQLException("Invalid len value: " + len, "M1M05"); } - buf.delete((int)len, buf.length()); - // Attempts to reduce storage used for the character sequence. + buf.setLength((int)len); + // reduce storage used for the character sequence. buf.trimToSize(); } @@ -321,7 +319,9 @@ public final class MonetClob implements * * @return the String this MonetClob wraps or empty string when this MonetClob was freed. */ - final public String toString() { - return (buf != null) ? buf.toString() : ""; + public String toString() { + if (buf == null) + return ""; + return buf.toString(); } }
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java +++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetStatement.java @@ -228,7 +228,7 @@ public class MonetStatement // send and receive error |= internalBatch(tmpBatch, counts, offset, i + 1, e); offset = i; - tmpBatch.delete(0, tmpBatch.length()); + tmpBatch.setLength(0); // clear the buffer first = true; continue; } @@ -236,7 +236,7 @@ public class MonetStatement // send and receive error |= internalBatch(tmpBatch, counts, offset, i + 1, e); offset = i; - tmpBatch.delete(0, tmpBatch.length()); + tmpBatch.setLength(0); // clear the buffer first = true; } if (first) @@ -267,16 +267,16 @@ public class MonetStatement throws BatchUpdateException { try { - boolean type = internalExecute(batch.toString()); + boolean hasResultSet = internalExecute(batch.toString()); int count = -1; - if (!type) + if (!hasResultSet) count = getUpdateCount(); do { if (offset >= max) throw new SQLException("Overflow: don't use multi statements when batching (" + max + ")", "M1M16"); - if (type) { + if (hasResultSet) { e.setNextException( new SQLException("Batch query produced a ResultSet! " + "Ignoring and setting update count to " + @@ -286,7 +286,7 @@ public class MonetStatement counts[offset] = count; } offset++; - } while ((type = getMoreResults()) || (count = getUpdateCount()) != -1); + } while ((hasResultSet = getMoreResults()) || (count = getUpdateCount()) != -1); } catch (SQLException ex) { e.setNextException(ex); for (; offset < max; offset++) {
--- a/src/main/java/nl/cwi/monetdb/mcl/parser/TupleLineParser.java +++ b/src/main/java/nl/cwi/monetdb/mcl/parser/TupleLineParser.java @@ -58,7 +58,9 @@ public final class TupleLineParser exten throw new MCLParseException("Expected a data row starting with ["); // It is a tuple. Extract separate fields by examining the string data char for char - final char[] chrLine = source.toCharArray(); // convert whole string to char[] to avoid overhead of source.charAt(i) calls TODO: measure the overhead + // convert whole string to char[] to avoid overhead of source.charAt(i) calls + // TODO: measure the source.charAt(i) overhead and whether it is faster to eliminate the source.toCharArray(); copy + final char[] chrLine = source.toCharArray(); boolean inString = false, escaped = false, fieldHasEscape = false; final StringBuilder uesc = new StringBuilder(128); // used for building field string value when an escape is present in the field value int column = 0, cursor = 2; @@ -102,8 +104,8 @@ public final class TupleLineParser exten { if (fieldHasEscape) { // reuse the StringBuilder by cleaning it - uesc.delete(0, uesc.length()); - // prevent capacity increasements + uesc.setLength(0); + // prevent multiple capacity increments during the append()'s in the inner loop uesc.ensureCapacity(endpos - (cursor + 1)); // parse the field value (excluding the double quotes) and convert it to a string without any escape characters for (int pos = cursor + 1; pos < endpos; pos++) { @@ -141,7 +143,7 @@ public final class TupleLineParser exten if (chr2 >= '0' && chr2 <= '7' && chr3 >= '0' && chr3 <= '7') { // we got an octal number between \000 and \377 try { - uesc.append((char)(Integer.parseInt("" + chr + chr2 + chr3, 8))); + uesc.append((char)(Integer.parseInt(new String(chrLine, pos, 3), 8))); pos += 2; } catch (NumberFormatException e) { // hmmm, this point should never be reached actually...
--- a/tests/Test_Clargequery.java +++ b/tests/Test_Clargequery.java @@ -34,7 +34,7 @@ public class Test_Clargequery { "select 1;\n"; int size = 1000; - StringBuffer bigq = new StringBuffer(query.length() * size); + StringBuilder bigq = new StringBuilder(query.length() * size); for (int i = 0; i < size; i++) { bigq.append(query); } @@ -61,7 +61,8 @@ public class Test_Clargequery { System.out.println("ABORTING TEST!!!"); } - if (rs != null) rs.close(); + if (rs != null) + rs.close(); con1.close(); }