1 8 9 package com.sleepycat.je.log; 10 11 import java.io.File ; 12 import java.io.IOException ; 13 import java.nio.ByteBuffer ; 14 import java.util.HashMap ; 15 import java.util.HashSet ; 16 import java.util.Map ; 17 import java.util.Set ; 18 import java.util.logging.Level ; 19 20 import com.sleepycat.je.DatabaseException; 21 import com.sleepycat.je.dbi.EnvironmentImpl; 22 import com.sleepycat.je.utilint.DbLsn; 23 import com.sleepycat.je.utilint.Tracer; 24 25 30 public class LastFileReader extends FileReader { 31 32 33 private Set trackableEntries; 34 35 private long nextUnprovenOffset; 36 private long lastValidOffset; 37 private LogEntryType entryType; 38 39 43 private Map lastOffsetSeen; 44 45 48 public LastFileReader(EnvironmentImpl env, 49 int readBufferSize) 50 throws IOException , DatabaseException { 51 52 super(env, readBufferSize, true, DbLsn.NULL_LSN, new Long (-1), 53 DbLsn.NULL_LSN, DbLsn.NULL_LSN); 54 55 trackableEntries = new HashSet (); 56 lastOffsetSeen = new HashMap (); 57 58 lastValidOffset = 0; 59 anticipateChecksumErrors = true; 60 nextUnprovenOffset = nextEntryOffset; 61 } 62 63 68 public LastFileReader(EnvironmentImpl env, 69 int readBufferSize, 70 Long specificFileNumber) 71 throws IOException , DatabaseException { 72 73 super(env, readBufferSize, true, DbLsn.NULL_LSN, 74 specificFileNumber, DbLsn.NULL_LSN, DbLsn.NULL_LSN); 75 76 trackableEntries = new HashSet (); 77 lastOffsetSeen = new HashMap (); 78 79 lastValidOffset = 0; 80 anticipateChecksumErrors = true; 81 nextUnprovenOffset = nextEntryOffset; 82 } 83 84 87 protected void initStartingPosition(long endOfFileLsn, 88 Long singleFileNum) 89 throws IOException , DatabaseException { 90 91 eof = false; 92 93 97 Long lastNum = ((singleFileNum != null) && 98 (singleFileNum.longValue() >= 0)) ? 99 singleFileNum : 100 fileManager.getLastFileNum(); 101 FileHandle fileHandle = null; 102 readBufferFileEnd = 0; 103 104 long fileLen = 0; 105 while ((fileHandle == null) && !eof) { 106 if (lastNum == null) { 107 eof = true; 108 } else { 109 try { 110 readBufferFileNum = lastNum.longValue(); 111 fileHandle = fileManager.getFileHandle(readBufferFileNum); 112 113 121 fileLen = fileHandle.getFile().length(); 122 if (fileLen <= FileManager.firstLogEntryOffset()) { 123 lastNum = fileManager.getFollowingFileNum 124 (lastNum.longValue(), false); 125 if (lastNum != null) { 126 fileHandle.release(); 127 fileHandle = null; 128 } 129 } 130 } catch (DatabaseException e) { 131 lastNum = attemptToMoveBadFile(e); 132 fileHandle = null; 133 } finally { 134 if (fileHandle != null) { 135 fileHandle.release(); 136 } 137 } 138 } 139 } 140 141 nextEntryOffset = 0; 142 } 143 144 151 private Long attemptToMoveBadFile(DatabaseException origException) 152 throws DatabaseException, IOException { 153 154 String fileName = fileManager.getFullFileNames(readBufferFileNum)[0]; 155 File problemFile = new File (fileName); 156 Long lastNum = null; 157 158 if (problemFile.length() <= FileManager.firstLogEntryOffset()) { 159 fileManager.clear(); 161 lastNum = fileManager.getFollowingFileNum(readBufferFileNum, 162 false); 163 fileManager.renameFile(readBufferFileNum, 164 FileManager.BAD_SUFFIX); 165 166 } else { 167 168 throw origException; 169 } 170 return lastNum; 171 } 172 173 public void setEndOfFile() 174 throws IOException , DatabaseException { 175 176 fileManager.truncateLog(readBufferFileNum, nextUnprovenOffset); 177 } 178 179 182 public long getEndOfLog() { 183 return DbLsn.makeLsn(readBufferFileNum, nextUnprovenOffset); 184 } 185 186 public long getLastValidLsn() { 187 return DbLsn.makeLsn(readBufferFileNum, lastValidOffset); 188 } 189 190 public long getPrevOffset() { 191 return lastValidOffset; 192 } 193 194 public LogEntryType getEntryType() { 195 return entryType; 196 } 197 198 201 public void setTargetType(LogEntryType type) { 202 trackableEntries.add(type); 203 } 204 205 208 public long getLastSeen(LogEntryType type) { 209 Long typeNumber =(Long ) lastOffsetSeen.get(type); 210 if (typeNumber != null) { 211 return DbLsn.makeLsn(readBufferFileNum, typeNumber.longValue()); 212 } else { 213 return DbLsn.NULL_LSN; 214 } 215 } 216 217 221 protected boolean processEntry(ByteBuffer entryBuffer) { 222 223 224 entryBuffer.position(entryBuffer.position() + currentEntrySize); 225 226 227 entryType = new LogEntryType(currentEntryTypeNum, 228 currentEntryTypeVersion); 229 if (trackableEntries.contains(entryType)) { 230 lastOffsetSeen.put(entryType, new Long (currentEntryOffset)); 231 } 232 233 return true; 234 } 235 236 240 public boolean readNextEntry() 241 throws DatabaseException, IOException { 242 243 boolean foundEntry = false; 244 245 try { 246 247 254 255 foundEntry = super.readNextEntry(); 256 257 258 263 lastValidOffset = currentEntryOffset; 264 nextUnprovenOffset = nextEntryOffset; 265 } catch (DbChecksumException e) { 266 Tracer.trace(Level.INFO, 267 env, "Found checksum exception while searching " + 268 " for end of log. Last valid entry is at " + 269 DbLsn.toString 270 (DbLsn.makeLsn(readBufferFileNum, lastValidOffset)) + 271 " Bad entry is at " + 272 DbLsn.makeLsn(readBufferFileNum, nextUnprovenOffset)); 273 } 274 return foundEntry; 275 } 276 } 277 | Popular Tags |