Skip to content

Commit 8cbe373

Browse files
author
Gary Gregory
committed
[IO-510] Add and adapt ReadAheadInputStream and
BufferedFileChannelInputStream from Apache Spark. Javadoc and better method names.
1 parent 0cc94ec commit 8cbe373

2 files changed

Lines changed: 22 additions & 15 deletions

File tree

src/main/java/org/apache/commons/io/input/BufferedFileChannelInputStream.java

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,30 @@ public synchronized int available() throws IOException {
9797
return byteBuffer.remaining();
9898
}
9999

100+
/**
101+
* Attempts to clean up a ByteBuffer if it is direct or memory-mapped. This uses an *unsafe* Sun API that will cause
102+
* errors if one attempts to read from the disposed buffer. However, neither the bytes allocated to direct buffers
103+
* nor file descriptors opened for memory-mapped buffers put pressure on the garbage collector. Waiting for garbage
104+
* collection may lead to the depletion of off-heap memory or huge numbers of open files. There's unfortunately no
105+
* standard API to manually dispose of these kinds of buffers.
106+
*
107+
* @param buffer the buffer to clean.
108+
*/
109+
private void clean(final ByteBuffer buffer) {
110+
if (buffer instanceof sun.nio.ch.DirectBuffer) {
111+
clean((sun.nio.ch.DirectBuffer) buffer);
112+
}
113+
}
114+
100115
/**
101116
* In Java 8, the type of DirectBuffer.cleaner() was sun.misc.Cleaner, and it was possible to access the method
102117
* sun.misc.Cleaner.clean() to invoke it. The type changed to jdk.internal.ref.Cleaner in later JDKs, and the
103118
* .clean() method is not accessible even with reflection. However sun.misc.Unsafe added a invokeCleaner() method in
104119
* JDK 9+ and this is still accessible with reflection.
120+
*
121+
* @param buffer the buffer to clean.
105122
*/
106-
private void bufferCleaner(final DirectBuffer buffer) {
123+
private void clean(final DirectBuffer buffer) {
107124
//
108125
// Ported from StorageUtils.scala.
109126
//
@@ -159,20 +176,7 @@ public synchronized void close() throws IOException {
159176
try {
160177
fileChannel.close();
161178
} finally {
162-
dispose(byteBuffer);
163-
}
164-
}
165-
166-
/**
167-
* Attempts to clean up a ByteBuffer if it is direct or memory-mapped. This uses an *unsafe* Sun API that will cause
168-
* errors if one attempts to read from the disposed buffer. However, neither the bytes allocated to direct buffers
169-
* nor file descriptors opened for memory-mapped buffers put pressure on the garbage collector. Waiting for garbage
170-
* collection may lead to the depletion of off-heap memory or huge numbers of open files. There's unfortunately no
171-
* standard API to manually dispose of these kinds of buffers.
172-
*/
173-
private void dispose(final ByteBuffer buffer) {
174-
if (buffer instanceof sun.nio.ch.DirectBuffer) {
175-
bufferCleaner((sun.nio.ch.DirectBuffer) buffer);
179+
clean(byteBuffer);
176180
}
177181
}
178182

src/main/java/org/apache/commons/io/input/ReadAheadInputStream.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,9 @@ public long skip(final long n) throws IOException {
393393
/**
394394
* Internal skip function which should be called only from skip(). The assumption is that the stateChangeLock is
395395
* already acquired in the caller before calling this function.
396+
*
397+
* @param n the number of bytes to be skipped.
398+
* @return the actual number of bytes skipped.
396399
*/
397400
private long skipInternal(final long n) throws IOException {
398401
assert stateChangeLock.isLocked();

0 commit comments

Comments
 (0)