class RAFContainer4 extends RAFContainer
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:
FileChannel
Modifier and Type | Field and Description |
---|---|
private java.lang.Object |
channelCleanupMonitor |
private ContainerKey |
currentIdentity |
private boolean |
giveUpIO |
private java.lang.Object |
giveUpIOm |
private int |
iosInProgress
For debugging - will be incremented when an IO is started, decremented
when it is done.
|
private java.nio.channels.FileChannel |
ourChannel
This channel will be retrieved from RAFContainer's fileData
member when fileData is set.
|
private boolean |
restoreChannelInProgress |
private int |
threadsInPageIO |
fileData, needsSync
allocCache, canUpdate, CHECKSUM_SIZE, CONTAINER_INFO_SIZE, containerCache, containerInfo, containerVersion, dataFactory, estimatedRowCount, FIRST_ALLOC_PAGE_NUMBER, FIRST_ALLOC_PAGE_OFFSET, firstAllocPageNumber, firstAllocPageOffset, formatIdInteger, initialPages, isDirty, lastLogInstant, minimumRecordSize, pageCache, pageSize, preDirty, SPACE_TRACE, spareSpace
identity, isCommittedDrop, isDropped, isReusableRecordId
Constructor and Description |
---|
RAFContainer4(BaseDataFileFactory factory) |
Modifier and Type | Method and Description |
---|---|
private void |
awaitRestoreChannel(java.lang.Exception e,
boolean stealthMode)
Use when seeing an exception during IO and when another thread is
presumably doing the recovery.
|
(package private) void |
closeContainer()
override of RAFContainer#closeContainer
|
(package private) void |
createContainer(ContainerKey newIdentity)
override of RAFContainer#createContainer
|
private static void |
debugTrace(java.lang.String msg) |
private java.nio.channels.FileChannel |
getChannel()
Return the file channel for the current value of the
fileData
field. |
private java.nio.channels.FileChannel |
getChannel(StorageRandomAccessFile file)
Return the
FileChannel for the specified
StorageRandomAccessFile if it is a RandomAccessFile . |
(package private) byte[] |
getEmbryonicPage(StorageRandomAccessFile file,
long offset)
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
StorageRandomAccessFile . |
private void |
handleClosedChannel(java.nio.channels.ClosedChannelException e,
boolean stealthMode,
int retries)
This method handles what to do when, during a NIO operation we receive a
ClosedChannelException . |
(package private) boolean |
openContainer(ContainerKey newIdentity)
Open a container.
|
private void |
readFull(java.nio.ByteBuffer dstBuffer,
java.nio.channels.FileChannel srcChannel,
long position)
Attempts to fill buf completely from start until it's full.
|
protected void |
readPage(long pageNumber,
byte[] pageData)
Read a page into the supplied array.
|
private void |
readPage(long pageNumber,
byte[] pageData,
long offset)
Read a page into the supplied array.
|
private void |
readPage0(long pageNumber,
byte[] pageData,
long offset) |
private boolean |
recoverContainerAfterInterrupt(java.lang.String whence,
boolean 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 (
ourChannel ) has been closed due to
interrupt, we need to reopen the underlying RAF to get a fresh channel
so we can resume IO. |
(package private) void |
writeAtOffset(StorageRandomAccessFile file,
byte[] bytes,
long offset)
Write a sequence of bytes at the given offset in a file.
|
private void |
writeFull(java.nio.ByteBuffer srcBuffer,
java.nio.channels.FileChannel dstChannel,
long 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)
Write a page from the supplied array.
|
private void |
writePage0(long pageNumber,
byte[] pageData,
boolean syncPage) |
backupContainer, clean, encryptOrDecryptContainer, flushAll, getFileName, getRandomAccessFile, isDirty, preAllocate, privGetFileName, removeContainer, removeFile, reopenContainer, run, truncatePages, updatePageArray
bumpContainerVersion, canUpdate, clearIdentity, clearPreallocThreshold, compressContainer, createIdent, createIdentity, deallocatePage, decryptPage, doPreAllocatePages, dropContainer, encryptPage, getAllocPage, getAnyPage, getContainerProperties, getContainerVersion, getContextService, getEmbryonicPage, getEncryptionBuffer, getEstimatedPageCount, getEstimatedRowCount, getFirstHeadPage, getHeadPage, getLastPageNumber, getLatchedPage, getMinimumRecordSize, getNextHeadPage, getPage, getPageForCompress, getPageForInsert, getPageSize, getReusableRecordIdSequenceNumber, getSpaceInfo, getSpareSpace, getTypeFormatId, incrementReusableRecordIdSequenceNumber, initPage, latchPage, letGo, logCreateContainerInfo, newPage, preDirty, prepareForBulkLoad, readHeader, reCreatePageForRedoRecovery, setDirty, setEstimatedRowCount, setIdent, setIdentity, trackUnfilledPage, updateEstimatedRowCount, writeHeader, writeHeader
addPage, compressContainer, fillInIdentity, getAllocPage, getAnyPage, getCommittedDropState, getContainerId, getContainerStatus, getDeallocLock, getDroppedState, getFirstPage, getIdentity, getNextPage, getSegmentId, isReusableRecordId, lockAttributes, lockerAlwaysCompatible, lockEvent, removePage, requestCompatible, setCommittedDropState, setDroppedState, setReusableRecordIdState, truncate, unlockEvent, use
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
getIdentity
private java.nio.channels.FileChannel ourChannel
private final java.lang.Object channelCleanupMonitor
private volatile int threadsInPageIO
private volatile boolean restoreChannelInProgress
private boolean giveUpIO
private final java.lang.Object giveUpIOm
private int iosInProgress
private ContainerKey currentIdentity
public RAFContainer4(BaseDataFileFactory factory)
private java.nio.channels.FileChannel getChannel(StorageRandomAccessFile file)
FileChannel
for the specified
StorageRandomAccessFile
if it is a RandomAccessFile
.
Otherwise, return null
.file
- the file to get the channel forFileChannel
if file
is an instance of
RandomAccessFile
, null
otherwiseprivate java.nio.channels.FileChannel getChannel()
Return the file channel for the current value of the fileData
field. If fileData
doesn't support file channels, return
null
.
Callers of this method must synchronize on the container object since
two shared fields (fileData
and ourChannel
) are
accessed.
FileChannel
object, if supported, or null
boolean openContainer(ContainerKey newIdentity) throws StandardException
FileContainer
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.
MT - single thread required - Enforced by cache manager.
openContainer
in class RAFContainer
StandardException
- Standard exception policy.void createContainer(ContainerKey newIdentity) throws StandardException
createContainer
in class RAFContainer
StandardException
- Derby Standard error policyprivate void reopen() throws StandardException
ourChannel
) has been closed due to
interrupt, we need to reopen the underlying RAF to get a fresh channel
so we can resume IO.StandardException
void closeContainer()
closeContainer
in class RAFContainer
protected void readPage(long pageNumber, byte[] pageData) throws java.io.IOException, StandardException
readPage
in class RAFContainer
java.io.IOException
- exception reading pageStandardException
- Standard Derby error policyprivate void readPage(long pageNumber, byte[] pageData, long offset) throws java.io.IOException, StandardException
pageNumber
- the page number to read data from, or -1 (called from
getEmbryonicPage)pageData
- the buffer to read data intooffset
- -1 normally (not used since offset is computed from
pageNumber), but used if pageNumber == -1
(getEmbryonicPage)java.io.IOException
- exception reading pageStandardException
- Standard Derby error policyprivate void readPage0(long pageNumber, byte[] pageData, long offset) throws java.io.IOException, StandardException
java.io.IOException
StandardException
protected void writePage(long pageNumber, byte[] pageData, boolean syncPage) throws java.io.IOException, StandardException
writePage
in class RAFContainer
StandardException
- Standard Derby error policyjava.io.IOException
- IO error accessing pageprivate void handleClosedChannel(java.nio.channels.ClosedChannelException e, boolean stealthMode, int retries) throws StandardException
This method handles what to do when, during a NIO operation we receive a
ClosedChannelException
. Note the specialization hierarchy:
ClosedChannelException
-> AsynchronousCloseException
->
ClosedByInterruptException
If e
is a ClosedByInterruptException, we normally start
container recovery, i.e. we need to reopen the random access file so we
get get a new interruptible channel and continue IO.
If e
is a AsynchronousCloseException
or a plain ClosedChannelException
, the behavior depends of stealthMode
:
If stealthMode == false
, the method will wait for
another thread tp finish recovering the IO channel before returning.
If stealthMode == true
, the method throws InterruptDetectedException
, allowing retry at a higher level in the
code. The reason for this is that we sometimes need to release monitors
on objects needed by the recovery thread.
e
- Should be an instance of ClosedChannelException
.stealthMode
- If true
, do retry at a higher levelretries
- Give up waiting for another thread to reopen the channel
when retries
reaches 0. Only applicable if stealthMode == false
.InterruptDetectedException
- if retry at higher level is required
stealthMode == true
.StandardException
- standard error policy, incl. when we give up
waiting for another thread to reopen channelprivate void awaitRestoreChannel(java.lang.Exception e, boolean stealthMode) throws StandardException
stealthMode == false
, wait for another thread to recover the
container after an interrupt. If stealthMode == true
, throw
internal exception InterruptDetectedException
to do retry from
higher in the stack.
If stealthMode == false
, maximum wait time for the container to
become available again is determined by the product InterruptStatus.MAX_INTERRUPT_RETRIES *
InterruptStatus.INTERRUPT_RETRY_SLEEP
.
There is a chance this thread will not see any recovery occuring (yet),
in which case it waits for a bit and just returns, so the caller must
retry IO until success.
If for some reason the recovering thread has given up on resurrecting
the container, cf #giveUpIO
, the method throws FILE_IO_INTERRUPTED
.e
- the exception we saw during IOstealthMode
- true if the thread doing IO in stealth modeStandardException
- InterruptDetectedException
and normal
error policyprivate boolean recoverContainerAfterInterrupt(java.lang.String whence, boolean stealthMode) throws StandardException
whence
- caller site (debug info)stealthMode
- don't update threadsInPageIO if trueStandardException
private void writePage0(long pageNumber, byte[] pageData, boolean syncPage) throws java.io.IOException, StandardException
java.io.IOException
StandardException
void writeAtOffset(StorageRandomAccessFile file, byte[] bytes, long offset) throws java.io.IOException, StandardException
handleClosedChannel
.
This presumes that IO retry happens at a higher level, i.e. the
caller(s) must be prepared to handle InterruptDetectedException
.
This method overrides FileContainer#writeAtOffset.
writeAtOffset
in class FileContainer
file
- the file to write tobytes
- the bytes to writeoffset
- the offset to start writing atjava.io.IOException
- if an I/O error occurs while writingStandardException
- Derby Standard error policybyte[] getEmbryonicPage(StorageRandomAccessFile file, long offset) throws java.io.IOException, StandardException
StorageRandomAccessFile
.
override of FileContainer#getEmbryonicPage
getEmbryonicPage
in class FileContainer
file
- the file to read fromoffset
- where to start reading (normally
FileContainer.FIRST_ALLOC_PAGE_OFFSET
)java.io.IOException
- if an I/O error occurs while readingStandardException
- if thread is interrupted.private void readFull(java.nio.ByteBuffer dstBuffer, java.nio.channels.FileChannel srcChannel, long position) throws java.io.IOException, StandardException
dstBuffer
- buffer to read intosrcChannel
- channel to read fromposition
- file position from where to readjava.io.IOException
- if an I/O error occurs while readingStandardException
- If thread is interrupted.private void writeFull(java.nio.ByteBuffer srcBuffer, java.nio.channels.FileChannel dstChannel, long position) throws java.io.IOException
srcBuffer
- buffer to writedstChannel
- channel to write toposition
- file position to start writing atjava.io.IOException
- if an I/O error occurs while writingStandardException
- If thread is interrupted.private static void debugTrace(java.lang.String msg)
Apache Derby V10.13 Internals - Copyright © 2004,2016 The Apache Software Foundation. All Rights Reserved.