001: /*-
002: * See the file LICENSE for redistribution information.
003: *
004: * Copyright (c) 2002,2008 Oracle. All rights reserved.
005: *
006: * $Id: CleanerFileReader.java,v 1.34.2.4 2008/01/07 15:14:13 cwl Exp $
007: */
008:
009: package com.sleepycat.je.log;
010:
011: import java.io.IOException;
012: import java.nio.ByteBuffer;
013: import java.util.HashMap;
014: import java.util.Map;
015:
016: import com.sleepycat.je.DatabaseException;
017: import com.sleepycat.je.dbi.DatabaseId;
018: import com.sleepycat.je.dbi.EnvironmentImpl;
019: import com.sleepycat.je.log.entry.INLogEntry;
020: import com.sleepycat.je.log.entry.LNLogEntry;
021: import com.sleepycat.je.log.entry.LogEntry;
022: import com.sleepycat.je.tree.IN;
023: import com.sleepycat.je.tree.LN;
024: import com.sleepycat.je.utilint.DbLsn;
025:
026: /**
027: * CleanerFileReader scans log files for INs and LNs.
028: */
029: public class CleanerFileReader extends FileReader {
030: private static final byte IS_IN = 0;
031: private static final byte IS_LN = 1;
032: private static final byte IS_ROOT = 2;
033: private static final byte IS_FILEHEADER = 3;
034:
035: private Map targetEntryMap;
036: private LogEntry targetLogEntry;
037: private byte targetCategory;
038:
039: /**
040: * Create this reader to start at a given LSN.
041: * @param env The relevant EnvironmentImpl.
042: * @param readBufferSize buffer size in bytes for reading in log.
043: * @param startLsn where to start in the log, or null for the beginning.
044: * @param fileNum single file number.
045: */
046: public CleanerFileReader(EnvironmentImpl env, int readBufferSize,
047: long startLsn, Long fileNum) throws IOException,
048: DatabaseException {
049:
050: super (env, readBufferSize, true, // forward
051: startLsn, fileNum, // single file number
052: DbLsn.NULL_LSN, // endOfFileLsn
053: DbLsn.NULL_LSN); // finishLsn
054:
055: targetEntryMap = new HashMap();
056:
057: addTargetType(IS_LN, LogEntryType.LOG_LN_TRANSACTIONAL);
058: addTargetType(IS_LN, LogEntryType.LOG_LN);
059: addTargetType(IS_LN, LogEntryType.LOG_NAMELN_TRANSACTIONAL);
060: addTargetType(IS_LN, LogEntryType.LOG_NAMELN);
061: addTargetType(IS_LN, LogEntryType.LOG_MAPLN_TRANSACTIONAL);
062: addTargetType(IS_LN, LogEntryType.LOG_MAPLN);
063: addTargetType(IS_LN, LogEntryType.LOG_DEL_DUPLN_TRANSACTIONAL);
064: addTargetType(IS_LN, LogEntryType.LOG_DEL_DUPLN);
065: addTargetType(IS_LN, LogEntryType.LOG_DUPCOUNTLN_TRANSACTIONAL);
066: addTargetType(IS_LN, LogEntryType.LOG_DUPCOUNTLN);
067: addTargetType(IS_LN, LogEntryType.LOG_FILESUMMARYLN);
068: addTargetType(IS_IN, LogEntryType.LOG_IN);
069: addTargetType(IS_IN, LogEntryType.LOG_BIN);
070: addTargetType(IS_IN, LogEntryType.LOG_DIN);
071: addTargetType(IS_IN, LogEntryType.LOG_DBIN);
072: addTargetType(IS_ROOT, LogEntryType.LOG_ROOT);
073: addTargetType(IS_FILEHEADER, LogEntryType.LOG_FILE_HEADER);
074: }
075:
076: private void addTargetType(byte category, LogEntryType entryType)
077: throws DatabaseException {
078:
079: targetEntryMap.put(entryType, new EntryInfo(entryType
080: .getNewLogEntry(), category));
081: }
082:
083: /**
084: * Helper for determining the starting position and opening
085: * up a file at the desired location.
086: */
087: protected void initStartingPosition(long endOfFileLsn, Long fileNum)
088: throws IOException, DatabaseException {
089:
090: eof = false;
091:
092: /*
093: * Start off at the startLsn. If that's null, start at the
094: * beginning of the log. If there are no log files, set
095: * eof.
096: */
097: readBufferFileNum = fileNum.longValue();
098: readBufferFileEnd = 0;
099:
100: /*
101: * After we read the first entry, the currentEntry will
102: * point here.
103: */
104: nextEntryOffset = readBufferFileEnd;
105: }
106:
107: /**
108: * @return true if this is a type we're interested in.
109: */
110: protected boolean isTargetEntry(byte entryTypeNum,
111: byte entryTypeVersion) {
112:
113: LogEntryType fromLogType = new LogEntryType(entryTypeNum,
114: entryTypeVersion);
115:
116: /* Is it a target entry? */
117: EntryInfo info = (EntryInfo) targetEntryMap.get(fromLogType);
118: if (info == null) {
119: return false;
120: } else {
121: targetCategory = info.targetCategory;
122: targetLogEntry = info.targetLogEntry;
123: return true;
124: }
125: }
126:
127: /**
128: * This reader instantiates an LN and key for every LN entry.
129: */
130: protected boolean processEntry(ByteBuffer entryBuffer)
131: throws DatabaseException {
132:
133: readEntry(targetLogEntry, entryBuffer, true); // readFullItem
134: return true;
135: }
136:
137: /**
138: * @return true if the last entry was an IN.
139: */
140: public boolean isIN() {
141: return (targetCategory == IS_IN);
142: }
143:
144: /**
145: * @return true if the last entry was a LN.
146: */
147: public boolean isLN() {
148: return (targetCategory == IS_LN);
149: }
150:
151: /**
152: * @return true if the last entry was a root
153: */
154: public boolean isRoot() {
155: return (targetCategory == IS_ROOT);
156: }
157:
158: public boolean isFileHeader() {
159: return (targetCategory == IS_FILEHEADER);
160: }
161:
162: /**
163: * Get the last LN seen by the reader.
164: */
165: public LN getLN() {
166: return ((LNLogEntry) targetLogEntry).getLN();
167: }
168:
169: /**
170: * Get the last entry seen by the reader as an IN.
171: */
172: public IN getIN() throws DatabaseException {
173:
174: return ((INLogEntry) targetLogEntry).getIN(envImpl);
175: }
176:
177: public FileHeader getFileHeader() throws DatabaseException {
178:
179: return (FileHeader) (targetLogEntry.getMainItem());
180: }
181:
182: /**
183: * Get the last databaseId seen by the reader.
184: */
185: public DatabaseId getDatabaseId() {
186: if (targetCategory == IS_LN) {
187: return ((LNLogEntry) targetLogEntry).getDbId();
188: } else if (targetCategory == IS_IN) {
189: return ((INLogEntry) targetLogEntry).getDbId();
190: } else {
191: return null;
192: }
193: }
194:
195: /**
196: * Get the last key seen by the reader.
197: */
198: public byte[] getKey() {
199: return ((LNLogEntry) targetLogEntry).getKey();
200: }
201:
202: /**
203: * Get the last key seen by the reader.
204: */
205: public byte[] getDupTreeKey() {
206: return ((LNLogEntry) targetLogEntry).getDupKey();
207: }
208:
209: private static class EntryInfo {
210: public LogEntry targetLogEntry;
211: public byte targetCategory;
212:
213: EntryInfo(LogEntry targetLogEntry, byte targetCategory) {
214: this.targetLogEntry = targetLogEntry;
215: this.targetCategory = targetCategory;
216: }
217: }
218: }
|