package com.sleepycat.je.log;
import java.util.HashSet;
import java.util.Set;
import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.log.entry.BINDeltaLogEntry;
import com.sleepycat.je.log.entry.DeletedDupLNLogEntry;
import com.sleepycat.je.log.entry.INLogEntry;
import com.sleepycat.je.log.entry.LNLogEntry;
import com.sleepycat.je.log.entry.LogEntry;
import com.sleepycat.je.log.entry.SingleItemLogEntry;
import de.ovgu.cide.jakutil.*;
/**
* LogEntryType is a type safe enumeration of all log entry types.
* <p>When adding a new version of a log entry, make sure the owning Loggable
* object is capable of reading in older versions from the log. The Loggable
* object must be sure that older versions are converted in memory into a
* correct instance of the newest version, so when that Loggable object is
* written again as the result of migration, eviction, the resulting new log
* entry conforms to the requirements of the new version. If context objects
* are required for data conversion, the conversion can be done in the
* Node.postFetchInit method.</p>
*/
public class LogEntryType {
private static final int MAX_TYPE_NUM=27;
private static LogEntryType[] LOG_TYPES=new LogEntryType[MAX_TYPE_NUM];
public static final LogEntryType LOG_LN_TRANSACTIONAL=new LogEntryType((byte)1,(byte)0,"LN_TX",new LNLogEntry(com.sleepycat.je.tree.LN.class,true));
public static final LogEntryType LOG_LN=new LogEntryType((byte)2,(byte)0,"LN",new LNLogEntry(com.sleepycat.je.tree.LN.class,false));
public static final LogEntryType LOG_MAPLN_TRANSACTIONAL=new LogEntryType((byte)3,(byte)1,"MapLN_TX",new LNLogEntry(com.sleepycat.je.tree.MapLN.class,true));
public static final LogEntryType LOG_MAPLN=new LogEntryType((byte)4,(byte)1,"MapLN",new LNLogEntry(com.sleepycat.je.tree.MapLN.class,false));
public static final LogEntryType LOG_NAMELN_TRANSACTIONAL=new LogEntryType((byte)5,(byte)0,"NameLN_TX",new LNLogEntry(com.sleepycat.je.tree.NameLN.class,true));
public static final LogEntryType LOG_NAMELN=new LogEntryType((byte)6,(byte)0,"NameLN",new LNLogEntry(com.sleepycat.je.tree.NameLN.class,false));
public static final LogEntryType LOG_DEL_DUPLN_TRANSACTIONAL=new LogEntryType((byte)7,(byte)0,"DelDupLN_TX",new DeletedDupLNLogEntry(true));
public static final LogEntryType LOG_DEL_DUPLN=new LogEntryType((byte)8,(byte)0,"DelDupLN",new DeletedDupLNLogEntry(false));
public static final LogEntryType LOG_DUPCOUNTLN_TRANSACTIONAL=new LogEntryType((byte)9,(byte)0,"DupCountLN_TX",new LNLogEntry(com.sleepycat.je.tree.DupCountLN.class,true));
public static final LogEntryType LOG_DUPCOUNTLN=new LogEntryType((byte)10,(byte)0,"DupCountLN",new LNLogEntry(com.sleepycat.je.tree.DupCountLN.class,false));
public static final LogEntryType LOG_FILESUMMARYLN=new LogEntryType((byte)11,(byte)2,"FileSummaryLN",new LNLogEntry(com.sleepycat.je.tree.FileSummaryLN.class,false));
public static final LogEntryType LOG_IN=new LogEntryType((byte)12,(byte)2,"IN",new INLogEntry(com.sleepycat.je.tree.IN.class));
public static final LogEntryType LOG_BIN=new LogEntryType((byte)13,(byte)2,"BIN",new INLogEntry(com.sleepycat.je.tree.BIN.class));
public static final LogEntryType LOG_DIN=new LogEntryType((byte)14,(byte)2,"DIN",new INLogEntry(com.sleepycat.je.tree.DIN.class));
public static final LogEntryType LOG_DBIN=new LogEntryType((byte)15,(byte)2,"DBIN",new INLogEntry(com.sleepycat.je.tree.DBIN.class));
public static final LogEntryType[] IN_TYPES={LogEntryType.LOG_IN,LogEntryType.LOG_BIN,LogEntryType.LOG_DIN,LogEntryType.LOG_DBIN};
/**
* If you add new types, be sure to update MAX_TYPE_NUM at the top.**
*/
private static final int MAX_NODE_TYPE_NUM=15;
public static boolean isNodeType( byte typeNum, byte version){
return (typeNum <= MAX_NODE_TYPE_NUM);
}
public static final LogEntryType LOG_ROOT=new LogEntryType((byte)16,(byte)1,"Root",new SingleItemLogEntry(com.sleepycat.je.dbi.DbTree.class));
public static final LogEntryType LOG_TXN_COMMIT=new LogEntryType((byte)17,(byte)0,"Commit",new SingleItemLogEntry(com.sleepycat.je.txn.TxnCommit.class));
public static final LogEntryType LOG_TXN_ABORT=new LogEntryType((byte)18,(byte)0,"Abort",new SingleItemLogEntry(com.sleepycat.je.txn.TxnAbort.class));
public static final LogEntryType LOG_CKPT_START=new LogEntryType((byte)19,(byte)0,"CkptStart",new SingleItemLogEntry(com.sleepycat.je.recovery.CheckpointStart.class));
public static final LogEntryType LOG_CKPT_END=new LogEntryType((byte)20,(byte)0,"CkptEnd",new SingleItemLogEntry(com.sleepycat.je.recovery.CheckpointEnd.class));
public static final LogEntryType LOG_IN_DELETE_INFO=new LogEntryType((byte)21,(byte)0,"INDelete",new SingleItemLogEntry(com.sleepycat.je.tree.INDeleteInfo.class));
public static final LogEntryType LOG_BIN_DELTA=new LogEntryType((byte)22,(byte)0,"BINDelta",new BINDeltaLogEntry(com.sleepycat.je.tree.BINDelta.class));
public static final LogEntryType LOG_DUP_BIN_DELTA=new LogEntryType((byte)23,(byte)0,"DupBINDelta",new BINDeltaLogEntry(com.sleepycat.je.tree.BINDelta.class));
public static final LogEntryType LOG_TRACE=new LogEntryType((byte)24,(byte)0,"Trace",new SingleItemLogEntry(com.sleepycat.je.utilint.Tracer.class));
public static final LogEntryType LOG_FILE_HEADER=new LogEntryType((byte)25,(byte)0,"FileHeader",new SingleItemLogEntry(com.sleepycat.je.log.FileHeader.class));
public static final LogEntryType LOG_IN_DUPDELETE_INFO=new LogEntryType((byte)26,(byte)0,"INDupDelete",new SingleItemLogEntry(com.sleepycat.je.tree.INDupDeleteInfo.class));
public static final LogEntryType LOG_TXN_PREPARE=new LogEntryType((byte)27,(byte)0,"Prepare",new SingleItemLogEntry(com.sleepycat.je.txn.TxnPrepare.class));
/**
* If you add new types, be sure to update MAX_TYPE_NUM at the top.**
*/
private static final byte PROVISIONAL_MASK=(byte)0x80;
private static final byte IGNORE_PROVISIONAL=~PROVISIONAL_MASK;
private byte typeNum;
private byte version;
private String displayName;
private LogEntry logEntry;
/**
* For base class support.
*/
LogEntryType( byte typeNum, byte version){
this.typeNum=typeNum;
this.version=version;
}
/**
* Create the static log types.
*/
private LogEntryType( byte typeNum, byte version, String displayName, LogEntry logEntry){
this.typeNum=typeNum;
this.version=version;
this.logEntry=logEntry;
this.displayName=displayName;
LOG_TYPES[typeNum - 1]=this;
}
public boolean isNodeType(){
return (typeNum <= MAX_NODE_TYPE_NUM);
}
/**
* @return the static version of this type
*/
public static LogEntryType findType( byte typeNum, byte version){
if (typeNum <= 0 || typeNum > MAX_TYPE_NUM) {
return null;
}
return (LogEntryType)LOG_TYPES[typeNum - 1];
}
/**
* Get a copy of all types for unit testing.
*/
public static Set getAllTypes(){
HashSet ret=new HashSet();
for (int i=0; i < MAX_TYPE_NUM; i++) {
ret.add(LOG_TYPES[i]);
}
return ret;
}
/**
* @return the log entry type owned by the shared, static version
*/
public LogEntry getSharedLogEntry(){
return logEntry;
}
/**
* @return a clone of the log entry type for a given log type.
*/
LogEntry getNewLogEntry() throws DatabaseException {
try {
return (LogEntry)logEntry.clone();
}
catch ( CloneNotSupportedException e) {
throw new DatabaseException(e);
}
}
/**
* Set the provisional bit.
*/
static byte setProvisional( byte version){
return (byte)(version | PROVISIONAL_MASK);
}
/**
* Clear the provisional bit.
*/
public static byte clearProvisional( byte version){
return (byte)(version & IGNORE_PROVISIONAL);
}
/**
* @return true if the provisional bit is set.
*/
static boolean isProvisional( byte version){
return ((version & PROVISIONAL_MASK) != 0);
}
byte getTypeNum(){
return typeNum;
}
byte getVersion(){
return version;
}
/**
* @return true if type number is valid.
*/
static boolean isValidType( byte typeNum){
return typeNum > 0 && typeNum <= MAX_TYPE_NUM;
}
public String toString(){
return displayName + "/" + version;
}
/**
* Check for equality without making a new object.
*/
boolean equalsType( byte typeNum, byte version){
return (this.typeNum == typeNum);
}
public boolean equalsType( byte typeNum){
return (this.typeNum == typeNum);
}
public boolean equals( Object obj){
if (this == obj) {
return true;
}
if (!(obj instanceof LogEntryType)) {
return false;
}
return typeNum == ((LogEntryType)obj).typeNum;
}
/**
* This is used as a hash key.
*/
public int hashCode(){
return typeNum;
}
}