Re: setBlob loop performance? - Mailing list pgsql-jdbc

From Barry Lind
Subject Re: setBlob loop performance?
Date
Msg-id 3D72D6CB.4070800@xythos.com
Whole thread Raw
In response to setBlob loop performance?  ("David Wall" <dwall@Yozons.com>)
List pgsql-jdbc
  David,

The fix below only provides half of a fix.  If you look further you will
see that LargeObject.getOutputStream() returns a BlobOutputStream.
 BlobOutputStream extends OutputStream.  However BlobOutputStream does
not override the
write(byte b[], int off, int len) method.  Therefore the default
implementation in OutputStream is used which still ends up writing one
byte at a time.  To get the desired benefit, you will need to implement
write(byte b[], int off, int len) in BlobOutputStream to be more efficient.

thanks,
--Barry


David Wall wrote:

>>Could you resend this in a diff -c format.  Since I don't know the exact
>>version you have it is difficult to pick out the changes.  A diff would
>>make that much easier.
>>
>>
>
>Sure.  I hope this helps...  The 'orig' version was the source included in
>the 7.2.2 download.
>
>David
>
>
>
>[postgresql@dev1 jdbc2]$ diff -c PreparedStatement.orig
>PreparedStatement.java
>*** PreparedStatement.orig      Mon Jan 14 23:37:33 2002
>--- PreparedStatement.java      Tue Aug 27 21:14:02 2002
>***************
>*** 879,907 ****
>        public void setBlob(int i, Blob x) throws SQLException
>        {
>                InputStream l_inStream = x.getBinaryStream();
>-               int l_length = (int) x.length();
>                LargeObjectManager lom = connection.getLargeObjectAPI();
>                int oid = lom.create();
>                LargeObject lob = lom.open(oid);
>                OutputStream los = lob.getOutputStream();
>                try
>                {
>                        // could be buffered, but then the OutputStream
>returned by LargeObject
>                        // is buffered internally anyhow, so there would be
>no performance
>                        // boost gained, if anything it would be worse!
>!                       int c = l_inStream.read();
>!                       int p = 0;
>!                       while (c > -1 && p < l_length)
>                        {
>!                               los.write(c);
>!                               c = l_inStream.read();
>!                               p++;
>                        }
>-                       los.close();
>                }
>                catch (IOException se)
>                {
>                        throw new PSQLException("postgresql.unusual", se);
>                }
>                // lob is closed by the stream so don't call lob.close()
>                setInt(i, oid);
>--- 879,915 ----
>        public void setBlob(int i, Blob x) throws SQLException
>        {
>                InputStream l_inStream = x.getBinaryStream();
>                LargeObjectManager lom = connection.getLargeObjectAPI();
>                int oid = lom.create();
>                LargeObject lob = lom.open(oid);
>                OutputStream los = lob.getOutputStream();
>+               byte[] buf = new byte[4096];
>                try
>                {
>                        // could be buffered, but then the OutputStream
>returned by LargeObject
>                        // is buffered internally anyhow, so there would be
>no performance
>                        // boost gained, if anything it would be worse!
>!                       int bytesRemaining = (int)x.length();
>!                       int numRead =
>l_inStream.read(buf,0,Math.min(buf.length,bytesRemaining));
>!                       while (numRead != -1 && bytesRemaining > 0)
>                        {
>!                               bytesRemaining -= numRead;
>!                               los.write(buf,0,numRead);
>!                               numRead =
>l_inStream.read(buf,0,Math.min(buf.length,bytesRemaining));
>                        }
>                }
>                catch (IOException se)
>                {
>                        throw new PSQLException("postgresql.unusual", se);
>+               }
>+               finally
>+               {
>+                   try
>+                   {
>+                           los.close();
>+                 l_inStream.close();
>+             }
>+             catch( Exception e ) {}
>                }
>                // lob is closed by the stream so don't call lob.close()
>                setInt(i, oid);
>
>
>
>
>



pgsql-jdbc by date:

Previous
From: Barry Lind
Date:
Subject: Re: Batch Update updatecounts when error happens
Next
From: Barry Lind
Date:
Subject: Re: FW: LISTEN/NOTIFY support in JDBC driver?