Note that our requests for multiple concurrent IOs may be serialized further down in the IO stack - this is entirely up to the JVM and OS. However, at least in Linux on Sun's 1.4.2_09 JVM we see the desired behavior: The FileChannel.read/write(ByteBuffer buf, long position) calls map to pread/pwrite system calls, which enable efficient IO to the same file descriptor by multiple threads.
This whole class should be merged back into RAFContainer when Derby officially stops supporting Java 1.3.
Significant behavior changes from RAFContainer:
java.nio.channels.FileChannel
| Modifier and Type | Field and Description |
|---|---|
| private final Object | |
| private ContainerKey | |
| private boolean | |
| private final Object | |
| private int | iosInProgress
For debugging - will be incremented when an IO is started, decremented when it is done. |
| private FileChannel | ourChannel
This channel will be retrieved from RAFContainer's fileData member when fileData is set. |
| private volatile boolean | |
| private volatile int |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| private void | awaitRestoreChannel(Exception
the exception we saw during IO e, boolean true if the thread doing IO in stealth mode stealthMode)Use when seeing an exception during IO and when another thread is presumably doing the recovery. |
| pack-priv synchronized void | closeContainer()
Overrides org. override of RAFContainer#closeContainer |
| pack-priv synchronized void | createContainer(ContainerKey newIdentity)
Overrides org. override of RAFContainer#createContainer |
| private static void | |
| private FileChannel | Returns: aFileChannel if file is an instance of
RandomAccessFile, null otherwisethe file to get the channel for file)Return the |
| private FileChannel | Returns: aFileChannel object, if supported, or null
Return the file channel for the current value of the |
| pack-priv byte[] | Returns: a byte array containing the embryonic pagethe file to read from file, long where to start reading (normally
offset)FileContainer.FIRST_ALLOC_PAGE_OFFSET)Overrides org. Read an embryonic page (that is, a section of the first alloc page that
is so large that we know all the borrowed space is included in it) from
the specified offset in a |
| private void | handleClosedChannel(ClosedChannelException
Should be an instance of e, boolean ClosedChannelException.If stealthMode, int true, do retry at a higher levelGive up waiting for another thread to reopen the channel
when retries)retries reaches 0. Only applicable if stealthMode == false.
This method handles what to do when, during a NIO operation we receive a
|
| pack-priv synchronized boolean | openContainer(ContainerKey newIdentity)
Overrides org. Open a container. |
| private void | readFull(ByteBuffer
buffer to read into dstBuffer, FileChannel channel to read from srcChannel, long file position from where to read position)Attempts to fill buf completely from start until it's full. |
| protected void | readPage(long pageNumber, byte[] pageData)
Overrides org. Read a page into the supplied array. |
| private void | readPage(long
the page number to read data from, or -1 (called from
getEmbryonicPage) pageNumber, byte[] the buffer to read data into pageData, long -1 normally (not used since offset is computed from
pageNumber), but used if pageNumber == -1
(getEmbryonicPage) offset)Read a page into the supplied array. |
| private void | |
| private boolean | Returns: true if we did recovery, false if we saw someone else do it and abstainedcaller site (debug info) whence, boolean don't update threadsInPageIO if true stealthMode)Use this when the thread has received a ClosedByInterruptException (or, prior to JDK 1.7 it may also be AsynchronousCloseException - a bug) exception during IO and its interruped flag is also set. |
| private void | reopen()
When the existing channel ( |
| pack-priv void | writeAtOffset(StorageRandomAccessFile
the file to write to file, byte[] the bytes to write bytes, long the offset to start writing at offset)Overrides org. Write a sequence of bytes at the given offset in a file. |
| private void | writeFull(ByteBuffer
buffer to write srcBuffer, FileChannel channel to write to dstChannel, long file position to start writing at position)Attempts to write buf completely from start until end, at the given position in the destination fileChannel. |
| protected void | writePage(long pageNumber, byte[] pageData, boolean syncPage)
Overrides org. Write a page from the supplied array. |
| private void |
| channelCleanupMonitor | back to summary |
|---|---|
| private final Object channelCleanupMonitor | |
| currentIdentity | back to summary |
|---|---|
| private ContainerKey currentIdentity | |
| giveUpIO | back to summary |
|---|---|
| private boolean giveUpIO | |
| giveUpIOm | back to summary |
|---|---|
| private final Object giveUpIOm | |
| iosInProgress | back to summary |
|---|---|
| private int iosInProgress For debugging - will be incremented when an IO is started, decremented when it is done. Should be == 0 when container state is changed. | |
| ourChannel | back to summary |
|---|---|
| private FileChannel ourChannel This channel will be retrieved from RAFContainer's fileData member when fileData is set. We wrap a couple of RAFContainer's methods to accomplish this. | |
| restoreChannelInProgress | back to summary |
|---|---|
| private volatile boolean restoreChannelInProgress | |
| threadsInPageIO | back to summary |
|---|---|
| private volatile int threadsInPageIO | |
| RAFContainer4 | back to summary |
|---|---|
| public RAFContainer4(BaseDataFileFactory factory) | |
| awaitRestoreChannel | back to summary |
|---|---|
| private void awaitRestoreChannel(Exception e, boolean stealthMode) throws StandardException Use when seeing an exception during IO and when another thread is presumably doing the recovery.
If
If
If for some reason the recovering thread has given up on resurrecting
the container, cf
| |
| closeContainer | back to summary |
|---|---|
| pack-priv synchronized void closeContainer() Overrides org. override of RAFContainer#closeContainer | |
| createContainer | back to summary |
|---|---|
| pack-priv synchronized void createContainer(ContainerKey newIdentity) throws StandardException Overrides org. override of RAFContainer#createContainer
| |
| debugTrace | back to summary |
|---|---|
| private static void debugTrace(String msg) | |
| getChannel | back to summary |
|---|---|
| private FileChannel getChannel(StorageRandomAccessFile file) Return the
| |
| getChannel | back to summary |
|---|---|
| private FileChannel getChannel()
Return the file channel for the current value of the
Callers of this method must synchronize on the container object since
two shared fields (
| |
| getEmbryonicPage | back to summary |
|---|---|
| pack-priv byte[] getEmbryonicPage(StorageRandomAccessFile file, long offset) throws IOException, StandardException Overrides org. Read an embryonic page (that is, a section of the first alloc page that
is so large that we know all the borrowed space is included in it) from
the specified offset in a override of FileContainer#getEmbryonicPage
| |
| handleClosedChannel | back to summary |
|---|---|
| private void handleClosedChannel(ClosedChannelException e, boolean stealthMode, int retries) throws StandardException
This method handles what to do when, during a NIO operation we receive a
If
If
If
If
| |
| openContainer | back to summary |
|---|---|
| pack-priv synchronized boolean openContainer(ContainerKey newIdentity) throws StandardException Overrides org. Doc from org. Open a container. Longer descrption of routine.
Open a container. Open the file that maps to this container, if the
file does not exist then we assume the container was never created.
If the file exists but we have trouble opening it then we throw some
exception.
| |
| readFull | back to summary |
|---|---|
| private void readFull(ByteBuffer dstBuffer, FileChannel srcChannel, long position) throws IOException, StandardException Attempts to fill buf completely from start until it's full. FileChannel has no readFull() method, so we roll our own.
| |
| readPage | back to summary |
|---|---|
| protected void readPage(long pageNumber, byte[] pageData) throws IOException, StandardException Overrides org. Read a page into the supplied array. override of RAFContainer#readPage
| |
| readPage | back to summary |
|---|---|
| private void readPage(long pageNumber, byte[] pageData, long offset) throws IOException, StandardException Read a page into the supplied array. override of RAFContainer#readPage
| |
| readPage0 | back to summary |
|---|---|
| private void readPage0(long pageNumber, byte[] pageData, long offset) throws IOException, StandardException | |
| recoverContainerAfterInterrupt | back to summary |
|---|---|
| private boolean recoverContainerAfterInterrupt(String whence, boolean stealthMode) throws StandardException Use this when the thread has received a ClosedByInterruptException (or, prior to JDK 1.7 it may also be AsynchronousCloseException - a bug) exception during IO and its interruped flag is also set. This makes this thread a likely candicate to do container recovery, unless another thread started it already, cf. return value.
| |
| reopen | back to summary |
|---|---|
| private void reopen() throws StandardException When the existing channel ( | |
| writeAtOffset | back to summary |
|---|---|
| pack-priv void writeAtOffset(StorageRandomAccessFile file, byte[] bytes, long offset) throws IOException, StandardException Overrides org. Write a sequence of bytes at the given offset in a file. This method
operates in stealth mode, see doc for This method overrides FileContainer#writeAtOffset.
| |
| writeFull | back to summary |
|---|---|
| private void writeFull(ByteBuffer srcBuffer, FileChannel dstChannel, long position) throws IOException Attempts to write buf completely from start until end, at the given position in the destination fileChannel. FileChannel has no writeFull() method, so we roll our own.
| |
| writePage | back to summary |
|---|---|
| protected void writePage(long pageNumber, byte[] pageData, boolean syncPage) throws IOException, StandardException Overrides org. Write a page from the supplied array. override of RAFContainer#writePage
| |
| writePage0 | back to summary |
|---|---|
| private void writePage0(long pageNumber, byte[] pageData, boolean syncPage) throws IOException, StandardException | |