[ 
https://issues.apache.org/jira/browse/DERBY-3732?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12608387#action_12608387
 ] 

Kristian Waagan commented on DERBY-3732:
----------------------------------------

Regarding skip performance, I would say it's hard to tell.
The code in the JVM might be optimized and perform slightly better, even if it 
is using the same approach.
However, in some cases the stream implementation might be capable of skipping 
an amount of data a lot faster than reading it. One example might be streams 
from files, where a skip could in theory consist of just changing a pointer. 
ByteArrayInputStream also has its own implementation of skip, which doesn't use 
read.

Only using read directly can result in loosing optimizations for some stream 
implementations.
Also note that the contracts are different for InputStream.skip and Reader.skip.


For reference, here's an excerpt from Java SE 6 InputStream.skip JavaDoc:
"Subclasses are encouraged to provide a more efficient implementation of this 
method. For instance, the implementation may depend on the ability to seek."

> SQL Length function materializes lob into memory
> ------------------------------------------------
>
>                 Key: DERBY-3732
>                 URL: https://issues.apache.org/jira/browse/DERBY-3732
>             Project: Derby
>          Issue Type: Improvement
>          Components: SQL
>    Affects Versions: 10.3.3.0, 10.4.1.3, 10.5.0.0
>            Reporter: Kathey Marsden
>            Priority: Minor
>         Attachments: derby-3732_diff.txt, derby-3732_proto_diff.txt, 
> LengthLargeLob.zip, LengthThruBlob.java
>
>
> Currently the SQL length function materializes the entire lob into memory. In 
> SQLBinary.getLength() we have 
> public final int      getLength() throws StandardException
>       {
>               if (stream != null) {
>                       if (streamValueLength != -1)
>                               return streamValueLength;
>               }
>               return (getBytes() == null) ? 0 : getBytes().length;
>       }
> Which actually is doubly bad because we call getBytes twice and materialize 
> it twice.
> It would be good to read the length from the stream if available and 
> otherwise stream the value to get the length, rather than materializing it 
> into memory.
> To reproduce, run the attached repro.
> java -Xmx16M  LengthLargeLob
> It gives an out of memory exception
> Caused by: java.lang.OutOfMemoryError: Java heap space
>         at 
> org.apache.derby.iapi.types.SQLBinary.readFromStream(SQLBinary.java:415)
>         at 
> org.apache.derby.iapi.types.SQLBinary.readExternal(SQLBinary.java:318)
>         at org.apache.derby.iapi.types.SQLBinary.getValue(SQLBinary.java:220)
>         at org.apache.derby.iapi.types.SQLBinary.getBytes(SQLBinary.java:210)
>         at org.apache.derby.iapi.types.SQLBinary.getLength(SQLBinary.java:250)
>         at 
> org.apache.derby.impl.sql.execute.BaseActivation.getDB2Length(BaseActivation.java:1684)
>         at 
> org.apache.derby.exe.acf81e0010x011axa317x5db8x0000003d9dc81.e1(Unknown 
> Source)
>         at 
> org.apache.derby.impl.services.reflect.DirectCall.invoke(ReflectGeneratedClass.java:141)
>         at 
> org.apache.derby.impl.sql.execute.ProjectRestrictResultSet.doProjection(ProjectRestrictResultSet.java:497)
>         at 
> org.apache.derby.impl.sql.execute.ProjectRestrictResultSet.getNextRowCore(ProjectRestrictResultSet.java:291)
>         at 
> org.apache.derby.impl.sql.execute.BasicNoPutResultSetImpl.getNextRow(BasicNoPutResultSetImpl.java:460)
>         at 
> org.apache.derby.impl.jdbc.EmbedResultSet.movePosition(EmbedResultSet.java:423)
>         ... 2 more
> [
>  

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to