/*
* Class com.neocoretechs.arieslogger.core.LogRecord
* writes a record to the log file containing transaction Id, 'Loggable' operation and the group
* value of the log record
*
*/
package com.neocoretechs.arieslogger.core.impl;
import com.neocoretechs.arieslogger.logrecords.Loggable;
import com.neocoretechs.arieslogger.logrecords.Undoable;
import com.neocoretechs.bigsack.io.pooled.GlobalDBIO;
import java.io.Externalizable;
import java.io.ObjectOutput;
import java.io.ObjectInput;
import java.io.IOException;
/**
The log record written out to disk. This log record includes:
<P>
This is a holder object that may be setup using the setValue() and re-used
rather than creating a new object for each actual log record.
<P> <PRE>
The format of a log record is
@.formatId LOG_RECORD
the formatId is written by FormatIdOutputStream when this object is
written out by writeObject
@.purpose The log record described every change to the persistent store
@.upgrade
@.diskLayout
loggable group(CompressedInt) the loggable's group value
xactId(TransactionId) The Transaction this log belongs to
op(Loggable) the log operation
@.endFormat
</PRE>
*/
public class LogRecord implements Externalizable {
public static long serialVersionUID = 1193478925184398366L;
private long xactId; // the transaction Id
private int group; // the loggable's group value
private Loggable op; // the loggable
private static final int LOG_RECORD = 0;
private static final boolean DEBUG = false;
public LogRecord() {}
public void reset() {
xactId = -1;
op = null;
group = Loggable.ALLGROUPS;
}
/**
Write this out.
@exception IOException error writing to log stream
*/
public void writeExternal(ObjectOutput out) throws IOException
{
out.writeInt(group);
out.writeLong(xactId);
out.writeObject(op);
}
public int getRecordSize() {
try {
return GlobalDBIO.getObjectAsBytes(this).length;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
Read this in
@exception IOException error reading from log stream
@exception ClassNotFoundException corrupted log stream
*/
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
group = in.readInt();
if( DEBUG ) {
System.out.println("LogRecord.readExternal group "+group);
}
xactId = in.readLong();
if( DEBUG ) {
System.out.println("LogRecord.readExternal xactId "+xactId);
}
op = (Loggable) in.readObject();
if( DEBUG ) {
System.out.println("LogRecord.readExternal op "+op);
}
}
/**
Return my format identifier.
*/
public int getTypeFormatId() {
return LOG_RECORD;
}
/*
* class specific methods
*/
public void setValue(long xactId, Loggable op)
{
this.xactId = xactId;
this.op = op;
this.group = op.group();
}
public static int maxGroupStoredSize()
{
return Integer.MAX_VALUE;
}
public static int maxTransactionIdStoredSize(long tranId)
{
return 8;
}
public long getTransactionId() throws IOException, ClassNotFoundException {
return xactId;
}
public Loggable getLoggable() throws IOException, ClassNotFoundException {
return op;
}
//public RePreparable getRePreparable() throws IOException, ClassNotFoundException
//{
// return((RePreparable) getLoggable());
//}
public Undoable getUndoable() throws IOException, ClassNotFoundException
{
if (op instanceof Undoable)
return (Undoable) op;
else
return null;
}
public boolean isCLR() {
return ((group & Loggable.COMPENSATION) != 0);
}
public boolean isFirst() {
return ((group & Loggable.FIRST) != 0);
}
public boolean isComplete() {
return ((group & Loggable.LAST) != 0);
}
public boolean isPrepare() {
return ((group & Loggable.PREPARE) != 0);
}
public boolean requiresPrepareLocks() {
return ((group & Loggable.XA_NEEDLOCK) != 0);
}
public boolean isCommit()
{
if (DEBUG)
{
assert((group & Loggable.LAST) == Loggable.LAST);//,
//"calling isCommit on log record that is not last");
assert((group & (Loggable.COMMIT | Loggable.ABORT)) != 0);//,
//"calling isCommit on log record before commit status is recorded");
}
return ((group & Loggable.COMMIT) != 0);
}
public boolean isAbort()
{
if (DEBUG)
{
assert((group & Loggable.LAST) == Loggable.LAST);//,
//"calling isAbort on log record that is not last");
assert((group & (Loggable.COMMIT | Loggable.ABORT)) != 0);//,
//"calling isAbort on log record before abort status is recorded");
}
return ((group & Loggable.ABORT) != 0);
}
public int group()
{
return group;
}
public boolean isChecksum() {
return ((group & Loggable.CHECKSUM) != 0);
}
}