org.apache.derby.impl.store.raw.log
Class LogAccessFile

java.lang.Object
  extended byorg.apache.derby.impl.store.raw.log.LogAccessFile

public class LogAccessFile
extends java.lang.Object

Wraps a RandomAccessFile file to provide buffering on log writes. Only supports the write calls required for the log! MT - unsafe. Caller of this class must provide synchronization. The one exception is with the log file access, LogAccessFile will touch the log only inside synchronized block protected by the semaphore, which is defined by the creator of this object. Write to the log buffers are allowed when there are free buffers even when dirty buffers are being written(flushed) to the disk by a different thread. Only one flush writes to log file at a time, other wait for it to finish. Except for flushLogAccessFile , SyncAccessLogFile other function callers must provide syncronization that will allow only one of them to write to the buffers. Log Buffers are used in circular fashion, each buffer moves through following stages: freeBuffers --> dirtyBuffers --> freeBuffers. Movement of buffers from one stage to another stage is synchronized using the object(this) of this class. A Checksum log record that has the checksum value for the data that is being written to the disk is generated and written before the actual data. Except for the large log records that does not fit into a single buffer, checksum is calcualted for a group of log records that are in the buffer when buffers is switched. Checksum log record is written into the reserved space in the beginning buffer. In case of a large log record that does not fit into a bufffer, it needs to be written directly to the disk instead of going through the log buffers. In this case the log record write gets broken into three parts: 1) Write checksum log record and LOG RECORD HEADER (length + instant) 2) Write the log record. 3) Write the trailing length of the log record. Checksum log records helps in identifying the incomplete log disk writes during recovery. This is done by recalculating the checksum value for the data on the disk and comparing it to the the value stored in the checksum log record.


Field Summary
private  long checksumInstant
           
private  int checksumLength
           
private  ChecksumOperation checksumLogOperation
           
private  LogRecord checksumLogRecord
           
private  int checksumLogRecordSize
           
private  LogAccessFileBuffer currentBuffer
           
private  boolean databaseEncrypted
           
private  byte[] db
           
private  boolean directWrite
           
private  java.util.LinkedList dirtyBuffers
           
private  boolean flushInProgress
           
private  java.util.LinkedList freeBuffers
           
private  StorageRandomAccessFile log
           
private static int LOG_NUMBER_LOG_BUFFERS
           
private static int LOG_RECORD_FIXED_OVERHEAD_SIZE
          The fixed size of a log record is 16 bytes: int length : 4 bytes long instant : 8 bytes int trailing length : 4 bytes
private static int LOG_RECORD_HEADER_SIZE
           
private static int LOG_RECORD_TRAILER_SIZE
           
private  LogToFile logFactory
           
private  java.lang.Object logFileSemaphore
           
private  FormatIdOutputStream logicalOut
           
private  ArrayOutputStream logOutputBuffer
           
(package private) static int mon_numBytesToLog
           
(package private) static int mon_numWritesToLog
           
private  boolean writeChecksum
           
 
Constructor Summary
LogAccessFile(LogToFile logFactory, StorageRandomAccessFile log, int bufferSize)
           
 
Method Summary
 void close()
           
 void corrupt()
          The database is being marked corrupted, get rid of file pointer without writing out anything more.
protected  void flushDirtyBuffers()
          Write data from all dirty buffers into the log file.
 void flushLogAccessFile()
           
protected  long reserveSpaceForChecksum(int length, long logFileNumber, long currentPosition)
          reserve the space for the checksum log record in the log file.
 void switchLogBuffer()
          Appends the current Buffer to the dirty Buffer list and assigns a free buffer to be the currrent active buffer .
 void syncLogAccessFile()
          Guarantee all writes up to the last call to flushLogAccessFile on disk.
 void write(byte[] b, int off, int len)
           
 void write(int b)
           
private  void writeChecksumLogRecord()
           
protected  void writeEndMarker(int marker)
           
 void writeInt(int i)
           
private  int writeInt(int i, byte[] b, int p)
           
 void writeLogRecord(int length, long instant, byte[] data, int data_offset, byte[] optional_data, int optional_data_offset, int optional_data_length)
          Write a single log record to the stream.
 void writeLong(long l)
           
private  int writeLong(long l, byte[] b, int p)
           
private  void writeToLog(byte[] b, int off, int len)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

LOG_RECORD_FIXED_OVERHEAD_SIZE

private static final int LOG_RECORD_FIXED_OVERHEAD_SIZE
The fixed size of a log record is 16 bytes: int length : 4 bytes long instant : 8 bytes int trailing length : 4 bytes

See Also:
Constant Field Values

LOG_RECORD_HEADER_SIZE

private static final int LOG_RECORD_HEADER_SIZE
See Also:
Constant Field Values

LOG_RECORD_TRAILER_SIZE

private static final int LOG_RECORD_TRAILER_SIZE
See Also:
Constant Field Values

LOG_NUMBER_LOG_BUFFERS

private static final int LOG_NUMBER_LOG_BUFFERS
See Also:
Constant Field Values

freeBuffers

private java.util.LinkedList freeBuffers

dirtyBuffers

private java.util.LinkedList dirtyBuffers

currentBuffer

private LogAccessFileBuffer currentBuffer

flushInProgress

private boolean flushInProgress

log

private final StorageRandomAccessFile log

logFileSemaphore

private final java.lang.Object logFileSemaphore

mon_numWritesToLog

static int mon_numWritesToLog

mon_numBytesToLog

static int mon_numBytesToLog

logOutputBuffer

private ArrayOutputStream logOutputBuffer

logicalOut

private FormatIdOutputStream logicalOut

directWrite

private boolean directWrite

checksumInstant

private long checksumInstant

checksumLength

private int checksumLength

checksumLogRecordSize

private int checksumLogRecordSize

writeChecksum

private boolean writeChecksum

checksumLogOperation

private ChecksumOperation checksumLogOperation

checksumLogRecord

private LogRecord checksumLogRecord

logFactory

private LogToFile logFactory

databaseEncrypted

private boolean databaseEncrypted

db

private byte[] db
Constructor Detail

LogAccessFile

public LogAccessFile(LogToFile logFactory,
                     StorageRandomAccessFile log,
                     int bufferSize)
Method Detail

writeLogRecord

public void writeLogRecord(int length,
                           long instant,
                           byte[] data,
                           int data_offset,
                           byte[] optional_data,
                           int optional_data_offset,
                           int optional_data_length)
                    throws StandardException,
                           java.io.IOException
Write a single log record to the stream.

For performance pass all parameters rather into a specialized routine rather than maintaining the writeInt, writeLong, and write interfaces that this class provides as a standard OutputStream. It will make it harder to use other OutputStream implementations, but makes for less function calls and allows optimizations knowing when to switch buffers.

This routine handles all log records which are smaller than one log buffer. If a log record is bigger than a log buffer it calls writeUnbufferedLogRecord().

The log record written will always look the same as if the following code had been executed: writeInt(length) writeLong(instant) write(data, data_offset, (length - optional_data_length) ) if (optional_data_length != 0) write(optional_data, optional_data_offset, optional_data_length) writeInt(length)

Parameters:
length - (data + optional_data) length bytes to write
instant - the log address of this log record.
data - "from" array to copy "data" portion of rec
data_offset - offset in "data" to start copying from.
optional_data - "from" array to copy "optional data" from
optional_data_offset - offset in "optional_data" to start copy from
optional_data_length - length of optional data to copy.
Throws:
StandardException - Standard exception policy.
java.io.IOException

writeInt

private final int writeInt(int i,
                           byte[] b,
                           int p)

writeLong

private final int writeLong(long l,
                            byte[] b,
                            int p)

writeInt

public void writeInt(int i)

writeLong

public void writeLong(long l)

write

public void write(int b)

write

public void write(byte[] b,
                  int off,
                  int len)

flushDirtyBuffers

protected void flushDirtyBuffers()
                          throws java.io.IOException
Write data from all dirty buffers into the log file.

A call for clients of LogAccessFile to insure that all privately buffered data has been writen to the file - so that reads on the file using one of the various scan classes will see all the data which has been writen to this point.

Note that this routine only "writes" the data to the file, this does not mean that the data has been synced to disk unless file was opened in WRITE SYNC mode(rws/rwd). The only way to insure that is by calling is to call syncLogAccessFile() after this call in Non-WRITE sync mode(rw)

MT-Safe : parallel thereads can call this function, only one threads does the flush and the other threads waits for the one that is doing the flush to finish. Currently there are two possible threads that can call this function in parallel 1) A Thread that is doing the commit 2) A Thread that is writing to the log and log buffers are full or a log records does not fit in a buffer. (Log Buffers full(switchLogBuffer() or a log record size that is greater than logbuffer size has to be writtern through writeToLog call directlty) Note: writeToLog() is not synchronized on the semaphore that is used to do buffer management to allow writes to the free buffers when flush is in progress.

Throws:
java.io.IOException

flushLogAccessFile

public void flushLogAccessFile()
                        throws java.io.IOException,
                               StandardException
Throws:
java.io.IOException
StandardException

switchLogBuffer

public void switchLogBuffer()
                     throws java.io.IOException,
                            StandardException
Appends the current Buffer to the dirty Buffer list and assigns a free buffer to be the currrent active buffer . Flushing of the buffer to disk is delayed if there is a free buffer available. dirty buffers will be flushed to the disk when flushDirtyBuffers() is invoked by a commit call or when no more free buffers are available.

Throws:
java.io.IOException
StandardException

syncLogAccessFile

public void syncLogAccessFile()
                       throws java.io.IOException,
                              StandardException
Guarantee all writes up to the last call to flushLogAccessFile on disk.

A call for clients of LogAccessFile to insure that all data written up to the last call to flushLogAccessFile() are written to disk. This call will not return until those writes have hit disk.

Note that this routine may block waiting for I/O to complete so callers should limit the number of resource held locked while this operation is called. It is expected that the caller Note that this routine only "writes" the data to the file, this does not mean that the data has been synced to disk. The only way to insure that is to first call switchLogBuffer() and then follow by a call of sync().

Throws:
java.io.IOException
StandardException

corrupt

public void corrupt()
             throws java.io.IOException
The database is being marked corrupted, get rid of file pointer without writing out anything more.

Throws:
java.io.IOException

close

public void close()
           throws java.io.IOException,
                  StandardException
Throws:
java.io.IOException
StandardException

writeToLog

private void writeToLog(byte[] b,
                        int off,
                        int len)
                 throws java.io.IOException
Throws:
java.io.IOException

reserveSpaceForChecksum

protected long reserveSpaceForChecksum(int length,
                                       long logFileNumber,
                                       long currentPosition)
                                throws StandardException,
                                       java.io.IOException
reserve the space for the checksum log record in the log file.

Parameters:
length - the length of the log record to be written
logFileNumber - current log file number
currentPosition - current position in the log file.
Returns:
the space that is needed to write a checksum log record.
Throws:
StandardException
java.io.IOException

writeChecksumLogRecord

private void writeChecksumLogRecord()
                             throws java.io.IOException,
                                    StandardException
Throws:
java.io.IOException
StandardException

writeEndMarker

protected void writeEndMarker(int marker)
                       throws java.io.IOException,
                              StandardException
Throws:
java.io.IOException
StandardException

Built on Tue 2006-10-10 19:23:47+0200, from revision exported

Apache Derby V10.1 Engine Documentation - Copyright © 1997,2005 The Apache Software Foundation or its licensors, as applicable.