changeset 97:e087be5c7225 embedded

Optimization: Got rid of the auxiliary matrix to hold null values. MonetDB's null values are now mapped to Java's min values.
author Pedro Ferreira <pedro.ferreira@monetdbsolutions.com>
date Mon, 09 Jan 2017 14:12:49 +0000 (2017-01-09)
parents 4a93f75c72c9
children c0ce1ea5075f
files src/main/java/nl/cwi/monetdb/mcl/protocol/AbstractProtocol.java src/main/java/nl/cwi/monetdb/mcl/protocol/newmapi/NewMapiProtocol.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParserHelper.java src/main/java/nl/cwi/monetdb/mcl/responses/DataBlockResponse.java
diffstat 6 files changed, 33 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/AbstractProtocol.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/AbstractProtocol.java
@@ -45,8 +45,7 @@ public abstract class AbstractProtocol {
     public abstract int getNextTableHeader(String[] columnNames, int[] columnLengths, String[] types,
                                            String[] tableNames) throws ProtocolException;
 
-    public abstract int parseTupleLines(int firstLineNumber, int[] typesMap, Object[] values,
-                                        boolean[][] nulls) throws ProtocolException;
+    public abstract int parseTupleLines(int firstLineNumber, int[] typesMap, Object[] values) throws ProtocolException;
 
     public abstract String getRemainingStringLine(int startIndex);
 
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/newmapi/NewMapiProtocol.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/newmapi/NewMapiProtocol.java
@@ -66,7 +66,7 @@ public class NewMapiProtocol extends Abs
     }
 
     @Override
-    public int parseTupleLines(int lineNumber, int[] typesMap, Object[] values, boolean[][] nulls) throws ProtocolException {
+    public int parseTupleLines(int lineNumber, int[] typesMap, Object[] values) throws ProtocolException {
         return 0;
     }
 
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java
@@ -123,14 +123,14 @@ public class OldMapiProtocol extends Abs
     }
 
     @Override
