internal void FinishCommit(Directory dir)
{
if (PendingSegnOutput == null)
{
throw new InvalidOperationException("prepareCommit was not called");
}
bool success = false;
try
{
CodecUtil.WriteFooter(PendingSegnOutput);
success = true;
}
finally
{
if (!success)
{
// Closes pendingSegnOutput & deletes partial segments_N:
RollbackCommit(dir);
}
else
{
success = false;
try
{
PendingSegnOutput.Dispose();
success = true;
}
finally
{
if (!success)
{
// Closes pendingSegnOutput & deletes partial segments_N:
RollbackCommit(dir);
}
else
{
PendingSegnOutput = null;
}
}
}
}
// NOTE: if we crash here, we have left a segments_N
// file in the directory in a possibly corrupt state (if
// some bytes made it to stable storage and others
// didn't). But, the segments_N file includes checksum
// at the end, which should catch this case. So when a
// reader tries to read it, it will throw a
// CorruptIndexException, which should cause the retry
// logic in SegmentInfos to kick in and load the last
// good (previous) segments_N-1 file.
var fileName = IndexFileNames.FileNameFromGeneration(IndexFileNames.SEGMENTS, "", _generation);
success = false;
try
{
dir.Sync(Collections.Singleton(fileName));
success = true;
}
finally
{
if (!success)
{
try
{
dir.DeleteFile(fileName);
}
catch (Exception)
{
// Suppress so we keep throwing the original exception
}
}
}
_lastGeneration = _generation;
WriteSegmentsGen(dir, _generation);
}