com.sleepycat.je.log
Class FileManager.LogEndFileDescriptor
java.lang.Object
com.sleepycat.je.log.FileManager.LogEndFileDescriptor
- Enclosing class:
- FileManager
class FileManager.LogEndFileDescriptor
- extends Object
The LogEndFileDescriptor is used to write and fsync the end of the log.
Because the JE log is append only, there is only one logical R/W file
descriptor for the whole environment. This class actually implements two
RandomAccessFile instances, one for writing and one for fsyncing, so the
two types of operations don't block each other.
The write file descriptor is considered the master. Manipulation of
this class is done under the log write latch. Here's an explanation of
why the log write latch is sufficient to safeguard all operations.
There are two types of callers who may use this file descriptor: the
thread that is currently writing to the end of the log and any threads
that are fsyncing on behalf of the FSyncManager.
The writing thread appends data to the file and fsyncs the file when we
flip over to a new log file. The file is only instantiated at the point
that it must do so -- which is either when the first fsync is required
by JE or when the log file is full and we flip files. Therefore, the
writing thread has two actions that change this descriptor -- we
initialize the file descriptor for the given log file at the first write
to the file, and we close the file descriptor when the log file is full.
Therefore is a period when there is no log descriptor -- when we have
not yet written a log buffer into a given log file.
The fsyncing threads ask for the log end file descriptor asynchronously,
but will never modify it. These threads may arrive at the point when
the file descriptor is null, and therefore skip their fysnc, but that is
fine because it means a writing thread already flipped that target file
and has moved on to the next file.
Time Activity
10 thread 1 writes log entry A into file 0x0, issues fsync
outside of log write latch, yields the processor
20 thread 2 writes log entry B, piggybacks off thread 1
30 thread 3 writes log entry C, but no room left in that file,
so it flips the log, and fsyncs file 0x0, all under the log
write latch. It nulls out endOfLogRWFile, moves onto file
0x1, but doesn't create the file yet.
40 thread 1 finally comes along, but endOfLogRWFile is null--
no need to fsync in that case, 0x0 got fsynced.
If a write is attempted and an fsync is already in progress, then the
information pertaining to the data to be written (data, offset, length)
is saved away in the "queuedWrites" array. When the fsync completes,
the queuedWrites buffer is emptied. This ensures that writes continue
to execute on file systems which block all IO calls during an fsync()
call (e.g. ext3).
Method Summary |
(package private) boolean |
checkWriteCache(ByteBuffer readBuffer,
long requestedOffset,
long fileNum)
|
(package private) void |
close()
Close the end of the log file descriptor. |
(package private) boolean |
enqueueWrite(long fileNum,
byte[] data,
long destOffset,
int arrayOffset,
int size)
|
(package private) boolean |
hasQueuedWrites()
Returns whether anything is in the write queue. |
(package private) void |
setQueueFileNum(long qwFileNum)
|
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
FileManager.LogEndFileDescriptor
FileManager.LogEndFileDescriptor()
setQueueFileNum
void setQueueFileNum(long qwFileNum)
checkWriteCache
boolean checkWriteCache(ByteBuffer readBuffer,
long requestedOffset,
long fileNum)
enqueueWrite
boolean enqueueWrite(long fileNum,
byte[] data,
long destOffset,
int arrayOffset,
int size)
throws DatabaseException
- Throws:
DatabaseException
hasQueuedWrites
boolean hasQueuedWrites()
- Returns whether anything is in the write queue.
close
void close()
throws IOException
- Close the end of the log file descriptor. Use atomic assignment to
ensure that we won't force and close on the same descriptor.
- Throws:
IOException
Copyright (c) 2004-2012 Oracle. All rights reserved.