-    public int getNextTableHeader(String[] columnNames, int[] columnLengths, String[] types, String[] tableNames) throws ProtocolException {
+    public int getNextTableHeader(String[] columnNames, int[] columnLengths, String[] types, String[] tableNames)
+            throws ProtocolException {
         return OldMapiTableHeaderParser.GetNextTableHeader(this.lineBuffer, columnNames, columnLengths, types, tableNames);
     }
 
     @Override
-    public int parseTupleLines(int firstLineNumber, int[] typesMap, Object[] data, boolean[][] nulls)
-            throws ProtocolException {
-        OldMapiTupleLineParser.OldMapiParseTupleLine(this, firstLineNumber, typesMap, data, nulls);
+    public int parseTupleLines(int firstLineNumber, int[] typesMap, Object[] data) throws ProtocolException {
+        OldMapiTupleLineParser.OldMapiParseTupleLine(this, firstLineNumber, typesMap, data);
         return firstLineNumber;
     }
 
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java
@@ -20,13 +20,14 @@ import java.nio.CharBuffer;
 import java.sql.Types;
 import java.text.ParsePosition;
 import java.util.Calendar;
+import java.util.Map;
 
 final class OldMapiTupleLineParser {
 
     private static final char[] NULL_STRING = new char[]{'N','U','L','L'};
 
-    static int OldMapiParseTupleLine(OldMapiProtocol protocol, int lineNumber, int[] typesMap, Object[] values,
-                                     boolean[][] nulls) throws ProtocolException {
+    static int OldMapiParseTupleLine(OldMapiProtocol protocol, int lineNumber, int[] typesMap, Object[] values)
+            throws ProtocolException {
         CharBuffer lineBuffer = protocol.lineBuffer;
         CharBuffer tupleLineBuffer = protocol.tupleLineBuffer;
 
@@ -127,13 +128,10 @@ final class OldMapiTupleLineParser {
                             // put the unescaped string in the right place
                             tupleLineBuffer.flip();
                             OldMapiStringToJavaDataConversion(tupleLineBuffer.array(), 0, tupleLineBuffer.limit(), lineNumber, values[column], typesMap[column]);
-                            nulls[column][lineNumber] = false;
                         } else if ((i - 1) - cursor == 4 && OldMapiTupleLineParserHelper.CharIndexOf(array, array.length, NULL_STRING, 4) == cursor) {
                             SetNullValue(lineNumber, values[column], typesMap[column]);
-                            nulls[column][lineNumber] = true;
                         } else {
                             OldMapiStringToJavaDataConversion(array, cursor, i - 1 - cursor, lineNumber, values[column], typesMap[column]);
-                            nulls[column][lineNumber] = false;
                         }
                         column++;
                         cursor = i + 1;
@@ -166,7 +164,7 @@ final class OldMapiTupleLineParser {
                                                           Object columnArray, int jDBCMapping) throws ProtocolException {
         switch (jDBCMapping) {
             case Types.BOOLEAN:
-                ((boolean[]) columnArray)[lineNumber] = OldMapiTupleLineParserHelper.CharArrayToBoolean(toParse, startPosition, count);
+                ((byte[]) columnArray)[lineNumber] = OldMapiTupleLineParserHelper.CharArrayToBoolean(toParse, startPosition, count);
                 break;
             case Types.TINYINT:
                 ((byte[]) columnArray)[lineNumber] = OldMapiTupleLineParserHelper.CharArrayToByte(toParse, startPosition, count);
@@ -230,8 +228,6 @@ final class OldMapiTupleLineParser {
     private static void SetNullValue(int lineNumber, Object columnArray, int jDBCMapping) throws ProtocolException {
         switch (jDBCMapping) {
             case Types.BOOLEAN:
-                ((boolean[]) columnArray)[lineNumber] = false;
-                break;
             case Types.TINYINT:
                 ((byte[]) columnArray)[lineNumber] = Byte.MIN_VALUE;
                 break;
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParserHelper.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParserHelper.java
@@ -33,8 +33,8 @@ final class OldMapiTupleLineParserHelper
 
     private static final char[] TrueConstant = new char[]{'t','r','u','e'};
 
-    static boolean CharArrayToBoolean(char[] data, int start, int count) {
-        return CharIndexOf(data, start + count, TrueConstant, 4) == start;
+    static byte CharArrayToBoolean(char[] data, int start, int count) {
+        return CharIndexOf(data, start + count, TrueConstant, 4) == start ? (byte)1 : (byte)0;
     }
 
     static byte CharArrayToByte(char[] data, int start, int count) {
--- a/src/main/java/nl/cwi/monetdb/mcl/responses/DataBlockResponse.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/responses/DataBlockResponse.java
@@ -44,8 +44,6 @@ public class DataBlockResponse implement
     private final AbstractProtocol protocol;
     /** The JdbcSQLTypes mapping */
     private final int[] jdbcSQLTypes;
-    /** A mapping of null values of the current Row */
-    private boolean[][] nullMappings;//
     /** A 'pointer' to the current line */
     private int blockLine;
     /** The number of rows in the block */
@@ -63,7 +61,6 @@ public class DataBlockResponse implement
         this.pos = -1;
         this.rowcount = rowcount;
         this.data = new Object[columncount];
-        this.nullMappings = new boolean[columncount][rowcount];
         this.protocol = protocol;
         this.jdbcSQLTypes = JdbcSQLTypes;
     }
@@ -87,8 +84,6 @@ public class DataBlockResponse implement
             for (int i = 0 ; i < numberOfColumns ; i++) {
                 switch (this.jdbcSQLTypes[i]) {
                     case Types.BOOLEAN:
-                        this.data[i] = new boolean[this.rowcount];
-                        break;
                     case Types.TINYINT:
                         this.data[i] = new byte[this.rowcount];
                         break;
@@ -137,7 +132,7 @@ public class DataBlockResponse implement
 
         // add to the backing array
         int nextPos = this.pos + 1;
-        this.pos = this.protocol.parseTupleLines(nextPos, this.jdbcSQLTypes, this.data, this.nullMappings);
+        this.pos = this.protocol.parseTupleLines(nextPos, this.jdbcSQLTypes, this.data);
     }
 
     /**
@@ -160,10 +155,8 @@ public class DataBlockResponse implement
         int numberOfColumns = this.data.length;
         for (int i = 0; i < numberOfColumns; i++) {
             data[i] = null;
-            nullMappings[i] = null;
         }
         data = null;
-        nullMappings = null;
     }
 
     /* Methods to be called after the block construction has been completed */
@@ -204,7 +197,23 @@ public class DataBlockResponse implement
      * @return If the value is null or not.
      */
     public boolean checkValueIsNull(int column) {
-        return this.nullMappings[column][this.blockLine];
+        switch (this.jdbcSQLTypes[column]) {
+            case Types.BOOLEAN:
+            case Types.TINYINT:
+                return ((byte[]) this.data[column])[this.blockLine] == Byte.MIN_VALUE;
+            case Types.SMALLINT:
+                return ((short[]) this.data[column])[this.blockLine] == Short.MIN_VALUE;
+            case Types.INTEGER:
+                return ((int[]) this.data[column])[this.blockLine] == Integer.MIN_VALUE;
+            case Types.BIGINT:
+                return ((long[]) this.data[column])[this.blockLine] == Long.MIN_VALUE;
+            case Types.REAL:
+                return ((float[]) this.data[column])[this.blockLine] == Float.MIN_VALUE;
+            case Types.DOUBLE:
+                return ((double[]) this.data[column])[this.blockLine] == Double.MIN_VALUE;
+            default:
+                return ((Object[]) this.data[column])[this.blockLine] == null;
+        }
     }
 
     /**
@@ -214,7 +223,7 @@ public class DataBlockResponse implement
      * @return A Java Boolean if the column is a boolean, otherwise a ClassCastException is thrown
      */
     public boolean getBooleanValue(int column) {
-        return ((boolean[]) this.data[column])[this.blockLine];
+        return ((byte[]) this.data[column])[this.blockLine] == 1;
     }
 
     /**
@@ -296,7 +305,7 @@ public class DataBlockResponse implement
     public String getValueAsString(int column) {
         switch (this.jdbcSQLTypes[column]) {
             case Types.BOOLEAN:
-                return Boolean.toString(((boolean[]) this.data[column])[this.blockLine]);
+                return ((byte[]) this.data[column])[this.blockLine] == 1 ? "true" : "false";
             case Types.TINYINT:
                 return Byte.toString(((byte[]) this.data[column])[this.blockLine]);
             case Types.SMALLINT:
@@ -330,7 +339,7 @@ public class DataBlockResponse implement
     public Object getValueAsObject(int column) {
         switch (this.jdbcSQLTypes[column]) {
             case Types.BOOLEAN:
-                return ((boolean[]) this.data[column])[this.blockLine];
+                return ((byte[]) this.data[column])[this.blockLine] == 1;
             case Types.TINYINT:
                 return ((byte[]) this.data[column])[this.blockLine];
             case Types.SMALLINT: