<div dir="ltr"><div dir="ltr">On Tue, Jul 9, 2024 at 10:51 AM Martin Desruisseaux <<a href="mailto:martin.desruisseaux@geomatys.com">martin.desruisseaux@geomatys.com</a>> wrote:</div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>
<div><p>JDK-22 has modified <font face="monospace">ByteArrayInputStream.transferTo(OutputStream)</font>
implementation for performing a defensive copy of the byte array
when the destination is not trusted (JDK-8321053). However, I was
using the previous implementation as a trick for reading the array
without copy. The reason is because we have millions of <font face="monospace">ByteArrayInputStream</font> instances when
reading BLOBs from a database (e.g., geometries from a spatial
database), and some popular JDBC drivers implement <font face="monospace">ResultSet.</font><span><font face="monospace">getBinaryStream(int)</font> by reading all
data in a <font face="monospace">byte[]</font> array and
wrapping the array in a <font face="monospace">ByteArrayInputStream</font>.
As a cleaner replacement for my old trick, would it be possible
to add something like the following method in <font face="monospace">ByteArrayInputStream</font>?</span></p>
<blockquote>
<pre><span>/**
* Returns the remaining content of this input stream as a read-only buffer.
* The sequence of remaining bytes in the buffer is the same as the sequence
* of bytes that would be returned by {@link #readAllBytes()}.
*
* @return the remaining content of this input stream, as a read-only buffer
*/
public synchronized ByteBuffer asByteBuffer() {
return ByteBuffer.wrap(buf, pos, count - pos).slice().asReadOnlyBuffer();
}
</span></pre>
</blockquote>
<p><span>The call to <font face="monospace">slice()</font>
is for blocking callers from accessing the bytes before the
current stream position. I assumed that it could be a security
issue. If this proposal is acceptable, I can create a pull
request.</span></p></div></blockquote></div><div>A few random thoughts...</div><div><div><br></div><div>First, let's consider what you are optimizing for.
The difference in the old vs. new behavior is the use of a 128k
temporary transfer buffer. So if I understand this correctly the performance problem you are addressing (in
terms of blown cache) is not proportional to the size of the original
BLOB, but to at most 128K (in both the old and new cases, you have to scan the entire BLOB, so that's a wash). Does that 128K create a noticeable difference?<br></div><div><br></div></div><div>Anyway, IMHO more interoperability between the different Java "ways of doing things" is good. E.g., converting between Instant and Date, etc. This falls into that category. In fact, in the past I've wished for the reverse - i.e., <span style="font-family:monospace">ByteBuffer.asOutputStream()</span> - and ended up creating a simple wrapper class that does that. So perhaps these two additions could go together - just a thought.<br></div><div><div><div><br></div><div>Minor nit - the Javadoc would need to clarify that operations on the returned ByteBuffer have no effect on the original OutputStream.</div><br><div>-Archie<br></div><div><br><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature">Archie L. Cobbs<br></div></div></div></div></div>