private long recoverLogFile(long fileNumber, VersionEdit edit) throws IOException { Preconditions.checkState(mutex.isHeldByCurrentThread()); File file = new File(databaseDir, Filename.logFileName(fileNumber)); FileChannel channel = new FileInputStream(file).getChannel(); try { LogMonitor logMonitor = LogMonitors.logMonitor(); LogReader logReader = new LogReader(channel, logMonitor, true, 0); // Log(options_.info_log, "Recovering log #%llu", (unsigned long long) log_number); // Read all the records and add to a memtable long maxSequence = 0; MemTable memTable = null; for (Slice record = logReader.readRecord(); record != null; record = logReader.readRecord()) { SliceInput sliceInput = record.input(); // read header if (sliceInput.available() < 12) { logMonitor.corruption(sliceInput.available(), "log record too small"); continue; } long sequenceBegin = sliceInput.readLong(); int updateSize = sliceInput.readInt(); // read entries WriteBatchImpl writeBatch = readWriteBatch(sliceInput, updateSize); // apply entries to memTable if (memTable == null) { memTable = new MemTable(internalKeyComparator); } writeBatch.forEach(new InsertIntoHandler(memTable, sequenceBegin)); // update the maxSequence long lastSequence = sequenceBegin + updateSize - 1; if (lastSequence > maxSequence) { maxSequence = lastSequence; } // flush mem table if necessary if (memTable.approximateMemoryUsage() > options.writeBufferSize()) { writeLevel0Table(memTable, edit, null); memTable = null; } } // flush mem table if (memTable != null && !memTable.isEmpty()) { writeLevel0Table(memTable, edit, null); } return maxSequence; } finally { channel.close(); } }