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();
}
}
}