Example #1
0
		/// <summary>Just do the merges in sequence. We do this
		/// "synchronized" so that even if the application is using
		/// multiple threads, only one merge may run at a time. 
		/// </summary>
		public override void  Merge(IndexWriter writer)
		{
			lock (this)
			{
				
				while (true)
				{
					MergePolicy.OneMerge merge = writer.GetNextMerge();
					if (merge == null)
						break;
					writer.Merge(merge);
				}
			}
		}
		public override void  Merge(IndexWriter writer)
		{
			
			// TODO: enable this once we are on JRE 1.5
			// assert !Thread.holdsLock(writer);
			
			this.writer = writer;
			
			InitMergeThreadPriority();
			
			dir = writer.GetDirectory();
			
			// First, quickly run through the newly proposed merges
			// and add any orthogonal merges (ie a merge not
			// involving segments already pending to be merged) to
			// the queue.  If we are way behind on merging, many of
			// these newly proposed merges will likely already be
			// registered.
			
			if (Verbose())
			{
				Message("now merge");
				Message("  index: " + writer.SegString());
			}
			
			// Iterate, pulling from the IndexWriter's queue of
			// pending merges, until it's empty:
			while (true)
			{
				
				// TODO: we could be careful about which merges to do in
				// the BG (eg maybe the "biggest" ones) vs FG, which
				// merges to do first (the easiest ones?), etc.
				
				MergePolicy.OneMerge merge = writer.GetNextMerge();
				if (merge == null)
				{
					if (Verbose())
						Message("  no more merges pending; now return");
					return ;
				}
				
				// We do this w/ the primary thread to keep
				// deterministic assignment of segment names
				writer.MergeInit(merge);
				
				bool success = false;
				try
				{
					lock (this)
					{
						MergeThread merger;
						while (MergeThreadCount(true) >= maxThreadCount)
						{
							if (Verbose())
								Message("    too many merge threads running; stalling...");
							try
							{
								System.Threading.Monitor.Wait(this);
							}
							catch (System.Threading.ThreadInterruptedException ie)
							{
								// In 3.0 we will change this to throw
								// InterruptedException instead
								SupportClass.ThreadClass.Current().Interrupt();
								throw new System.SystemException(ie.Message, ie);
							}
						}
						
						if (Verbose())
							Message("  consider merge " + merge.SegString(dir));
						
												
						// OK to spawn a new merge thread to handle this
						// merge:
						merger = GetMergeThread(writer, merge);
						mergeThreads.Add(merger);
						if (Verbose())
							Message("    launch new thread [" + merger.Name + "]");
						
						merger.Start();
						success = true;
					}
				}
				finally
				{
					if (!success)
					{
						writer.MergeFinish(merge);
					}
				}
			}
		}