Lucene.Net.Index.DocumentsWriter.GetThreadState C# (CSharp) Method

GetThreadState() private method

Returns a free (idle) ThreadState that may be used for indexing this one document. This call also pauses if a flush is pending. If delTerm is non-null then we buffer this deleted term after the thread state has been acquired.
private GetThreadState ( Lucene.Net.Documents.Document doc, Lucene.Net.Index.Term delTerm ) : Lucene.Net.Index.DocumentsWriterThreadState
doc Lucene.Net.Documents.Document
delTerm Lucene.Net.Index.Term
return Lucene.Net.Index.DocumentsWriterThreadState
		internal DocumentsWriterThreadState GetThreadState(Document doc, Term delTerm)
		{
			lock (this)
			{
				
				// First, find a thread state.  If this thread already
				// has affinity to a specific ThreadState, use that one
				// again.
				DocumentsWriterThreadState state = threadBindings[ThreadClass.Current()];
				if (state == null)
				{
					
					// First time this thread has called us since last
					// flush.  Find the least loaded thread state:
					DocumentsWriterThreadState minThreadState = null;
					for (int i = 0; i < threadStates.Length; i++)
					{
						DocumentsWriterThreadState ts = threadStates[i];
						if (minThreadState == null || ts.numThreads < minThreadState.numThreads)
							minThreadState = ts;
					}
					if (minThreadState != null && (minThreadState.numThreads == 0 || threadStates.Length >= MAX_THREAD_STATE))
					{
						state = minThreadState;
						state.numThreads++;
					}
					else
					{
						// Just create a new "private" thread state
						DocumentsWriterThreadState[] newArray = new DocumentsWriterThreadState[1 + threadStates.Length];
						if (threadStates.Length > 0)
							Array.Copy(threadStates, 0, newArray, 0, threadStates.Length);
						state = newArray[threadStates.Length] = new DocumentsWriterThreadState(this);
						threadStates = newArray;
					}
					threadBindings[ThreadClass.Current()] = state;
				}
				
				// Next, wait until my thread state is idle (in case
				// it's shared with other threads) and for threads to
				// not be paused nor a flush pending:
				WaitReady(state);
				
				// Allocate segment name if this is the first doc since
				// last flush:
				InitSegmentName(false);
				
				state.isIdle = false;
				
				bool success = false;
				try
				{
					state.docState.docID = nextDocID;
					
					System.Diagnostics.Debug.Assert(writer.TestPoint("DocumentsWriter.ThreadState.init start"));
					
					if (delTerm != null)
					{
						AddDeleteTerm(delTerm, state.docState.docID);
						state.doFlushAfter = TimeToFlushDeletes();
					}
					
					System.Diagnostics.Debug.Assert(writer.TestPoint("DocumentsWriter.ThreadState.init after delTerm"));
					
					nextDocID++;
					numDocsInRAM++;
					
					// We must at this point commit to flushing to ensure we
					// always get N docs when we flush by doc count, even if
					// > 1 thread is adding documents:
					if (!flushPending && maxBufferedDocs != IndexWriter.DISABLE_AUTO_FLUSH && numDocsInRAM >= maxBufferedDocs)
					{
						flushPending = true;
						state.doFlushAfter = true;
					}
					
					success = true;
				}
				finally
				{
					if (!success)
					{
						// Forcefully idle this ThreadState:
						state.isIdle = true;
						System.Threading.Monitor.PulseAll(this);
						if (state.doFlushAfter)
						{
							state.doFlushAfter = false;
							flushPending = false;
						}
					}
				}
				
				return state;
			}
		}