private void ResolveExternalSegments()
{
bool any = false;
bool done = false;
while (!done)
{
SegmentInfo info = null;
MergePolicy.OneMerge merge = null;
lock (this)
{
if (stopMerges)
throw new MergePolicy.MergeAbortedException("rollback() was called or addIndexes* hit an unhandled exception");
int numSegments = segmentInfos.Count;
done = true;
for (int i = 0; i < numSegments; i++)
{
info = segmentInfos.Info(i);
if (info.dir != directory)
{
done = false;
MergePolicy.OneMerge newMerge = new MergePolicy.OneMerge(segmentInfos.Range(i, 1 + i), mergePolicy is LogMergePolicy && UseCompoundFile);
// Returns true if no running merge conflicts
// with this one (and, records this merge as
// pending), ie, this segment is not currently
// being merged:
if (RegisterMerge(newMerge))
{
merge = newMerge;
// If this segment is not currently being
// merged, then advance it to running & run
// the merge ourself (below):
pendingMerges.Remove(merge); // {{Aroush-2.9}} From Mike Garski: this is an O(n) op... is that an issue?
runningMerges.Add(merge);
break;
}
}
}
if (!done && merge == null)
// We are not yet done (external segments still
// exist in segmentInfos), yet, all such segments
// are currently "covered" by a pending or running
// merge. We now try to grab any pending merge
// that involves external segments:
merge = GetNextExternalMerge();
if (!done && merge == null)
// We are not yet done, and, all external segments
// fall under merges that the merge scheduler is
// currently running. So, we now wait and check
// back to see if the merge has completed.
DoWait();
}
if (merge != null)
{
any = true;
Merge(merge);
}
}
if (any)
// Sometimes, on copying an external segment over,
// more merges may become necessary:
mergeScheduler.Merge(this);
}