public bool Add(DocWriter doc) { lock (this) { System.Diagnostics.Debug.Assert(doc.docID >= nextWriteDocID); if (doc.docID == nextWriteDocID) { WriteDocument(doc); while (true) { doc = waiting[nextWriteLoc]; if (doc != null) { numWaiting--; waiting[nextWriteLoc] = null; waitingBytes -= doc.SizeInBytes(); WriteDocument(doc); } else break; } } else { // I finished before documents that were added // before me. This can easily happen when I am a // small doc and the docs before me were large, or, // just due to luck in the thread scheduling. Just // add myself to the queue and when that large doc // finishes, it will flush me: int gap = doc.docID - nextWriteDocID; if (gap >= waiting.Length) { // Grow queue DocWriter[] newArray = new DocWriter[ArrayUtil.GetNextSize(gap)]; System.Diagnostics.Debug.Assert(nextWriteLoc >= 0); Array.Copy(waiting, nextWriteLoc, newArray, 0, waiting.Length - nextWriteLoc); Array.Copy(waiting, 0, newArray, waiting.Length - nextWriteLoc, nextWriteLoc); nextWriteLoc = 0; waiting = newArray; gap = doc.docID - nextWriteDocID; } int loc = nextWriteLoc + gap; if (loc >= waiting.Length) loc -= waiting.Length; // We should only wrap one time System.Diagnostics.Debug.Assert(loc < waiting.Length); // Nobody should be in my spot! System.Diagnostics.Debug.Assert(waiting [loc] == null); waiting[loc] = doc; numWaiting++; waitingBytes += doc.SizeInBytes(); } return DoPause(); } }