001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: CheckpointEnd.java,v 1.29.2.3 2008/01/07 15:14:14 cwl Exp $
007: */
008:
009: package com.sleepycat.je.recovery;
010:
011: import java.nio.ByteBuffer;
012: import java.sql.Timestamp;
013: import java.util.Calendar;
014:
015: import com.sleepycat.je.log.LogException;
016: import com.sleepycat.je.log.LogUtils;
017: import com.sleepycat.je.log.Loggable;
018: import com.sleepycat.je.utilint.DbLsn;
019:
020: /**
021: * CheckpointEnd encapsulates the information needed by a checkpoint end
022: * log entry.
023: */
024: public class CheckpointEnd implements Loggable {
025:
026: /*
027: * invoker is just a way to tag each checkpoint in the
028: * log for easier log based debugging. It will tell us whether the
029: * checkpoint was invoked by recovery, the daemon, the api, or
030: * the cleaner.
031: */
032: private String invoker;
033:
034: private Timestamp endTime;
035: private long checkpointStartLsn;
036: private boolean rootLsnExists;
037: private long rootLsn;
038: private long firstActiveLsn;
039: private long lastNodeId;
040: private int lastDbId;
041: private long lastTxnId;
042: private long id;
043:
044: public CheckpointEnd(String invoker, long checkpointStartLsn,
045: long rootLsn, long firstActiveLsn, long lastNodeId,
046: int lastDbId, long lastTxnId, long id) {
047: if (invoker == null) {
048: this .invoker = "";
049: } else {
050: this .invoker = invoker;
051: }
052:
053: Calendar cal = Calendar.getInstance();
054: this .endTime = new Timestamp(cal.getTime().getTime());
055: this .checkpointStartLsn = checkpointStartLsn;
056: this .rootLsn = rootLsn;
057: if (rootLsn == DbLsn.NULL_LSN) {
058: rootLsnExists = false;
059: } else {
060: rootLsnExists = true;
061: }
062: if (firstActiveLsn == DbLsn.NULL_LSN) {
063: this .firstActiveLsn = checkpointStartLsn;
064: } else {
065: this .firstActiveLsn = firstActiveLsn;
066: }
067: this .lastNodeId = lastNodeId;
068: this .lastDbId = lastDbId;
069: this .lastTxnId = lastTxnId;
070: this .id = id;
071: }
072:
073: /* For logging only */
074: public CheckpointEnd() {
075: checkpointStartLsn = DbLsn.NULL_LSN;
076: rootLsn = DbLsn.NULL_LSN;
077: firstActiveLsn = DbLsn.NULL_LSN;
078: }
079:
080: /*
081: * Logging support for writing to the log
082: */
083:
084: /**
085: * @see Loggable#getLogSize
086: */
087: public int getLogSize() {
088: int size = LogUtils.getStringLogSize(invoker) + // invoker
089: LogUtils.getTimestampLogSize() + // endTime
090: LogUtils.getLongLogSize() + // checkpointStartLsn
091: LogUtils.getBooleanLogSize() + // rootLsnExists
092: LogUtils.getLongLogSize() + // firstActiveLsn
093: LogUtils.getLongLogSize() + // lastNodeId
094: LogUtils.getIntLogSize() + // lastDbId
095: LogUtils.getLongLogSize() + // lastTxnId
096: LogUtils.getLongLogSize(); // id
097:
098: if (rootLsnExists) {
099: size += LogUtils.getLongLogSize();
100: }
101: return size;
102: }
103:
104: /**
105: * @see Loggable#writeToLog
106: */
107: public void writeToLog(ByteBuffer logBuffer) {
108: LogUtils.writeString(logBuffer, invoker);
109: LogUtils.writeTimestamp(logBuffer, endTime);
110: LogUtils.writeLong(logBuffer, checkpointStartLsn);
111: LogUtils.writeBoolean(logBuffer, rootLsnExists);
112: if (rootLsnExists) {
113: LogUtils.writeLong(logBuffer, rootLsn);
114: }
115: LogUtils.writeLong(logBuffer, firstActiveLsn);
116: LogUtils.writeLong(logBuffer, lastNodeId);
117: LogUtils.writeInt(logBuffer, lastDbId);
118: LogUtils.writeLong(logBuffer, lastTxnId);
119: LogUtils.writeLong(logBuffer, id);
120: }
121:
122: /**
123: * @see Loggable#readFromLog
124: */
125: public void readFromLog(ByteBuffer logBuffer, byte entryTypeVersion)
126: throws LogException {
127: invoker = LogUtils.readString(logBuffer);
128: endTime = LogUtils.readTimestamp(logBuffer);
129: checkpointStartLsn = LogUtils.readLong(logBuffer);
130: rootLsnExists = LogUtils.readBoolean(logBuffer);
131: if (rootLsnExists) {
132: rootLsn = LogUtils.readLong(logBuffer);
133: }
134: firstActiveLsn = LogUtils.readLong(logBuffer);
135: lastNodeId = LogUtils.readLong(logBuffer);
136: lastDbId = LogUtils.readInt(logBuffer);
137: lastTxnId = LogUtils.readLong(logBuffer);
138: id = LogUtils.readLong(logBuffer);
139: }
140:
141: /**
142: * @see Loggable#dumpLog
143: */
144: public void dumpLog(StringBuffer sb, boolean verbose) {
145: sb.append("<CkptEnd invoker=\"").append(invoker);
146: sb.append("\" time=\"").append(endTime);
147: sb.append("\" lastNodeId=\"").append(lastNodeId);
148: sb.append("\" lastDbId=\"").append(lastDbId);
149: sb.append("\" lastTxnId=\"").append(lastTxnId);
150: sb.append("\" id=\"").append(id);
151: sb.append("\" rootExists=\"").append(rootLsnExists);
152: sb.append("\">");
153: sb.append("<ckptStart>");
154: sb.append(DbLsn.toString(checkpointStartLsn));
155: sb.append("</ckptStart>");
156:
157: if (rootLsnExists) {
158: sb.append("<root>");
159: sb.append(DbLsn.toString(rootLsn));
160: sb.append("</root>");
161: }
162: sb.append("<firstActive>");
163: sb.append(DbLsn.toString(firstActiveLsn));
164: sb.append("</firstActive>");
165: sb.append("</CkptEnd>");
166: }
167:
168: /**
169: * @see Loggable#getTransactionId
170: */
171: public long getTransactionId() {
172: return 0;
173: }
174:
175: public String toString() {
176: StringBuffer sb = new StringBuffer();
177: sb.append("time=").append(endTime);
178: sb.append(" lastNodeId=").append(lastNodeId);
179: sb.append(" lastDbId=").append(lastDbId);
180: sb.append(" lastTxnId=").append(lastTxnId);
181: sb.append(" id=").append(id);
182: sb.append(" rootExists=").append(rootLsnExists);
183: sb.append(" ckptStartLsn=").append(
184: DbLsn.getNoFormatString(checkpointStartLsn));
185: if (rootLsnExists) {
186: sb.append(" root=")
187: .append(DbLsn.getNoFormatString(rootLsn));
188: }
189: sb.append(" firstActive=").append(
190: DbLsn.getNoFormatString(firstActiveLsn));
191: return sb.toString();
192: }
193:
194: /*
195: * Accessors
196: */
197: long getCheckpointStartLsn() {
198: return checkpointStartLsn;
199: }
200:
201: long getRootLsn() {
202: return rootLsn;
203: }
204:
205: long getFirstActiveLsn() {
206: return firstActiveLsn;
207: }
208:
209: long getLastNodeId() {
210: return lastNodeId;
211: }
212:
213: int getLastDbId() {
214: return lastDbId;
215: }
216:
217: long getLastTxnId() {
218: return lastTxnId;
219: }
220:
221: long getId() {
222: return id;
223: }
224: }
|