Changeset: 4bb4e988164d for monetdb-java
URL: http://dev.monetdb.org/hg/monetdb-java?cmd=changeset;node=4bb4e988164d
Added Files:
        
src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParserHelper.java
Modified Files:
        src/main/java/nl/cwi/monetdb/jdbc/MonetClob.java
        
src/main/java/nl/cwi/monetdb/mcl/connection/helpers/BufferReallocator.java
        src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java
        
src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java
        
src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java
Branch: embedded
Log Message:

Less memory usage while retrieving some native types on a JDBC MAPI connection.


diffs (truncated from 504 to 300 lines):

diff --git a/src/main/java/nl/cwi/monetdb/jdbc/MonetClob.java 
b/src/main/java/nl/cwi/monetdb/jdbc/MonetClob.java
--- a/src/main/java/nl/cwi/monetdb/jdbc/MonetClob.java
+++ b/src/main/java/nl/cwi/monetdb/jdbc/MonetClob.java
@@ -30,6 +30,10 @@ public class MonetClob implements Clob, 
                buffer = new StringBuilder(in);
        }
 
+       public MonetClob(char[] toParse, int startPosition, int count) {
+               buffer = new StringBuilder(new String(toParse, startPosition, 
count));
+       }
+
        //== begin interface Clob
        
        /**
diff --git 
a/src/main/java/nl/cwi/monetdb/mcl/connection/helpers/BufferReallocator.java 
b/src/main/java/nl/cwi/monetdb/mcl/connection/helpers/BufferReallocator.java
--- a/src/main/java/nl/cwi/monetdb/mcl/connection/helpers/BufferReallocator.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/connection/helpers/BufferReallocator.java
@@ -33,9 +33,16 @@ public final class BufferReallocator {
 
     public static CharBuffer ReallocateBuffer(CharBuffer oldBuffer) {
         int newCapacity = GetNewCapacity(oldBuffer);
-        CharBuffer newBuffer = CharBuffer.allocate(newCapacity);
+        CharBuffer newBuffer = CharBuffer.wrap(new char[newCapacity]);
         oldBuffer.flip();
         newBuffer.put(oldBuffer.array());
         return newBuffer;
     }
+
+    public static CharBuffer EnsureCapacity(CharBuffer oldBuffer, int 
newCapacity) {
+        if(newCapacity > oldBuffer.capacity()) {
+            oldBuffer = CharBuffer.wrap(new char[newCapacity]);
+        }
+        return oldBuffer;
+    }
 }
diff --git 
a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java 
b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java
--- a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java
+++ b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiProtocol.java
@@ -32,12 +32,12 @@ public class OldMapiProtocol extends Abs
 
     CharBuffer lineBuffer;
 
-    private final StringBuilder tupleLineBuilder;
+    CharBuffer tupleLineBuffer;
 
     public OldMapiProtocol(OldMapiSocket socket) {
         this.socket = socket;
         this.lineBuffer = CharBuffer.wrap(new char[OldMapiSocket.BLOCK]);
-        this.tupleLineBuilder = new StringBuilder(OldMapiSocket.BLOCK);
+        this.tupleLineBuffer = CharBuffer.wrap(new char[1024]);
     }
 
     public OldMapiSocket getSocket() {
@@ -132,8 +132,7 @@ public class OldMapiProtocol extends Abs
     @Override
     public int parseTupleLines(int firstLineNumber, int[] typesMap, Object[] 
data, boolean[][] nulls)
             throws ProtocolException {
-        OldMapiTupleLineParser.OldMapiParseTupleLine(firstLineNumber, 
this.lineBuffer,
-                this.tupleLineBuilder, typesMap, data, nulls);
+        OldMapiTupleLineParser.OldMapiParseTupleLine(this, firstLineNumber, 
typesMap, data, nulls);
         return firstLineNumber;
     }
 
diff --git 
a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java
 
b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java
--- 
a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java
+++ 
b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiStartOfHeaderParser.java
@@ -55,13 +55,14 @@ final class OldMapiStartOfHeaderParser {
         if (currentPointer >= limit) {
             throw new ProtocolException("unexpected end of string", 
currentPointer - 1);
         }
-        int tmp = 0, negative = 1;;
+        int tmp = 0;
+        boolean positive = true;
         char chr = array[currentPointer++];
         // note: don't use Character.isDigit() here, because we only want 
ISO-LATIN-1 digits
         if (chr >= '0' && chr <= '9') {
             tmp = (int)chr - (int)'0';
         } else if(chr == '-') {
-            negative = -1;
+            positive = false;
         } else {
             throw new ProtocolException("expected a digit", currentPointer - 
1);
         }
@@ -78,9 +79,8 @@ final class OldMapiStartOfHeaderParser {
                 throw new ProtocolException("expected a digit", currentPointer 
- 1);
             }
         }
-        tmp *= negative;
         protocol.lineBuffer.position(currentPointer);
-        return tmp;
+        return positive ? tmp : -tmp;
     }
 
     static String GetNextResponseDataAsString(OldMapiProtocol protocol) throws 
ProtocolException {
diff --git 
a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java 
b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java
--- 
a/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java
+++ 
b/src/main/java/nl/cwi/monetdb/mcl/protocol/oldmapi/OldMapiTupleLineParser.java
@@ -10,6 +10,7 @@ package nl.cwi.monetdb.mcl.protocol.oldm
 
 import nl.cwi.monetdb.jdbc.MonetBlob;
 import nl.cwi.monetdb.jdbc.MonetClob;
+import nl.cwi.monetdb.mcl.connection.helpers.BufferReallocator;
 import nl.cwi.monetdb.mcl.connection.helpers.GregorianCalendarParser;
 import nl.cwi.monetdb.mcl.protocol.ProtocolException;
 
@@ -22,39 +23,13 @@ import java.util.Calendar;
 
 final class OldMapiTupleLineParser {
 
-    private static final char[] NULL_STRING = "NULL".toCharArray();
+    private static final char[] NULL_STRING = new char[]{'N','U','L','L'};
 
-    private static int CharIndexOf(char[] source, int sourceCount, char[] 
target, int targetCount) {
-        if (targetCount == 0) {
-            return 0;
-        }
+    static int OldMapiParseTupleLine(OldMapiProtocol protocol, int lineNumber, 
int[] typesMap, Object[] values,
+                                     boolean[][] nulls) throws 
ProtocolException {
+        CharBuffer lineBuffer = protocol.lineBuffer;
+        CharBuffer tupleLineBuffer = protocol.tupleLineBuffer;
 
-        char first = target[0];
-        int max = sourceCount - targetCount;
-
-        for (int i = 0; i <= max; i++) {
-            /* Look for first character. */
-            if (source[i] != first) {
-                while (++i <= max && source[i] != first);
-            }
-
-            /* Found first character, now look at the rest of v2 */
-            if (i <= max) {
-                int j = i + 1;
-                int end = j + targetCount - 1;
-                for (int k = 1; j < end && source[j] == target[k]; j++, k++);
-
-                if (j == end) {
-                    /* Found whole string. */
-                    return i;
-                }
-            }
-        }
-        return -1;
-    }
-
-    static int OldMapiParseTupleLine(int lineNumber, CharBuffer lineBuffer, 
StringBuilder helper, int[] typesMap,
-                                     Object[] values, boolean[][] nulls) 
throws ProtocolException {
         int len = lineBuffer.limit();
         char[] array = lineBuffer.array();
 
@@ -64,7 +39,7 @@ final class OldMapiTupleLineParser {
                 throw new ProtocolException(typesMap.length + " columns 
expected, but only single value found");
             }
             // return the whole string but the leading =
-            OldMapiStringToJavaObjectConverter(new String(array, 1, len - 1), 
lineNumber, values[0], typesMap[0]);
+            OldMapiStringToJavaDataConversion(array, 1, len - 1, lineNumber, 
values[0], typesMap[0]);
             return 1;
         }
 
@@ -102,26 +77,26 @@ final class OldMapiTupleLineParser {
                     if (!inString && (i > 0 && array[i - 1] == ',') || (i + 1 
== len - 1 && array[++i] == ']')) { // dirty
                         // split!
                         if (array[cursor] == '"' && array[i - 2] == '"') {
-                            // reuse the StringBuilder by cleaning it
-                            helper.setLength(0);
-                            // prevent capacity increases
-                            helper.ensureCapacity((i - 2) - (cursor + 1));
+                            // reuse the CharBuffer by cleaning it and ensure 
the capacity
+                            tupleLineBuffer.clear();
+                            tupleLineBuffer = 
BufferReallocator.EnsureCapacity(tupleLineBuffer, (i - 2) - (cursor + 1));
+
                             for (int pos = cursor + 1; pos < i - 2; pos++) {
                                 if (array[cursor] == '\\' && pos + 1 < i - 2) {
                                     pos++;
                                     // strToStr and strFromStr in gdk_atoms.mx 
only support \t \n \\ \" and \377
                                     switch (array[pos]) {
                                         case '\\':
-                                            helper.append('\\');
+                                            tupleLineBuffer.put('\\');
                                             break;
                                         case 'n':
-                                            helper.append('\n');
+                                            tupleLineBuffer.put('\n');
                                             break;
                                         case 't':
-                                            helper.append('\t');
+                                            tupleLineBuffer.put('\t');
                                             break;
                                         case '"':
-                                            helper.append('"');
+                                            tupleLineBuffer.put('"');
                                             break;
                                         case '0': case '1': case '2': case '3':
                                             // this could be an octal number, 
let's check it out
@@ -129,7 +104,7 @@ final class OldMapiTupleLineParser {
                                                     array[pos + 2] >= '0' && 
array[pos + 2] <= '7') {
                                                 // we got the number!
                                                 try {
-                                                    
helper.append((char)(Integer.parseInt("" + array[pos] + array[pos + 1] + 
array[pos + 2], 8)));
+                                                    
tupleLineBuffer.put((char)(Integer.parseInt("" + array[pos] + array[pos + 1] + 
array[pos + 2], 8)));
                                                     pos += 2;
                                                 } catch (NumberFormatException 
e) {
                                                     // hmmm, this point should 
never be reached actually...
@@ -137,26 +112,27 @@ final class OldMapiTupleLineParser {
                                                 }
                                             } else {
                                                 // do default action if number 
seems not to be correct
-                                                helper.append(array[pos]);
+                                                
tupleLineBuffer.put(array[pos]);
                                             }
                                             break;
                                         default:
                                             // this is wrong, just ignore the 
escape, and print the char
-                                            helper.append(array[pos]);
+                                            tupleLineBuffer.put(array[pos]);
                                             break;
                                     }
                                 } else {
-                                    helper.append(array[pos]);
+                                    tupleLineBuffer.put(array[pos]);
                                 }
                             }
                             // put the unescaped string in the right place
-                            
OldMapiStringToJavaObjectConverter(helper.toString(), lineNumber, 
values[column], typesMap[column]);
+                            tupleLineBuffer.flip();
+                            
OldMapiStringToJavaDataConversion(tupleLineBuffer.array(), 0, 
tupleLineBuffer.limit(), lineNumber, values[column], typesMap[column]);
                             nulls[column][lineNumber] = false;
-                        } else if ((i - 1) - cursor == 4 && CharIndexOf(array, 
array.length, NULL_STRING, NULL_STRING.length) == cursor) {
+                        } 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 {
-                            OldMapiStringToJavaObjectConverter(new 
String(array, cursor, i - 1 - cursor), lineNumber, values[column], 
typesMap[column]);
+                            OldMapiStringToJavaDataConversion(array, cursor, i 
- 1 - cursor, lineNumber, values[column], typesMap[column]);
                             nulls[column][lineNumber] = false;
                         }
                         column++;
@@ -167,82 +143,84 @@ final class OldMapiTupleLineParser {
                     break;
             }
         }
+
+        protocol.tupleLineBuffer = tupleLineBuffer;
         // check if this result is of the size we expected it to be
         if (column != typesMap.length)
             throw new ProtocolException("illegal result length: " + column + 
"\nlast read: " + (column > 0 ? values[column - 1] : "<none>"));
         return column;
     }
 
-    private static byte[] BinaryBlobConverter(String toParse) {
-        int len = toParse.length() / 2;
+    private static byte[] BinaryBlobConverter(char[] toParse, int 
startPosition, int count) {
+        int len = (startPosition + count) / 2;
         byte[] res = new byte[len];
         for (int i = 0; i < len; i++) {
-            res[i] = (byte) Integer.parseInt(toParse.substring(2 * i, (2 * i) 
+ 2), 16);
+            res[i] = (byte) Integer.parseInt(new String(toParse, 2 * i, (2 * 
i) + 2), 16);
         }
         return res;
     }
 
     private static final ParsePosition Ppos = new ParsePosition(0);
 
-    private static void OldMapiStringToJavaObjectConverter(String toParse, int 
lineNumber, Object columnArray,
-                                                           int jDBCMapping) 
throws ProtocolException {
+    private static void OldMapiStringToJavaDataConversion(char[] toParse, int 
startPosition, int count, int lineNumber,
+                                                          Object columnArray, 
int jDBCMapping) throws ProtocolException {
         switch (jDBCMapping) {
             case Types.BOOLEAN:
-                ((boolean[]) columnArray)[lineNumber] = 
Boolean.parseBoolean(toParse);
+                ((boolean[]) columnArray)[lineNumber] = 
OldMapiTupleLineParserHelper.CharArrayToBoolean(toParse, startPosition, count);
                 break;
             case Types.TINYINT:
-                ((byte[]) columnArray)[lineNumber] = Byte.parseByte(toParse);
+                ((byte[]) columnArray)[lineNumber] = 
OldMapiTupleLineParserHelper.CharArrayToByte(toParse, startPosition, count);
                 break;
             case Types.SMALLINT:
-                ((short[]) columnArray)[lineNumber] = 
Short.parseShort(toParse);
+                ((short[]) columnArray)[lineNumber] = 
OldMapiTupleLineParserHelper.CharArrayToShort(toParse, startPosition, count);
                 break;
             case Types.INTEGER:
-                ((int[]) columnArray)[lineNumber] = 
Integer.parseInt(toParse.replace(".", "")); //intervals :(
+                ((int[]) columnArray)[lineNumber] = 
OldMapiTupleLineParserHelper.CharArrayToInt(toParse, startPosition, count);
                 break;
             case Types.BIGINT:
-                ((long[]) columnArray)[lineNumber] = 
Long.parseLong(toParse.replace(".", "")); //intervals :(
+                ((long[]) columnArray)[lineNumber] = 
OldMapiTupleLineParserHelper.CharArrayToLong(toParse, startPosition, count);
                 break;
             case Types.REAL:
-                ((float[]) columnArray)[lineNumber] = 
Float.parseFloat(toParse);
+                ((float[]) columnArray)[lineNumber] = Float.parseFloat(new 
String(toParse, startPosition, count));
                 break;
             case Types.DOUBLE:
-                ((double[]) columnArray)[lineNumber] = 
Double.parseDouble(toParse);
+                ((double[]) columnArray)[lineNumber] = Double.parseDouble(new 
String(toParse, startPosition, count));
                 break;
             case Types.DECIMAL:
-                ((BigDecimal[]) columnArray)[lineNumber] = new 
BigDecimal(toParse);
+                ((BigDecimal[]) columnArray)[lineNumber] = new 
BigDecimal(toParse, startPosition, count);
                 break;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to