/// <summary> /// Walk through all files referenced by the current /// segmentInfos and ask the Directory to sync each file, /// if it wasn't already. If that succeeds, then we /// prepare a new segments_N file but do not fully commit /// it. /// </summary> private void StartCommit(SegmentInfos toSync) { Debug.Assert(TestPoint("startStartCommit")); Debug.Assert(PendingCommit == null); if (HitOOM) { throw new InvalidOperationException("this writer hit an OutOfMemoryError; cannot commit"); } try { if (infoStream.IsEnabled("IW")) { infoStream.Message("IW", "startCommit(): start"); } lock (this) { Debug.Assert(LastCommitChangeCount <= ChangeCount, "lastCommitChangeCount=" + LastCommitChangeCount + " changeCount=" + ChangeCount); if (PendingCommitChangeCount == LastCommitChangeCount) { if (infoStream.IsEnabled("IW")) { infoStream.Message("IW", " skip startCommit(): no changes pending"); } Deleter.DecRef(FilesToCommit); FilesToCommit = null; return; } if (infoStream.IsEnabled("IW")) { infoStream.Message("IW", "startCommit index=" + SegString(ToLiveInfos(toSync).Segments) + " changeCount=" + ChangeCount); } Debug.Assert(FilesExist(toSync)); } Debug.Assert(TestPoint("midStartCommit")); bool pendingCommitSet = false; try { Debug.Assert(TestPoint("midStartCommit2")); lock (this) { Debug.Assert(PendingCommit == null); Debug.Assert(segmentInfos.Generation == toSync.Generation); // Exception here means nothing is prepared // (this method unwinds everything it did on // an exception) toSync.PrepareCommit(directory); //System.out.println("DONE prepareCommit"); pendingCommitSet = true; PendingCommit = toSync; } // this call can take a long time -- 10s of seconds // or more. We do it without syncing on this: bool success = false; ICollection<string> filesToSync; try { filesToSync = toSync.Files(directory, false); directory.Sync(filesToSync); success = true; } finally { if (!success) { pendingCommitSet = false; PendingCommit = null; toSync.RollbackCommit(directory); } } if (infoStream.IsEnabled("IW")) { infoStream.Message("IW", "done all syncs: " + filesToSync); } Debug.Assert(TestPoint("midStartCommitSuccess")); } finally { lock (this) { // Have our master segmentInfos record the // generations we just prepared. We do this // on error or success so we don't // double-write a segments_N file. segmentInfos.UpdateGeneration(toSync); if (!pendingCommitSet) { if (infoStream.IsEnabled("IW")) { infoStream.Message("IW", "hit exception committing segments file"); } // Hit exception Deleter.DecRef(FilesToCommit); FilesToCommit = null; } } } } catch (System.OutOfMemoryException oom) { HandleOOM(oom, "startCommit"); } Debug.Assert(TestPoint("finishStartCommit")); }