Add and adapt ReadAheadInputStream and
BufferedFileChannelInputStream from Apache Spark.
Javadoc and better method names.
MODIFY
src/main/java/org/apache/commons/io/input/BufferedFileChannelInputStream.java
src/main/java/org/apache/commons/io/input/BufferedFileChannelInputStream.java
@@ -97,13 +97,30 @@ public synchronized int available() throws IOException {
return byteBuffer.remaining();
}
+ /**
+ * Attempts to clean up a ByteBuffer if it is direct or memory-mapped. This uses an *unsafe* Sun API that will cause
+ * errors if one attempts to read from the disposed buffer. However, neither the bytes allocated to direct buffers
+ * nor file descriptors opened for memory-mapped buffers put pressure on the garbage collector. Waiting for garbage
+ * collection may lead to the depletion of off-heap memory or huge numbers of open files. There's unfortunately no
+ * standard API to manually dispose of these kinds of buffers.
+ *
+ * @param buffer the buffer to clean.
+ */
+ private void clean(final ByteBuffer buffer) {
+ if (buffer instanceof sun.nio.ch.DirectBuffer) {
+ clean((sun.nio.ch.DirectBuffer) buffer);
+ }
+ }
+
/**
* In Java 8, the type of DirectBuffer.cleaner() was sun.misc.Cleaner, and it was possible to access the method
* sun.misc.Cleaner.clean() to invoke it. The type changed to jdk.internal.ref.Cleaner in later JDKs, and the
* .clean() method is not accessible even with reflection. However sun.misc.Unsafe added a invokeCleaner() method in
* JDK 9+ and this is still accessible with reflection.
+ *
+ * @param buffer the buffer to clean.
*/
- private void bufferCleaner(final DirectBuffer buffer) {
+ private void clean(final DirectBuffer buffer) {
//
// Ported from StorageUtils.scala.
//
@@ -159,20 +176,7 @@ public synchronized void close() throws IOException {
try {
fileChannel.close();
} finally {
- dispose(byteBuffer);
- }
- }
-
- /**
- * Attempts to clean up a ByteBuffer if it is direct or memory-mapped. This uses an *unsafe* Sun API that will cause
- * errors if one attempts to read from the disposed buffer. However, neither the bytes allocated to direct buffers
- * nor file descriptors opened for memory-mapped buffers put pressure on the garbage collector. Waiting for garbage
- * collection may lead to the depletion of off-heap memory or huge numbers of open files. There's unfortunately no
- * standard API to manually dispose of these kinds of buffers.
- */
- private void dispose(final ByteBuffer buffer) {
- if (buffer instanceof sun.nio.ch.DirectBuffer) {
- bufferCleaner((sun.nio.ch.DirectBuffer) buffer);
+ clean(byteBuffer);
}
}

MODIFY
src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java
src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java
@@ -393,6 +393,9 @@ public long skip(final long n) throws IOException {
/**
* Internal skip function which should be called only from skip(). The assumption is that the stateChangeLock is
* already acquired in the caller before calling this function.
+ *
+ * @param n the number of bytes to be skipped.
+ * @return the actual number of bytes skipped.
*/
private long skipInternal(final long n) throws IOException {
assert stateChangeLock.isLocked();

[IO-510] Add and adapt ReadAheadInputStream and
BufferedFileChannelInputStream from Apache Spark.

Javadoc and better method names.