/// <exception cref="System.IO.IOException"/> private FSEditLogOp NextOpImpl(bool skipBrokenEdits) { FSEditLogOp op = null; switch (state) { case EditLogFileInputStream.State.Uninit: { try { Init(true); } catch (Exception e) { Log.Error("caught exception initializing " + this, e); if (skipBrokenEdits) { return(null); } Throwables.PropagateIfPossible <IOException>(e); } Preconditions.CheckState(state != EditLogFileInputStream.State.Uninit); return(NextOpImpl(skipBrokenEdits)); } case EditLogFileInputStream.State.Open: { op = reader.ReadOp(skipBrokenEdits); if ((op != null) && (op.HasTransactionId())) { long txId = op.GetTransactionId(); if ((txId >= lastTxId) && (lastTxId != HdfsConstants.InvalidTxid)) { // // Sometimes, the NameNode crashes while it's writing to the // edit log. In that case, you can end up with an unfinalized edit log // which has some garbage at the end. // JournalManager#recoverUnfinalizedSegments will finalize these // unfinished edit logs, giving them a defined final transaction // ID. Then they will be renamed, so that any subsequent // readers will have this information. // // Since there may be garbage at the end of these "cleaned up" // logs, we want to be sure to skip it here if we've read everything // we were supposed to read out of the stream. // So we force an EOF on all subsequent reads. // long skipAmt = log.Length() - tracker.GetPos(); if (skipAmt > 0) { if (Log.IsDebugEnabled()) { Log.Debug("skipping " + skipAmt + " bytes at the end " + "of edit log '" + GetName () + "': reached txid " + txId + " out of " + lastTxId); } tracker.ClearLimit(); IOUtils.SkipFully(tracker, skipAmt); } } } break; } case EditLogFileInputStream.State.Closed: { break; } } // return null return(op); }