1 8 9 package com.sleepycat.je.log; 10 11 import java.io.IOException ; 12 import java.nio.ByteBuffer ; 13 import java.util.HashSet ; 14 import java.util.Set ; 15 16 import com.sleepycat.je.DatabaseException; 17 import com.sleepycat.je.dbi.EnvironmentImpl; 18 import com.sleepycat.je.log.entry.LogEntry; 19 import com.sleepycat.je.utilint.DbLsn; 20 21 33 abstract public class ScavengerFileReader extends FileReader { 34 35 36 private Set targetEntryTypes; 37 38 private int readBufferSize; 39 40 41 private boolean dumpCorruptedBounds; 42 43 46 public ScavengerFileReader(EnvironmentImpl env, 47 int readBufferSize, 48 long startLsn, 49 long finishLsn, 50 long endOfFileLsn) 51 throws IOException , DatabaseException { 52 53 super(env, 54 readBufferSize, 55 false, 56 startLsn, 57 null, endOfFileLsn, 59 finishLsn); 60 61 this.readBufferSize = readBufferSize; 62 63 67 anticipateChecksumErrors = true; 68 targetEntryTypes = new HashSet (); 69 dumpCorruptedBounds = false; 70 } 71 72 75 public void setDumpCorruptedBounds(boolean dumpCorruptedBounds) { 76 this.dumpCorruptedBounds = dumpCorruptedBounds; 77 } 78 79 82 public void setTargetType(LogEntryType type) { 83 targetEntryTypes.add(new Byte (type.getTypeNum())); 84 } 85 86 89 protected boolean processEntry(ByteBuffer entryBuffer) 90 throws DatabaseException { 91 92 LogEntryType lastEntryType = 93 LogEntryType.findType(currentEntryTypeNum, 94 currentEntryTypeVersion); 95 LogEntry entry = lastEntryType.getSharedLogEntry(); 96 entry.readEntry(entryBuffer, currentEntrySize, 97 currentEntryTypeVersion, true); 98 processEntryCallback(entry, lastEntryType); 99 return true; 100 } 101 102 106 abstract protected void processEntryCallback(LogEntry entry, 107 LogEntryType entryType) 108 throws DatabaseException; 109 110 115 public boolean readNextEntry() 116 throws DatabaseException, IOException { 117 118 long saveCurrentEntryOffset = currentEntryOffset; 119 try { 120 return super.readNextEntry(); 121 } catch (DbChecksumException DCE) { 122 resyncReader(DbLsn.makeLsn(readBufferFileNum, 123 saveCurrentEntryOffset), 124 dumpCorruptedBounds); 125 return super.readNextEntry(); 126 } 127 } 128 129 134 protected boolean resyncReader(long nextGoodRecordPostCorruption, 135 boolean showCorruptedBounds) 136 throws DatabaseException, IOException { 137 138 LastFileReader reader = null; 139 long tryReadBufferFileNum = 140 DbLsn.getFileNumber(nextGoodRecordPostCorruption); 141 142 while (tryReadBufferFileNum >= 0) { 143 try { 144 reader = new LastFileReader(env, 145 readBufferSize, 146 new Long (tryReadBufferFileNum)); 147 break; 148 } catch (DbChecksumException DCE) { 149 150 154 tryReadBufferFileNum--; 155 continue; 156 } 157 } 158 159 boolean switchedFiles = tryReadBufferFileNum != 160 DbLsn.getFileNumber(nextGoodRecordPostCorruption); 161 162 if (!switchedFiles) { 163 164 168 while (reader.readNextEntry()) { 169 } 170 } 171 172 long lastUsedLsn = reader.getLastValidLsn(); 173 long nextAvailableLsn = reader.getEndOfLog(); 174 if (showCorruptedBounds) { 175 System.err.println("A checksum error was found in the log."); 176 System.err.println 177 ("Corruption begins at LSN:\n " + 178 DbLsn.toString(nextAvailableLsn)); 179 System.err.println 180 ("Last known good record before corruption is at LSN:\n " + 181 DbLsn.toString(lastUsedLsn)); 182 System.err.println 183 ("Next known good record after corruption is at LSN:\n " + 184 DbLsn.toString(nextGoodRecordPostCorruption)); 185 } 186 187 startLsn = lastUsedLsn; 188 initStartingPosition(nextAvailableLsn, null); 189 if (switchedFiles) { 190 currentEntryPrevOffset = 0; 191 } 192 193 return true; 194 } 195 196 200 protected boolean isTargetEntry(byte logEntryTypeNumber, 201 byte logEntryTypeVersion) { 202 if (targetEntryTypes.size() == 0) { 203 204 return true; 205 } else { 206 return targetEntryTypes.contains(new Byte (logEntryTypeNumber)); 207 } 208 } 209 } 210 | Popular Tags |