Subject FBBlobField.java.patch
Author Alexey Panchenko
Hello,

Yesterday I was looking in our application poor performance when
working with BLOBs (about 3 Mb each).

I think that FBBlobField.getBytesInternal() method is not optimal - it
allocates small ByteArrayOutputStream which will reallocate several
times to larger length and finally in toByteArray() another copy is
created.

So I think that reading directly into the result array will be
quicker.

This class compiles, however the HEAD is not compilable now, giving 5
errors "overridden method does not throw
org.firebirdsql.jdbc.FBSQLException", so I did not test it.

What do you think ?

Index: FBBlobField.java
===================================================================
RCS file: /cvsroot/firebird/client-java/src/main/org/firebirdsql/jdbc/field/FBBlobField.java,v
retrieving revision 1.11
diff -u -U6 -r1.11 FBBlobField.java
--- FBBlobField.java 27 Dec 2005 00:02:00 -0000 1.11
+++ FBBlobField.java 29 Dec 2005 06:39:23 -0000
@@ -117,44 +117,43 @@
public byte[] getBytesInternal() throws SQLException {
Blob blob = getBlob();

if (blob == BLOB_NULL_VALUE)
return BYTES_NULL_VALUE;

+ final int length = (int) blob.length();
+
InputStream in = blob.getBinaryStream();

if (in == STREAM_NULL_VALUE)
return BYTES_NULL_VALUE;
-
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
-
- // copy stream data
- byte[] buff = new byte[BUFF_SIZE];
- int counter = 0;
try {
- while((counter = in.read(buff)) != -1) {
- bout.write(buff, 0, counter);
+ // copy stream data
+ final byte[] buff = new byte[length];
+ int offset = 0;
+ while (offset < length) {
+ final int chunkSize = length - offset;
+ final int counter = in.read(buff, offset, chunkSize);
+ if (counter == -1) {
+ // unexpected EOF
+ throw (SQLException) createException(BYTES_CONVERSION_ERROR);
+ }
+ offset += counter;
}
+ return buff;
} catch(IOException ioex) {
throw (SQLException)createException(
BYTES_CONVERSION_ERROR + " " + ioex.getMessage());
} finally {
try {
in.close();
} catch(IOException ioex) {
throw new FBSQLException(ioex);
}
-
- try {
- bout.close();
- } catch(IOException ioex) {
- throw new FBSQLException(ioex);
- }
}

- return bout.toByteArray();
}

public byte[] getCachedObject() throws SQLException {
if (getFieldData()==null)
return BYTES_NULL_VALUE;


--
Best regards,
Alexey mailto:alex+news@...