public DocFieldProcessorPerThread(DocumentsWriterThreadState threadState, DocFieldProcessor docFieldProcessor)
 {
     InitBlock();
     this.docState          = threadState.docState;
     this.docFieldProcessor = docFieldProcessor;
     this.fieldInfos        = docFieldProcessor.fieldInfos;
     this.consumer          = docFieldProcessor.consumer.AddThread(this);
     fieldsWriter           = docFieldProcessor.fieldsWriter.AddThread(docState);
 }
		public DocFieldProcessorPerThread(DocumentsWriterThreadState threadState, DocFieldProcessor docFieldProcessor)
		{
			InitBlock();
			this.docState = threadState.docState;
			this.docFieldProcessor = docFieldProcessor;
			this.fieldInfos = docFieldProcessor.fieldInfos;
			this.consumer = docFieldProcessor.consumer.AddThread(this);
			fieldsWriter = docFieldProcessor.fieldsWriter.AddThread(docState);
		}
		public override DocConsumerPerThread AddThread(DocumentsWriterThreadState threadState)
		{
			return new DocFieldProcessorPerThread(threadState, this);
		}
		/// <summary>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. 
		/// </summary>
		internal DocumentsWriterThreadState GetThreadState(Document.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;
			}
		}
		/// <summary>Does the synchronized work to finish/flush the
		/// inverted document. 
		/// </summary>
		private void  FinishDocument(DocumentsWriterThreadState perThread, DocWriter docWriter)
		{
			
			if (DoBalanceRAM())
			// Must call this w/o holding synchronized(this) else
			// we'll hit deadlock:
				BalanceRAM();
			
			lock (this)
			{
				
				System.Diagnostics.Debug.Assert(docWriter == null || docWriter.docID == perThread.docState.docID);
				
				if (aborting)
				{
					
					// We are currently aborting, and another thread is
					// waiting for me to become idle.  We just forcefully
					// idle this threadState; it will be fully reset by
					// abort()
					if (docWriter != null)
						try
						{
							docWriter.Abort();
						}
						catch (System.Exception)
						{
						}
					
					perThread.isIdle = true;
					System.Threading.Monitor.PulseAll(this);
					return ;
				}
				
				bool doPause;
				
				if (docWriter != null)
					doPause = waitQueue.Add(docWriter);
				else
				{
					skipDocWriter.docID = perThread.docState.docID;
					doPause = waitQueue.Add(skipDocWriter);
				}
				
				if (doPause)
					WaitForWaitQueue();
				
				if (bufferIsFull && !flushPending)
				{
					flushPending = true;
					perThread.doFlushAfter = true;
				}
				
				perThread.isIdle = true;
				System.Threading.Monitor.PulseAll(this);
			}
		}
		private void  WaitReady(DocumentsWriterThreadState state)
		{
			lock (this)
			{
				
				while (!closed && ((state != null && !state.isIdle) || pauseThreads != 0 || flushPending || aborting))
				{
					System.Threading.Monitor.Wait(this);
				}
				
				if (closed)
					throw new AlreadyClosedException("this IndexWriter is closed");
			}
		}
Beispiel #7
0
 public override DocConsumerPerThread AddThread(DocumentsWriterThreadState threadState)
 {
     return(new DocFieldProcessorPerThread(threadState, this));
 }