private void HandleMergeException(System.Exception t, MergePolicy.OneMerge merge) { if (infoStream != null) { Message("handleMergeException: merge=" + merge.SegString(directory) + " exc=" + t); } // Set the exception on the merge, so if // optimize() is waiting on us it sees the root // cause exception: merge.SetException(t); AddMergeException(merge); if (t is MergePolicy.MergeAbortedException) { // We can ignore this exception (it happens when // close(false) or rollback is called), unless the // merge involves segments from external directories, // in which case we must throw it so, for example, the // rollbackTransaction code in addIndexes* is // executed. if (merge.isExternal) throw (MergePolicy.MergeAbortedException) t; } else if (t is System.IO.IOException) throw (System.IO.IOException) t; else if (t is System.SystemException) throw (System.SystemException) t; else if (t is System.ApplicationException) throw (System.ApplicationException) t; // Should not get here else throw new System.SystemException(null, t); }
/// <summary> Merges the indicated segments, replacing them in the stack with a /// single segment. /// </summary> public /*internal*/ void Merge(MergePolicy.OneMerge merge) { System.Diagnostics.Debug.Assert(merge.registerDone); System.Diagnostics.Debug.Assert(!merge.optimize || merge.maxNumSegmentsOptimize > 0); bool success = false; try { try { try { if (merge.info == null) MergeInit(merge); if (infoStream != null) Message("now merge\n merge=" + merge.SegString(directory) + "\n index=" + SegString()); MergeMiddle(merge); success = true; } catch (MergePolicy.MergeAbortedException e) { merge.SetException(e); AddMergeException(merge); // We can ignore this exception, unless the merge // involves segments from external directories, in // which case we must throw it so, for example, the // rollbackTransaction code in addIndexes* is // executed. if (merge.isExternal) throw e; } } finally { lock (this) { try { MergeFinish(merge); if (!success) { if (infoStream != null) Message("hit exception during merge"); AddMergeException(merge); if (merge.info != null && !segmentInfos.Contains(merge.info)) deleter.Refresh(merge.info.name); } // This merge (and, generally, any change to the // segments) may now enable new merges, so we call // merge policy & update pending merges. if (success && !merge.IsAborted() && !closed && !closing) UpdatePendingMerges(merge.maxNumSegmentsOptimize, merge.optimize); } finally { runningMerges.Remove(merge); // Optimize may be waiting on the final optimize // merge to finish; and finishMerges() may be // waiting for all merges to finish: System.Threading.Monitor.PulseAll(this); } } } } catch (OutOfMemoryException oom) { hitOOM = true; throw oom; } }