package com.sleepycat.je.log.entry;
import java.nio.ByteBuffer;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.dbi.DatabaseId;
import com.sleepycat.je.dbi.EnvironmentImpl;
import com.sleepycat.je.log.LogEntryType;
import com.sleepycat.je.log.LogUtils;
import com.sleepycat.je.log.LoggableObject;
import com.sleepycat.je.tree.IN;
import com.sleepycat.je.utilint.DbLsn;
import de.ovgu.cide.jakutil.*;
/**
* INLogEntry embodies all IN log entries. These entries contain an IN and a
* databaseId. This class can both write out an entry and read one in.
*/
public class INLogEntry implements LogEntry, LoggableObject, NodeLogEntry, INContainingEntry {
private IN in;
private DatabaseId dbId;
private long obsoleteLsn;
private long nodeId;
private Class logClass;
/**
* Construct a log entry for reading.
*/
public INLogEntry( Class logClass){
this.logClass=logClass;
}
/**
* Construct a log entry for writing to the log.
*/
public INLogEntry( IN in){
this.in=in;
this.dbId=in.getDatabase().getId();
this.logClass=in.getClass();
this.nodeId=in.getNodeId();
this.obsoleteLsn=in.getLastFullVersion();
}
/**
* Read in an IN entry.
*/
public void readEntry( ByteBuffer entryBuffer, int entrySize, byte entryTypeVersion, boolean readFullItem) throws DatabaseException {
entryTypeVersion&=LogEntryType.clearProvisional(entryTypeVersion);
try {
if (readFullItem) {
in=(IN)logClass.newInstance();
in.readFromLog(entryBuffer,entryTypeVersion);
nodeId=in.getNodeId();
}
else {
int position=entryBuffer.position() + entrySize;
if (entryTypeVersion == 1) {
position-=LogUtils.UNSIGNED_INT_BYTES;
}
else if (entryTypeVersion >= 2) {
position-=LogUtils.LONG_BYTES;
}
position-=LogUtils.INT_BYTES;
nodeId=LogUtils.readLong(entryBuffer);
entryBuffer.position(position);
in=null;
}
dbId=new DatabaseId();
dbId.readFromLog(entryBuffer,entryTypeVersion);
if (entryTypeVersion < 1) {
obsoleteLsn=DbLsn.NULL_LSN;
}
else if (entryTypeVersion == 1) {
long fileNum=LogUtils.getUnsignedInt(entryBuffer);
if (fileNum == 0xffffffffL) {
obsoleteLsn=DbLsn.NULL_LSN;
}
else {
obsoleteLsn=DbLsn.makeLsn(fileNum,0);
}
}
else {
obsoleteLsn=LogUtils.readLong(entryBuffer);
}
}
catch ( IllegalAccessException e) {
throw new DatabaseException(e);
}
catch ( InstantiationException e) {
throw new DatabaseException(e);
}
}
/**
* Returns the LSN of the prior version of this node. Used for counting
* the prior version as obsolete. If the offset of the LSN is zero, only
* the file number is known because we read a version 1 log entry.
*/
public long getObsoleteLsn(){
return obsoleteLsn;
}
/**
* Print out the contents of an entry.
*/
public StringBuffer dumpEntry( StringBuffer sb, boolean verbose){
in.dumpLog(sb,verbose);
dbId.dumpLog(sb,verbose);
return sb;
}
/**
* @return the item in the log entry
*/
public Object getMainItem(){
return in;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
/**
* @see LogEntry#isTransactional
*/
public boolean isTransactional(){
return false;
}
/**
* @see LogEntry#getTransactionId
*/
public long getTransactionId(){
return 0;
}
/**
* @see LoggableObject#getLogType
*/
public LogEntryType getLogType(){
return in.getLogType();
}
/**
* @see LoggableObject#marshallOutsideWriteLatchAsk the in if it can be marshalled outside the log write latch.
*/
public boolean marshallOutsideWriteLatch(){
return in.marshallOutsideWriteLatch();
}
/**
* @see LoggableObject#countAsObsoleteWhenLogged
*/
public boolean countAsObsoleteWhenLogged(){
return false;
}
/**
* @see LoggableObject#postLogWork
*/
public void postLogWork( long justLoggedLsn){
}
/**
* @see LoggableObject#getLogSize
*/
public int getLogSize(){
return (in.getLogSize() + dbId.getLogSize() + LogUtils.LONG_BYTES);
}
/**
* @see LoggableObject#writeToLog
*/
public void writeToLog( ByteBuffer destBuffer){
in.writeToLog(destBuffer);
dbId.writeToLog(destBuffer);
LogUtils.writeLong(destBuffer,obsoleteLsn);
}
public IN getIN( EnvironmentImpl env) throws DatabaseException {
return in;
}
/**
* @see NodeLogEntry#getNodeId
*/
public long getNodeId(){
return nodeId;
}
/**
* @see INContainingEntry#getDbId()
*/
public DatabaseId getDbId(){
return (DatabaseId)dbId;
}
/**
* @return the LSN that represents this IN. For a vanilla IN entry, it's
* the last lsn read by the log reader.
*/
public long getLsnOfIN( long lastReadLsn){
return lastReadLsn;
}
}