You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ar...@apache.org on 2007/05/01 20:45:35 UTC

svn commit: r534192 [15/19] - in /incubator/lucene.net/trunk/C#: ./ src/ src/Demo/ src/Demo/DeleteFiles/ src/Demo/DemoLib/ src/Demo/DemoLib/HTML/ src/Demo/IndexFiles/ src/Demo/IndexHtml/ src/Demo/SearchFiles/ src/Lucene.Net/ src/Lucene.Net/Analysis/ sr...

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ConjunctionScorer.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/ConjunctionScorer.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ConjunctionScorer.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ConjunctionScorer.cs Tue May  1 11:45:26 2007
@@ -48,7 +48,10 @@
 				return ((Scorer) o1).Doc() - ((Scorer) o2).Doc();
 			}
 		}
-		private System.Collections.ArrayList scorers = new System.Collections.ArrayList();
+		private Scorer[] scorers = new Scorer[2];
+		private int length = 0;
+		private int first = 0;
+		private int last = - 1;
 		private bool firstTime = true;
 		private bool more = true;
 		private float coord;
@@ -59,21 +62,21 @@
 		
 		internal void  Add(Scorer scorer)
 		{
-			scorers.Insert(scorers.Count, scorer);
-		}
-		
-		private Scorer First()
-		{
-			return (Scorer) scorers[0];
-		}
-		private Scorer Last()
-		{
-			return (Scorer) scorers[scorers.Count - 1];
+			if (length >= scorers.Length)
+			{
+				// grow the array
+				Scorer[] temps = new Scorer[scorers.Length * 2];
+				Array.Copy(scorers, 0, temps, 0, length);
+				scorers = temps;
+			}
+			last += 1;
+			length += 1;
+			scorers[last] = scorer;
 		}
 		
 		public override int Doc()
 		{
-			return First().Doc();
+			return scorers[first].Doc();
 		}
 		
 		public override bool Next()
@@ -84,21 +87,19 @@
 			}
 			else if (more)
 			{
-				more = Last().Next(); // trigger further scanning
+				more = scorers[last].Next(); // trigger further scanning
 			}
 			return DoNext();
 		}
 		
 		private bool DoNext()
 		{
-			while (more && First().Doc() < Last().Doc())
+			while (more && scorers[first].Doc() < scorers[last].Doc())
 			{
 				// find doc w/ all clauses
-				more = First().SkipTo(Last().Doc()); // skip first upto last
-				System.Object tempObject;
-				tempObject = scorers[0];
-				scorers.RemoveAt(0);
-				scorers.Insert(scorers.Count, tempObject); // move first to last
+				more = scorers[first].SkipTo(scorers[last].Doc()); // skip first upto last
+				last = first; // move first to last
+				first = (first == length - 1) ? 0 : first + 1;
 			}
 			return more; // found a doc with all clauses
 		}
@@ -110,10 +111,12 @@
 				Init(false);
 			}
 			
-			System.Collections.IEnumerator i = scorers.GetEnumerator();
-			while (more && i.MoveNext())
+			for (int i = 0, pos = first; i < length; i++)
 			{
-				more = ((Scorer) i.Current).SkipTo(target);
+				if (!more)
+					break;
+				more = scorers[pos].SkipTo(target);
+				pos = (pos == length - 1) ? 0 : pos + 1;
 			}
 			
 			if (more)
@@ -124,33 +127,34 @@
 		
 		public override float Score()
 		{
-			float score = 0.0f; // sum scores
-			System.Collections.IEnumerator i = scorers.GetEnumerator();
-			while (i.MoveNext())
+			float sum = 0.0f;
+			for (int i = 0; i < length; i++)
 			{
-				score += ((Scorer) i.Current).Score();
+				sum += scorers[i].Score();
 			}
-			score *= coord;
-			return score;
+			return sum * coord;
 		}
 		
 		private void  Init(bool initScorers)
 		{
 			//  compute coord factor
-			coord = GetSimilarity().Coord(scorers.Count, scorers.Count);
+			coord = GetSimilarity().Coord(length, length);
 			
-			more = scorers.Count > 0;
+			more = length > 0;
 			
 			if (initScorers)
 			{
 				// move each scorer to its first entry
-				System.Collections.IEnumerator i = scorers.GetEnumerator();
-				while (more && i.MoveNext())
+				for (int i = 0, pos = first; i < length; i++)
 				{
-					more = ((Scorer) i.Current).Next();
+					if (!more)
+						break;
+					more = scorers[pos].Next();
+					pos = (pos == length - 1) ? 0 : pos + 1;
 				}
+				// initial sort of simulated list
 				if (more)
-					SortScorers(); // initial sort of list
+					SortScorers();
 			}
 			
 			firstTime = false;
@@ -158,17 +162,19 @@
 		
 		private void  SortScorers()
 		{
-			// move scorers to an array
-			Scorer[] array = (Scorer[]) scorers.ToArray(typeof(Scorer));
-			scorers.Clear(); // empty the list
+			// squeeze the array down for the sort
+			if (length != scorers.Length)
+			{
+				Scorer[] temps = new Scorer[length];
+				Array.Copy(scorers, 0, temps, 0, length);
+				scorers = temps;
+			}
 			
 			// note that this comparator is not consistent with equals!
-			System.Array.Sort(array, new AnonymousClassComparator(this));
+			System.Array.Sort(scorers, new AnonymousClassComparator(this));
 			
-			for (int i = 0; i < array.Length; i++)
-			{
-				scorers.Insert(scorers.Count, array[i]); // re-build list, now sorted
-			}
+			first = 0;
+			last = length - 1;
 		}
 		
 		public override Explanation Explain(int doc)

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ConstantScoreQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/ConstantScoreQuery.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ConstantScoreQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ConstantScoreQuery.cs Tue May  1 11:45:26 2007
@@ -16,6 +16,7 @@
  */
 
 using System;
+
 using IndexReader = Lucene.Net.Index.IndexReader;
 
 namespace Lucene.Net.Search
@@ -27,7 +28,7 @@
 	/// </summary>
 	/// <author>  yonik
 	/// </author>
-	/// <version>  $Id$
+	/// <version>  $Id: ConstantScoreQuery.java 507374 2007-02-14 03:12:50Z yonik $
 	/// </version>
 	[Serializable]
 	public class ConstantScoreQuery : Query
@@ -39,18 +40,24 @@
 			this.filter = filter;
 		}
 		
+		/// <summary>Returns the encapsulated filter </summary>
+		public virtual Filter GetFilter()
+		{
+			return filter;
+		}
+		
 		public override Query Rewrite(IndexReader reader)
 		{
 			return this;
 		}
 		
-        public override void  ExtractTerms(System.Collections.Hashtable terms)
-        {
-            // OK to not add any terms when used for MultiSearcher,
-            // but may not be OK for highlighting
-        }
+		public override void  ExtractTerms(System.Collections.Hashtable terms)
+		{
+			// OK to not add any terms when used for MultiSearcher,
+			// but may not be OK for highlighting
+		}
 		
-        [Serializable]
+		[Serializable]
 		protected internal class ConstantWeight : Weight
 		{
 			private void  InitBlock(ConstantScoreQuery enclosingInstance)
@@ -109,12 +116,14 @@
 				ConstantScorer cs = (ConstantScorer) Scorer(reader);
 				bool exists = cs.bits.Get(doc);
 				
-				Explanation result = new Explanation();
+				ComplexExplanation result = new ComplexExplanation();
 				
 				if (exists)
 				{
 					result.SetDescription("ConstantScoreQuery(" + Enclosing_Instance.filter + "), product of:");
 					result.SetValue(queryWeight);
+					System.Boolean tempAux = true;
+					result.SetMatch(tempAux);
 					result.AddDetail(new Explanation(Enclosing_Instance.GetBoost(), "boost"));
 					result.AddDetail(new Explanation(queryNorm, "queryNorm"));
 				}
@@ -122,6 +131,8 @@
 				{
 					result.SetDescription("ConstantScoreQuery(" + Enclosing_Instance.filter + ") doesn't match id " + doc);
 					result.SetValue(0);
+					System.Boolean tempAux2 = false;
+					result.SetMatch(tempAux2);
 				}
 				return result;
 			}
@@ -146,7 +157,7 @@
 			internal float theScore;
 			internal int doc = - 1;
 			
-			public ConstantScorer(ConstantScoreQuery enclosingInstance, Similarity similarity, IndexReader reader, Weight w) : base(similarity)
+			public ConstantScorer(ConstantScoreQuery enclosingInstance, Similarity similarity, IndexReader reader, Weight w):base(similarity)
 			{
 				InitBlock(enclosingInstance);
 				theScore = w.GetValue();
@@ -212,7 +223,7 @@
 			return filter.GetHashCode() + BitConverter.ToInt32(BitConverter.GetBytes(GetBoost()), 0);
 		}
 
-        override public System.Object Clone()
+		override public System.Object Clone()
 		{
             // {{Aroush-1.9}} is this all that we need to clone?!
             ConstantScoreQuery clone = (ConstantScoreQuery) base.Clone();

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ConstantScoreRangeQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/ConstantScoreRangeQuery.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ConstantScoreRangeQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ConstantScoreRangeQuery.cs Tue May  1 11:45:26 2007
@@ -16,13 +16,14 @@
  */
 
 using System;
+
 using IndexReader = Lucene.Net.Index.IndexReader;
 
 namespace Lucene.Net.Search
 {
 	
-    /// <summary> A range query that returns a constant score equal to its boost for
-    /// all documents in the range.
+	/// <summary> A range query that returns a constant score equal to its boost for
+	/// all documents in the range.
 	/// <p>
 	/// It does not have an upper bound on the number of clauses covered in the range.
 	/// <p>
@@ -33,7 +34,7 @@
 	/// </summary>
 	/// <author>  yonik
 	/// </author>
-	/// <version>  $Id$
+	/// <version>  $Id: ConstantScoreRangeQuery.java 472959 2006-11-09 16:21:50Z yonik $
 	/// </version>
 	
 	[Serializable]
@@ -100,7 +101,7 @@
 		public override Query Rewrite(IndexReader reader)
 		{
 			// Map to RangeFilter semantics which are slightly different...
-			RangeFilter rangeFilt = new RangeFilter(fieldName, lowerVal != null ? lowerVal : "", upperVal, (System.Object) lowerVal == (System.Object) ""?false:includeLower, upperVal == null?false:includeUpper);
+			RangeFilter rangeFilt = new RangeFilter(fieldName, lowerVal != null ? lowerVal : "", upperVal, (System.Object) lowerVal == (System.Object) "" ? false : includeLower, upperVal == null ? false : includeUpper);
 			Query q = new ConstantScoreQuery(rangeFilt);
 			q.SetBoost(GetBoost());
 			return q;
@@ -161,17 +162,17 @@
 			h ^= (includeLower ? 0x665599aa : 0) ^ (includeUpper ? unchecked((int) 0x99aa5566) : 0);    // {{Aroush-1.9}} Is this OK?!
 			return h;
 		}
-
-        override public System.Object Clone()
+		
+		override public System.Object Clone()
 		{
             // {{Aroush-1.9}} is this all that we need to clone?!
-			ConstantScoreRangeQuery clone = (ConstantScoreRangeQuery) base.Clone();
-			clone.fieldName = (System.String) this.fieldName.Clone();
-			clone.lowerVal = (System.String) this.lowerVal.Clone();
-			clone.upperVal = (System.String) this.upperVal.Clone();
-			clone.includeLower = this.includeLower;
-			clone.includeUpper = this.includeUpper;
-			return clone;
+            ConstantScoreRangeQuery clone = (ConstantScoreRangeQuery) base.Clone();
+            clone.fieldName = (System.String) this.fieldName.Clone();
+            clone.lowerVal = (System.String) this.lowerVal.Clone();
+            clone.upperVal = (System.String) this.upperVal.Clone();
+            clone.includeLower = this.includeLower;
+            clone.includeUpper = this.includeUpper;
+            return clone;
         }
 	}
 }

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/DisjunctionMaxQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/DisjunctionMaxQuery.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/DisjunctionMaxQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/DisjunctionMaxQuery.cs Tue May  1 11:45:26 2007
@@ -16,14 +16,15 @@
  */
 
 using System;
+
 using IndexReader = Lucene.Net.Index.IndexReader;
 
 namespace Lucene.Net.Search
 {
 	
-	/// <summary> A query that generates the union of the documents produced by its subqueries, and that scores each document as the maximum
-	/// score for that document produced by any subquery plus a tie breaking increment for any additional matching subqueries.
-	/// This is useful to search for a word in multiple fields with different boost factors (so that the fields cannot be
+	/// <summary> A query that generates the union of documents produced by its subqueries, and that scores each document with the maximum
+	/// score for that document as produced by any subquery, plus a tie breaking increment for any additional matching subqueries.
+	/// This is useful when searching for a word in multiple fields with different boost factors (so that the fields cannot be
 	/// combined equivalently into a single search field).  We want the primary score to be the one associated with the highest boost,
 	/// not the sum of the field scores (as BooleanQuery would give).
 	/// If the query is "albino elephant" this ensures that "albino" matching one field and "elephant" matching
@@ -173,14 +174,16 @@
 			{
 				if (Enclosing_Instance.disjuncts.Count == 1)
 					return ((Weight) weights[0]).Explain(reader, doc);
-				Explanation result = new Explanation();
+				ComplexExplanation result = new ComplexExplanation();
 				float max = 0.0f, sum = 0.0f;
 				result.SetDescription(Enclosing_Instance.tieBreakerMultiplier == 0.0f ? "max of:" : "max plus " + Enclosing_Instance.tieBreakerMultiplier + " times others of:");
 				for (int i = 0; i < weights.Count; i++)
 				{
 					Explanation e = ((Weight) weights[i]).Explain(reader, doc);
-					if (e.GetValue() > 0)
+					if (e.IsMatch())
 					{
+						System.Boolean tempAux = true;
+						result.SetMatch(tempAux);
 						result.AddDetail(e);
 						sum += e.GetValue();
 						max = System.Math.Max(max, e.GetValue());
@@ -245,17 +248,17 @@
 		}
 		
 		
-        // inherit javadoc
-        public override void  ExtractTerms(System.Collections.Hashtable terms)
-        {
-            for (int i = 0; i < disjuncts.Count; i++)
-            {
-                ((Query) disjuncts[i]).ExtractTerms(terms);
-            }
-        }
+		// inherit javadoc
+		public override void  ExtractTerms(System.Collections.Hashtable terms)
+		{
+			for (int i = 0; i < disjuncts.Count; i++)
+			{
+				((Query) disjuncts[i]).ExtractTerms(terms);
+			}
+		}
 		
 		
-        /// <summary>Prettyprint us.</summary>
+		/// <summary>Prettyprint us.</summary>
 		/// <param name="field">the field to which we are applied
 		/// </param>
 		/// <returns> a string that shows what we do, of the form "(disjunct1 | disjunct2 | ... | disjunctn)^boost"

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/DisjunctionMaxScorer.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/DisjunctionMaxScorer.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/DisjunctionMaxScorer.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/DisjunctionMaxScorer.cs Tue May  1 11:45:26 2007
@@ -133,6 +133,15 @@
 		/// </returns>
 		public override bool SkipTo(int target)
 		{
+			if (firstTime)
+			{
+				if (!more)
+					return false;
+				Heapify();
+				firstTime = false;
+				return true; // more would have been false if no subScorers had any docs
+			}
+			
 			while (subScorers.Count > 0 && ((Scorer) subScorers[0]).Doc() < target)
 			{
 				if (((Scorer) subScorers[0]).SkipTo(target))

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/DisjunctionSumScorer.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/DisjunctionSumScorer.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/DisjunctionSumScorer.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/DisjunctionSumScorer.cs Tue May  1 11:45:26 2007
@@ -16,14 +16,16 @@
  */
 
 using System;
-using PriorityQueue = Lucene.Net.Util.PriorityQueue;
+
+using ScorerDocQueue = Lucene.Net.Util.ScorerDocQueue;
 
 namespace Lucene.Net.Search
 {
 	
-	/// <summary>A Scorer for OR like queries, counterpart of Lucene's <code>ConjunctionScorer</code>.
+	/// <summary>A Scorer for OR like queries, counterpart of <code>ConjunctionScorer</code>.
 	/// This Scorer implements {@link Scorer#SkipTo(int)} and uses skipTo() on the given Scorers. 
 	/// </summary>
+	/// <todo>  Implement score(HitCollector, int). </todo>
 	class DisjunctionSumScorer : Scorer
 	{
 		/// <summary>The number of subscorers. </summary>
@@ -35,19 +37,20 @@
 		/// <summary>The minimum number of scorers that should match. </summary>
 		private int minimumNrMatchers;
 		
-		/// <summary>The scorerQueue contains all subscorers ordered by their current doc(),
+		/// <summary>The scorerDocQueue contains all subscorers ordered by their current doc(),
 		/// with the minimum at the top.
-		/// <br>The scorerQueue is initialized the first time next() or skipTo() is called.
-		/// <br>An exhausted scorer is immediately removed from the scorerQueue.
+		/// <br>The scorerDocQueue is initialized the first time next() or skipTo() is called.
+		/// <br>An exhausted scorer is immediately removed from the scorerDocQueue.
 		/// <br>If less than the minimumNrMatchers scorers
-		/// remain in the scorerQueue next() and skipTo() return false.
+		/// remain in the scorerDocQueue next() and skipTo() return false.
 		/// <p>
 		/// After each to call to next() or skipTo()
 		/// <code>currentSumScore</code> is the total score of the current matching doc,
 		/// <code>nrMatchers</code> is the number of matching scorers,
 		/// and all scorers are after the matching doc, or are exhausted.
 		/// </summary>
-		private ScorerQueue scorerQueue = null;
+		private ScorerDocQueue scorerDocQueue = null;
+		private int queueSize = - 1; // used to avoid size() method calls on scorerDocQueue
 		
 		/// <summary>The document number of the current match. </summary>
 		private int currentDoc = - 1;
@@ -94,73 +97,79 @@
 		}
 		
 		/// <summary>Called the first time next() or skipTo() is called to
-		/// initialize <code>scorerQueue</code>.
+		/// initialize <code>scorerDocQueue</code>.
 		/// </summary>
-		private void  InitScorerQueue()
+		private void  InitScorerDocQueue()
 		{
 			System.Collections.IEnumerator si = subScorers.GetEnumerator();
-			scorerQueue = new ScorerQueue(this, nrScorers);
+			scorerDocQueue = new ScorerDocQueue(nrScorers);
+			queueSize = 0;
 			while (si.MoveNext())
 			{
 				Scorer se = (Scorer) si.Current;
 				if (se.Next())
 				{
-					// doc() method will be used in scorerQueue.
-					scorerQueue.Insert(se);
+					// doc() method will be used in scorerDocQueue.
+					if (scorerDocQueue.Insert(se))
+					{
+						queueSize++;
+					}
 				}
 			}
 		}
 		
-		/// <summary>A <code>PriorityQueue</code> that orders by {@link Scorer#Doc()}. </summary>
-		private class ScorerQueue : PriorityQueue
+		/// <summary>Scores and collects all matching documents.</summary>
+		/// <param name="hc">The collector to which all matching documents are passed through
+		/// {@link HitCollector#Collect(int, float)}.
+		/// <br>When this method is used the {@link #Explain(int)} method should not be used.
+		/// </param>
+		public override void  Score(HitCollector hc)
 		{
-			private void  InitBlock(DisjunctionSumScorer enclosingInstance)
+			while (Next())
 			{
-				this.enclosingInstance = enclosingInstance;
+				hc.Collect(currentDoc, currentScore);
 			}
-			private DisjunctionSumScorer enclosingInstance;
-			public DisjunctionSumScorer Enclosing_Instance
+		}
+		
+		/// <summary>Expert: Collects matching documents in a range.  Hook for optimization.
+		/// Note that {@link #Next()} must be called once before this method is called
+		/// for the first time.
+		/// </summary>
+		/// <param name="hc">The collector to which all matching documents are passed through
+		/// {@link HitCollector#Collect(int, float)}.
+		/// </param>
+		/// <param name="max">Do not score documents past this.
+		/// </param>
+		/// <returns> true if more matching documents may remain.
+		/// </returns>
+		protected internal override bool Score(HitCollector hc, int max)
+		{
+			while (currentDoc < max)
 			{
-				get
+				hc.Collect(currentDoc, currentScore);
+				if (!Next())
 				{
-					return enclosingInstance;
+					return false;
 				}
-				
-			}
-			internal ScorerQueue(DisjunctionSumScorer enclosingInstance, int size)
-			{
-				InitBlock(enclosingInstance);
-				Initialize(size);
-			}
-			
-			public override bool LessThan(System.Object o1, System.Object o2)
-			{
-				return ((Scorer) o1).Doc() < ((Scorer) o2).Doc();
 			}
+			return true;
 		}
 		
 		public override bool Next()
 		{
-			if (scorerQueue == null)
+			if (scorerDocQueue == null)
 			{
-				InitScorerQueue();
-			}
-			if (scorerQueue.Size() < minimumNrMatchers)
-			{
-				return false;
-			}
-			else
-			{
-				return AdvanceAfterCurrent();
+				InitScorerDocQueue();
 			}
+			return (scorerDocQueue.Size() >= minimumNrMatchers) && AdvanceAfterCurrent();
 		}
 		
 		
 		/// <summary>Advance all subscorers after the current document determined by the
-		/// top of the <code>scorerQueue</code>.
+		/// top of the <code>scorerDocQueue</code>.
 		/// Repeat until at least the minimum number of subscorers match on the same
 		/// document and all subscorers are after that document or are exhausted.
-		/// <br>On entry the <code>scorerQueue</code> has at least <code>minimumNrMatchers</code>
+		/// <br>On entry the <code>scorerDocQueue</code> has at least <code>minimumNrMatchers</code>
 		/// available. At least the scorer with the minimum document number will be advanced.
 		/// </summary>
 		/// <returns> true iff there is a match.
@@ -171,47 +180,35 @@
 		/// <todo>  Investigate whether it is possible to use skipTo() when </todo>
 		/// <summary> the minimum number of matchers is bigger than one, ie. try and use the
 		/// character of ConjunctionScorer for the minimum number of matchers.
+		/// Also delay calling score() on the sub scorers until the minimum number of
+		/// matchers is reached.
+		/// <br>For this, a Scorer array with minimumNrMatchers elements might
+		/// hold Scorers at currentDoc that are temporarily popped from scorerQueue.
 		/// </summary>
 		protected internal virtual bool AdvanceAfterCurrent()
 		{
 			do 
 			{
 				// repeat until minimum nr of matchers
-				Scorer top = (Scorer) scorerQueue.Top();
-				currentDoc = top.Doc();
-				currentScore = top.Score();
+				currentDoc = scorerDocQueue.TopDoc();
+				currentScore = scorerDocQueue.TopScore();
 				nrMatchers = 1;
 				do 
 				{
 					// Until all subscorers are after currentDoc
-					if (top.Next())
-					{
-						scorerQueue.AdjustTop();
-					}
-					else
+					if (!scorerDocQueue.TopNextAndAdjustElsePop())
 					{
-						scorerQueue.Pop();
-						if (scorerQueue.Size() < (minimumNrMatchers - nrMatchers))
-						{
-							// Not enough subscorers left for a match on this document,
-							// and also no more chance of any further match.
-							return false;
-						}
-						if (scorerQueue.Size() == 0)
+						if (--queueSize == 0)
 						{
 							break; // nothing more to advance, check for last match.
 						}
 					}
-					top = (Scorer) scorerQueue.Top();
-					if (top.Doc() != currentDoc)
+					if (scorerDocQueue.TopDoc() != currentDoc)
 					{
 						break; // All remaining subscorers are after currentDoc.
 					}
-					else
-					{
-						currentScore += top.Score();
-						nrMatchers++;
-					}
+					currentScore += scorerDocQueue.TopScore();
+					nrMatchers++;
 				}
 				while (true);
 				
@@ -219,7 +216,7 @@
 				{
 					return true;
 				}
-				else if (scorerQueue.Size() < minimumNrMatchers)
+				else if (queueSize < minimumNrMatchers)
 				{
 					return false;
 				}
@@ -259,11 +256,11 @@
 		/// </returns>
 		public override bool SkipTo(int target)
 		{
-			if (scorerQueue == null)
+			if (scorerDocQueue == null)
 			{
-				InitScorerQueue();
+				InitScorerDocQueue();
 			}
-			if (scorerQueue.Size() < minimumNrMatchers)
+			if (queueSize < minimumNrMatchers)
 			{
 				return false;
 			}
@@ -273,19 +270,13 @@
 			}
 			do 
 			{
-				Scorer top = (Scorer) scorerQueue.Top();
-				if (top.Doc() >= target)
+				if (scorerDocQueue.TopDoc() >= target)
 				{
 					return AdvanceAfterCurrent();
 				}
-				else if (top.SkipTo(target))
+				else if (!scorerDocQueue.TopSkipToAndAdjustElsePop(target))
 				{
-					scorerQueue.AdjustTop();
-				}
-				else
-				{
-					scorerQueue.Pop();
-					if (scorerQueue.Size() < minimumNrMatchers)
+					if (--queueSize < minimumNrMatchers)
 					{
 						return false;
 					}
@@ -294,16 +285,34 @@
 			while (true);
 		}
 		
-		/// <summary>Gives and explanation for the score of a given document.</summary>
-		/// <todo>  Show the resulting score. See BooleanScorer.explain() on how to do this. </todo>
+		/// <returns> An explanation for the score of a given document. 
+		/// </returns>
 		public override Explanation Explain(int doc)
 		{
 			Explanation res = new Explanation();
-			res.SetDescription("At least " + minimumNrMatchers + " of");
 			System.Collections.IEnumerator ssi = subScorers.GetEnumerator();
+			float sumScore = 0.0f;
+			int nrMatches = 0;
 			while (ssi.MoveNext())
 			{
-				res.AddDetail(((Scorer) ssi.Current).Explain(doc));
+				Explanation es = ((Scorer) ssi.Current).Explain(doc);
+				if (es.GetValue() > 0.0f)
+				{
+					// indicates match
+					sumScore += es.GetValue();
+					nrMatches++;
+				}
+				res.AddDetail(es);
+			}
+			if (nrMatchers >= minimumNrMatchers)
+			{
+				res.SetValue(sumScore);
+				res.SetDescription("sum over at least " + minimumNrMatchers + " of " + subScorers.Count + ":");
+			}
+			else
+			{
+				res.SetValue(0.0f);
+				res.SetDescription(nrMatches + " match(es) but at least " + minimumNrMatchers + " of " + subScorers.Count + " needed");
 			}
 			return res;
 		}

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ExactPhraseScorer.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/ExactPhraseScorer.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ExactPhraseScorer.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/ExactPhraseScorer.cs Tue May  1 11:45:26 2007
@@ -16,6 +16,7 @@
  */
 
 using System;
+
 using Lucene.Net.Index;
 
 namespace Lucene.Net.Search

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Explanation.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Explanation.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Explanation.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Explanation.cs Tue May  1 11:45:26 2007
@@ -38,6 +38,21 @@
 			this.description = description;
 		}
 		
+		/// <summary> Indicates wether or not this Explanation models a good match.
+		/// 
+		/// <p>
+		/// By default, an Explanation represents a "match" if the value is positive.
+		/// </p>
+		/// </summary>
+		/// <seealso cref="#getValue">
+		/// </seealso>
+		public virtual bool IsMatch()
+		{
+			return (0.0f < GetValue());
+		}
+		
+		
+		
 		/// <summary>The value assigned to this explanation node. </summary>
 		public virtual float GetValue()
 		{
@@ -60,6 +75,14 @@
 			this.description = description;
 		}
 		
+		/// <summary> A short one line summary which should contain all high level
+		/// information about this Explanation, without the "Details"
+		/// </summary>
+		protected internal virtual System.String GetSummary()
+		{
+			return GetValue() + " = " + GetDescription();
+		}
+		
 		/// <summary>The sub-nodes of this explanation node. </summary>
 		public virtual Explanation[] GetDetails()
 		{
@@ -81,16 +104,14 @@
 		{
 			return ToString(0);
 		}
-		private System.String ToString(int depth)
+		protected internal virtual System.String ToString(int depth)
 		{
 			System.Text.StringBuilder buffer = new System.Text.StringBuilder();
 			for (int i = 0; i < depth; i++)
 			{
 				buffer.Append("  ");
 			}
-			buffer.Append(GetValue());
-			buffer.Append(" = ");
-			buffer.Append(GetDescription());
+			buffer.Append(GetSummary());
 			buffer.Append("\n");
 			
 			Explanation[] details = GetDetails();
@@ -113,10 +134,8 @@
 			buffer.Append("<ul>\n");
 			
 			buffer.Append("<li>");
-			buffer.Append(GetValue());
-			buffer.Append(" = ");
-			buffer.Append(GetDescription());
-			buffer.Append("</li>\n");
+			buffer.Append(GetSummary());
+			buffer.Append("<br />\n");
 			
 			Explanation[] details = GetDetails();
 			if (details != null)
@@ -127,6 +146,7 @@
 				}
 			}
 			
+			buffer.Append("</li>\n");
 			buffer.Append("</ul>\n");
 			
 			return buffer.ToString();

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldCache.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/FieldCache.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldCache.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldCache.cs Tue May  1 11:45:26 2007
@@ -16,6 +16,7 @@
  */
 
 using System;
+
 using IndexReader = Lucene.Net.Index.IndexReader;
 
 namespace Lucene.Net.Search
@@ -30,7 +31,7 @@
 	/// </author>
 	/// <since>   lucene 1.4
 	/// </since>
-	/// <version>  $Id: FieldCache.java 179605 2005-06-02 16:48:40Z cutting $
+	/// <version>  $Id: FieldCache.java 472959 2006-11-09 16:21:50Z yonik $
 	/// </version>
 	/// <summary>Expert: Stores term text values and document ordering data. </summary>
 	public class StringIndex
@@ -50,7 +51,7 @@
 		}
 	}
 	public struct FieldCache_Fields
-	{
+    {
 		/// <summary>Indicator for StringIndex values in the cache. </summary>
 		// NOTE: the value assigned to this constant must not be
 		// the same as any of those in SortField!!
@@ -187,18 +188,18 @@
 		/// <throws>  IOException  If any error occurs. </throws>
 		System.IComparable[] GetCustom(IndexReader reader, System.String field, SortComparator comparator);
 	}
-
-    /// <summary>Interface to parse ints from document fields.</summary>
-	/// <seealso cref="GetInts(IndexReader, String, IntParser)">
+	
+	/// <summary>Interface to parse ints from document fields.</summary>
+	/// <seealso cref="String, IntParser)">
 	/// </seealso>
 	public interface IntParser
 	{
 		/// <summary>Return an integer representation of this field's value. </summary>
 		int ParseInt(System.String string_Renamed);
 	}
-
-    /// <summary>Interface to parse floats from document fields.</summary>
-	/// <seealso cref="GetFloats(IndexReader, String, FloatParser)">
+	
+	/// <summary>Interface to parse floats from document fields.</summary>
+	/// <seealso cref="String, FloatParser)">
 	/// </seealso>
 	public interface FloatParser
 	{

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldCacheImpl.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/FieldCacheImpl.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldCacheImpl.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldCacheImpl.cs Tue May  1 11:45:26 2007
@@ -16,11 +16,11 @@
  */
 
 using System;
+
 using IndexReader = Lucene.Net.Index.IndexReader;
 using Term = Lucene.Net.Index.Term;
 using TermDocs = Lucene.Net.Index.TermDocs;
 using TermEnum = Lucene.Net.Index.TermEnum;
-using StringIndex = Lucene.Net.Search.StringIndex; // required by GCJ
 
 namespace Lucene.Net.Search
 {
@@ -35,23 +35,17 @@
 	/// </author>
 	/// <since>   lucene 1.4
 	/// </since>
-	/// <version>  $Id: FieldCacheImpl.java 331964 2005-11-09 06:44:10Z otis $
+	/// <version>  $Id: FieldCacheImpl.java 488908 2006-12-20 03:47:09Z yonik $
 	/// </version>
 	class FieldCacheImpl : FieldCache
 	{
-		public virtual void Close(IndexReader reader)
-		{ 
-			lock (this) 
-			{ 
-				System.Collections.Hashtable readerCache = (System.Collections.Hashtable) cache[reader]; 
-				if (readerCache != null) 
-				{ 
-					readerCache.Clear(); 
-					readerCache = null;
-				}
+        public virtual void Close(IndexReader reader)
+        {
+        }
 
-				cache.Remove(reader); 
-			} 
+		public FieldCacheImpl()
+		{
+			InitBlock();
 		}
 
 		public class AnonymousClassIntParser : IntParser
@@ -61,6 +55,7 @@
 				return System.Int32.Parse(value_Renamed);
 			}
 		}
+
 		public class AnonymousClassFloatParser : FloatParser
 		{
 			public virtual float ParseFloat(System.String value_Renamed)
@@ -69,148 +64,31 @@
 			}
 		}
 		
-		/// <summary>Expert: Every key in the internal cache is of this type. </summary>
-		internal class Entry
+		internal class AnonymousClassCache : Cache
 		{
-			internal System.String field; // which Field
-			internal int type; // which SortField type
-			internal System.Object custom; // which custom comparator
-            internal System.Globalization.CultureInfo locale; // the locale we're sorting (if string)
-			
-			/// <summary>Creates one of these objects. </summary>
-			internal Entry(System.String field, int type, System.Globalization.CultureInfo locale)
+			public AnonymousClassCache(Lucene.Net.Search.FieldCacheImpl enclosingInstance)
 			{
-				this.field = String.Intern(field);
-				this.type = type;
-				this.custom = null;
-                this.locale = locale;
-            }
-			
-			/// <summary>Creates one of these objects for a custom comparator. </summary>
-			internal Entry(System.String field, System.Object custom)
-			{
-				this.field = String.Intern(field);
-				this.type = SortField.CUSTOM;
-				this.custom = custom;
-                this.locale = null;
-            }
-			
-			/// <summary>Two of these are equal iff they reference the same field and type. </summary>
-			public  override bool Equals(System.Object o)
-			{
-				if (o is Entry)
-				{
-					Entry other = (Entry) o;
-					if (other.field == field && other.type == type)
-					{
-                        if (other.locale == null ? locale == null : other.locale.Equals(locale))
-                        {
-                            if (other.custom == null)
-                            {
-                                if (custom == null)
-                                    return true;
-                            }
-                            else if (other.custom.Equals(custom))
-                            {
-                                return true;
-                            }
-                        }
-					}
-				}
-				return false;
+				InitBlock(enclosingInstance);
 			}
-			
-			/// <summary>Composes a hashcode based on the field and type. </summary>
-			public override int GetHashCode()
+			private void  InitBlock(Lucene.Net.Search.FieldCacheImpl enclosingInstance)
 			{
-				return field.GetHashCode() ^ type ^ (custom == null ? 0 : custom.GetHashCode()) ^ (locale == null ? 0 : locale.GetHashCode());
+				this.enclosingInstance = enclosingInstance;
 			}
-		}
-		
-		private static readonly IntParser INT_PARSER;
-		
-		private static readonly FloatParser FLOAT_PARSER;
-		
-		/// <summary>The internal cache. Maps Entry to array of interpreted term values. *</summary>
-		internal System.Collections.IDictionary cache = new System.Collections.Hashtable();
-		
-		/// <summary>See if an object is in the cache. </summary>
-		internal virtual System.Object Lookup(IndexReader reader, System.String field, int type, System.Globalization.CultureInfo locale)
-		{
-			Entry entry = new Entry(field, type, locale);
-			lock (this)
-			{
-				System.Collections.Hashtable readerCache = (System.Collections.Hashtable) cache[reader];
-				if (readerCache == null)
-					return null;
-				return readerCache[entry];
-			}
-		}
-		
-		/// <summary>See if a custom object is in the cache. </summary>
-		internal virtual System.Object Lookup(IndexReader reader, System.String field, System.Object comparer)
-		{
-			Entry entry = new Entry(field, comparer);
-			lock (this)
-			{
-				System.Collections.Hashtable readerCache = (System.Collections.Hashtable) cache[reader];
-				if (readerCache == null)
-					return null;
-				return readerCache[entry];
-			}
-		}
-		
-		/// <summary>Put an object into the cache. </summary>
-		internal virtual System.Object Store(IndexReader reader, System.String field, int type, System.Globalization.CultureInfo locale, System.Object value_Renamed)
-		{
-			Entry entry = new Entry(field, type, locale);
-			lock (this)
-			{
-				System.Collections.Hashtable readerCache = (System.Collections.Hashtable) cache[reader];
-				if (readerCache == null)
-				{
-					readerCache = new System.Collections.Hashtable();
-					cache[reader] = readerCache;
-				}
-				System.Object tempObject;
-				tempObject = readerCache[entry];
-				readerCache[entry] = value_Renamed;
-				return tempObject;
-			}
-		}
-		
-		/// <summary>Put a custom object into the cache. </summary>
-		internal virtual System.Object Store(IndexReader reader, System.String field, System.Object comparer, System.Object value_Renamed)
-		{
-			Entry entry = new Entry(field, comparer);
-			lock (this)
+			private Lucene.Net.Search.FieldCacheImpl enclosingInstance;
+			public Lucene.Net.Search.FieldCacheImpl Enclosing_Instance
 			{
-				System.Collections.Hashtable readerCache = (System.Collections.Hashtable) cache[reader];
-				if (readerCache == null)
+				get
 				{
-					readerCache = new System.Collections.Hashtable();
-					cache[reader] = readerCache;
+					return enclosingInstance;
 				}
-				System.Object tempObject;
-				tempObject = readerCache[entry];
-				readerCache[entry] = value_Renamed;
-				return tempObject;
+				
 			}
-		}
-		
-		// inherit javadocs
-		public virtual int[] GetInts(IndexReader reader, System.String field)
-		{
-			return GetInts(reader, field, INT_PARSER);
-		}
-		
-		// inherit javadocs
-		public virtual int[] GetInts(IndexReader reader, System.String field, IntParser parser)
-		{
-			field = String.Intern(field);
-			System.Object ret = Lookup(reader, field, parser);
-			if (ret == null)
+			
+			protected internal override System.Object CreateValue(IndexReader reader, System.Object entryKey)
 			{
+				Entry entry = (Entry) entryKey;
+				System.String field = entry.field;
+				IntParser parser = (IntParser) entry.custom;
 				int[] retArray = new int[reader.MaxDoc()];
 				TermDocs termDocs = reader.TermDocs();
 				TermEnum termEnum = reader.Terms(new Term(field, ""));
@@ -219,7 +97,7 @@
 					do 
 					{
 						Term term = termEnum.Term();
-						if (term == null || term.Field() != field)
+						if (term == null || (System.Object) term.Field() != (System.Object) field)
 							break;
 						int termval = parser.ParseInt(term.Text());
 						termDocs.Seek(termEnum);
@@ -235,25 +113,35 @@
 					termDocs.Close();
 					termEnum.Close();
 				}
-				Store(reader, field, parser, retArray);
 				return retArray;
 			}
-			return (int[]) ret;
 		}
 		
-		// inherit javadocs
-		public virtual float[] GetFloats(IndexReader reader, System.String field)
-		{
-			return GetFloats(reader, field, FLOAT_PARSER);
-		}
-		
-		// inherit javadocs
-		public virtual float[] GetFloats(IndexReader reader, System.String field, FloatParser parser)
+		internal class AnonymousClassCache1:Cache
 		{
-			field = String.Intern(field);
-			System.Object ret = Lookup(reader, field, parser);
-			if (ret == null)
+			public AnonymousClassCache1(Lucene.Net.Search.FieldCacheImpl enclosingInstance)
+			{
+				InitBlock(enclosingInstance);
+			}
+			private void  InitBlock(Lucene.Net.Search.FieldCacheImpl enclosingInstance)
 			{
+				this.enclosingInstance = enclosingInstance;
+			}
+			private Lucene.Net.Search.FieldCacheImpl enclosingInstance;
+			public Lucene.Net.Search.FieldCacheImpl Enclosing_Instance
+			{
+				get
+				{
+					return enclosingInstance;
+				}
+				
+			}
+			
+			protected internal override System.Object CreateValue(IndexReader reader, System.Object entryKey)
+			{
+				Entry entry = (Entry) entryKey;
+				System.String field = entry.field;
+				FloatParser parser = (FloatParser) entry.custom;
 				float[] retArray = new float[reader.MaxDoc()];
 				TermDocs termDocs = reader.TermDocs();
 				TermEnum termEnum = reader.Terms(new Term(field, ""));
@@ -262,10 +150,9 @@
 					do 
 					{
 						Term term = termEnum.Term();
-						if (term == null || term.Field() != field)
+						if (term == null || (System.Object) term.Field() != (System.Object) field)
 							break;
-						float termval;
-						termval = SupportClass.Single.Parse(term.Text());
+						float termval = parser.ParseFloat(term.Text());
 						termDocs.Seek(termEnum);
 						while (termDocs.Next())
 						{
@@ -279,19 +166,33 @@
 					termDocs.Close();
 					termEnum.Close();
 				}
-				Store(reader, field, parser, retArray);
 				return retArray;
 			}
-			return (float[]) ret;
 		}
 		
-		// inherit javadocs
-		public virtual System.String[] GetStrings(IndexReader reader, System.String field)
+		internal class AnonymousClassCache2 : Cache
 		{
-			field = String.Intern(field);
-			System.Object ret = Lookup(reader, field, SortField.STRING, null);
-			if (ret == null)
+			public AnonymousClassCache2(Lucene.Net.Search.FieldCacheImpl enclosingInstance)
+			{
+				InitBlock(enclosingInstance);
+			}
+			private void  InitBlock(Lucene.Net.Search.FieldCacheImpl enclosingInstance)
+			{
+				this.enclosingInstance = enclosingInstance;
+			}
+			private Lucene.Net.Search.FieldCacheImpl enclosingInstance;
+			public Lucene.Net.Search.FieldCacheImpl Enclosing_Instance
+			{
+				get
+				{
+					return enclosingInstance;
+				}
+				
+			}
+			
+			protected internal override System.Object CreateValue(IndexReader reader, System.Object fieldKey)
 			{
+				System.String field = String.Intern(((System.String) fieldKey));
 				System.String[] retArray = new System.String[reader.MaxDoc()];
 				TermDocs termDocs = reader.TermDocs();
 				TermEnum termEnum = reader.Terms(new Term(field, ""));
@@ -300,7 +201,7 @@
 					do 
 					{
 						Term term = termEnum.Term();
-						if (term == null || term.Field() != field)
+						if (term == null || (System.Object) term.Field() != (System.Object) field)
 							break;
 						System.String termval = term.Text();
 						termDocs.Seek(termEnum);
@@ -316,19 +217,33 @@
 					termDocs.Close();
 					termEnum.Close();
 				}
-				Store(reader, field, SortField.STRING, null, retArray);
 				return retArray;
 			}
-			return (System.String[]) ret;
 		}
 		
-		// inherit javadocs
-		public virtual StringIndex GetStringIndex(IndexReader reader, System.String field)
+		internal class AnonymousClassCache3 : Cache
 		{
-			field = String.Intern(field);
-			System.Object ret = Lookup(reader, field, Lucene.Net.Search.FieldCache_Fields.STRING_INDEX, null);
-			if (ret == null)
+			public AnonymousClassCache3(Lucene.Net.Search.FieldCacheImpl enclosingInstance)
 			{
+				InitBlock(enclosingInstance);
+			}
+			private void  InitBlock(Lucene.Net.Search.FieldCacheImpl enclosingInstance)
+			{
+				this.enclosingInstance = enclosingInstance;
+			}
+			private Lucene.Net.Search.FieldCacheImpl enclosingInstance;
+			public Lucene.Net.Search.FieldCacheImpl Enclosing_Instance
+			{
+				get
+				{
+					return enclosingInstance;
+				}
+				
+			}
+			
+			protected internal override System.Object CreateValue(IndexReader reader, System.Object fieldKey)
+			{
+				System.String field = String.Intern(((System.String) fieldKey));
 				int[] retArray = new int[reader.MaxDoc()];
 				System.String[] mterms = new System.String[reader.MaxDoc() + 1];
 				TermDocs termDocs = reader.TermDocs();
@@ -346,7 +261,7 @@
 					do 
 					{
 						Term term = termEnum.Term();
-						if (term == null || term.Field() != field)
+						if (term == null || (System.Object) term.Field() != (System.Object) field)
 							break;
 						
 						// store term text
@@ -386,31 +301,34 @@
 					mterms = terms;
 				}
 				
-                StringIndex value_Renamed = new StringIndex(retArray, mterms);
-				Store(reader, field, Lucene.Net.Search.FieldCache_Fields.STRING_INDEX, null, value_Renamed);
+				StringIndex value_Renamed = new StringIndex(retArray, mterms);
 				return value_Renamed;
 			}
-			return (StringIndex) ret;
 		}
 		
-		/// <summary>The pattern used to detect integer values in a field </summary>
-		/// <summary>removed for java 1.3 compatibility
-		/// protected static final Pattern pIntegers = Pattern.compile ("[0-9\\-]+");
-		/// 
-		/// </summary>
-		
-		/// <summary>The pattern used to detect float values in a field </summary>
-		/// <summary> removed for java 1.3 compatibility
-		/// protected static final Object pFloats = Pattern.compile ("[0-9+\\-\\.eEfFdD]+");
-		/// </summary>
-		
-		// inherit javadocs
-		public virtual System.Object GetAuto(IndexReader reader, System.String field)
+		internal class AnonymousClassCache4 : Cache
 		{
-			field = String.Intern(field);
-			System.Object ret = Lookup(reader, field, SortField.AUTO, null);
-			if (ret == null)
+			public AnonymousClassCache4(Lucene.Net.Search.FieldCacheImpl enclosingInstance)
 			{
+				InitBlock(enclosingInstance);
+			}
+			private void  InitBlock(Lucene.Net.Search.FieldCacheImpl enclosingInstance)
+			{
+				this.enclosingInstance = enclosingInstance;
+			}
+			private Lucene.Net.Search.FieldCacheImpl enclosingInstance;
+			public Lucene.Net.Search.FieldCacheImpl Enclosing_Instance
+			{
+				get
+				{
+					return enclosingInstance;
+				}
+				
+			}
+			
+			protected internal override System.Object CreateValue(IndexReader reader, System.Object fieldKey)
+			{
+				System.String field = String.Intern(((System.String) fieldKey));
 				TermEnum enumerator = reader.Terms(new Term(field, ""));
 				try
 				{
@@ -419,60 +337,75 @@
 					{
 						throw new System.SystemException("no terms in field " + field + " - cannot determine sort type");
 					}
-					if (term.Field() == field)
+					System.Object ret = null;
+					if ((System.Object) term.Field() == (System.Object) field)
 					{
 						System.String termtext = term.Text().Trim();
 						
-                        /// <summary> Java 1.4 level code:
-                        /// if (pIntegers.matcher(termtext).matches())
-                        /// return IntegerSortedHitQueue.comparator (reader, enumerator, field);
-                        /// else if (pFloats.matcher(termtext).matches())
-                        /// return FloatSortedHitQueue.comparator (reader, enumerator, field);
-                        /// </summary>
+						/// <summary> Java 1.4 level code:
+						/// if (pIntegers.matcher(termtext).matches())
+						/// return IntegerSortedHitQueue.comparator (reader, enumerator, field);
+						/// else if (pFloats.matcher(termtext).matches())
+						/// return FloatSortedHitQueue.comparator (reader, enumerator, field);
+						/// </summary>
 						
-                        // Java 1.3 level code:
-                        try
+						// Java 1.3 level code:
+						try
 						{
 							System.Int32.Parse(termtext);
-							ret = GetInts(reader, field);
+							ret = Enclosing_Instance.GetInts(reader, field);
 						}
 						catch (System.FormatException nfe1)
 						{
 							try
 							{
 								System.Single.Parse(termtext);
-								ret = GetFloats(reader, field);
+								ret = Enclosing_Instance.GetFloats(reader, field);
 							}
 							catch (System.FormatException nfe2)
 							{
-								ret = GetStringIndex(reader, field);
+								ret = Enclosing_Instance.GetStringIndex(reader, field);
 							}
 						}
-						if (ret != null)
-						{
-							Store(reader, field, SortField.AUTO, null, ret);
-						}
 					}
 					else
 					{
 						throw new System.SystemException("field \"" + field + "\" does not appear to be indexed");
 					}
+					return ret;
 				}
 				finally
 				{
 					enumerator.Close();
 				}
 			}
-			return ret;
 		}
 		
-		// inherit javadocs
-		public virtual System.IComparable[] GetCustom(IndexReader reader, System.String field, SortComparator comparator)
+		internal class AnonymousClassCache5 : Cache
 		{
-			field = String.Intern(field);
-			System.Object ret = Lookup(reader, field, comparator);
-			if (ret == null)
+			public AnonymousClassCache5(Lucene.Net.Search.FieldCacheImpl enclosingInstance)
+			{
+				InitBlock(enclosingInstance);
+			}
+			private void  InitBlock(Lucene.Net.Search.FieldCacheImpl enclosingInstance)
+			{
+				this.enclosingInstance = enclosingInstance;
+			}
+			private Lucene.Net.Search.FieldCacheImpl enclosingInstance;
+			public Lucene.Net.Search.FieldCacheImpl Enclosing_Instance
 			{
+				get
+				{
+					return enclosingInstance;
+				}
+				
+			}
+			
+			protected internal override System.Object CreateValue(IndexReader reader, System.Object entryKey)
+			{
+				Entry entry = (Entry) entryKey;
+				System.String field = entry.field;
+				SortComparator comparator = (SortComparator) entry.custom;
 				System.IComparable[] retArray = new System.IComparable[reader.MaxDoc()];
 				TermDocs termDocs = reader.TermDocs();
 				TermEnum termEnum = reader.Terms(new Term(field, ""));
@@ -481,7 +414,7 @@
 					do 
 					{
 						Term term = termEnum.Term();
-						if (term == null || term.Field() != field)
+						if (term == null || (System.Object) term.Field() != (System.Object) field)
 							break;
 						System.IComparable termval = comparator.GetComparable(term.Text());
 						termDocs.Seek(termEnum);
@@ -497,11 +430,206 @@
 					termDocs.Close();
 					termEnum.Close();
 				}
-				Store(reader, field, comparator, retArray);
 				return retArray;
 			}
-			return (System.IComparable[]) ret;
 		}
+		private void  InitBlock()
+		{
+			intsCache = new AnonymousClassCache(this);
+			floatsCache = new AnonymousClassCache1(this);
+			stringsCache = new AnonymousClassCache2(this);
+			stringsIndexCache = new AnonymousClassCache3(this);
+			autoCache = new AnonymousClassCache4(this);
+			customCache = new AnonymousClassCache5(this);
+		}
+		
+		/// <summary>Expert: Internal cache. </summary>
+		internal abstract class Cache
+		{
+			private System.Collections.IDictionary readerCache = new System.Collections.Hashtable();
+			
+			protected internal abstract System.Object CreateValue(IndexReader reader, System.Object key);
+			
+			public virtual System.Object Get(IndexReader reader, System.Object key)
+			{
+				System.Collections.IDictionary innerCache;
+				System.Object value_Renamed;
+				lock (readerCache.SyncRoot)
+				{
+					innerCache = (System.Collections.IDictionary) readerCache[reader];
+					if (innerCache == null)
+					{
+						innerCache = new System.Collections.Hashtable();
+						readerCache[reader] = innerCache;
+						value_Renamed = null;
+					}
+					else
+					{
+						value_Renamed = innerCache[key];
+					}
+					if (value_Renamed == null)
+					{
+						value_Renamed = new CreationPlaceholder();
+						innerCache[key] = value_Renamed;
+					}
+				}
+				if (value_Renamed is CreationPlaceholder)
+				{
+					lock (value_Renamed)
+					{
+						CreationPlaceholder progress = (CreationPlaceholder) value_Renamed;
+						if (progress.value_Renamed == null)
+						{
+							progress.value_Renamed = CreateValue(reader, key);
+							lock (readerCache.SyncRoot)
+							{
+								innerCache[key] = progress.value_Renamed;
+							}
+						}
+						return progress.value_Renamed;
+					}
+				}
+				return value_Renamed;
+			}
+		}
+		
+		internal sealed class CreationPlaceholder
+		{
+			internal System.Object value_Renamed;
+		}
+		
+		/// <summary>Expert: Every composite-key in the internal cache is of this type. </summary>
+		internal class Entry
+		{
+			internal System.String field; // which Fieldable
+			internal int type; // which SortField type
+			internal System.Object custom; // which custom comparator
+			internal System.Globalization.CultureInfo locale; // the locale we're sorting (if string)
+			
+			/// <summary>Creates one of these objects. </summary>
+			internal Entry(System.String field, int type, System.Globalization.CultureInfo locale)
+			{
+				this.field = String.Intern(field);
+				this.type = type;
+				this.custom = null;
+				this.locale = locale;
+			}
+			
+			/// <summary>Creates one of these objects for a custom comparator. </summary>
+			internal Entry(System.String field, System.Object custom)
+			{
+				this.field = String.Intern(field);
+				this.type = SortField.CUSTOM;
+				this.custom = custom;
+				this.locale = null;
+			}
+			
+			/// <summary>Two of these are equal iff they reference the same field and type. </summary>
+			public  override bool Equals(System.Object o)
+			{
+				if (o is Entry)
+				{
+					Entry other = (Entry) o;
+					if ((System.Object) other.field == (System.Object) field && other.type == type)
+					{
+						if (other.locale == null?locale == null:other.locale.Equals(locale))
+						{
+							if (other.custom == null)
+							{
+								if (custom == null)
+									return true;
+							}
+							else if (other.custom.Equals(custom))
+							{
+								return true;
+							}
+						}
+					}
+				}
+				return false;
+			}
+			
+			/// <summary>Composes a hashcode based on the field and type. </summary>
+			public override int GetHashCode()
+			{
+				return field.GetHashCode() ^ type ^ (custom == null ? 0 : custom.GetHashCode()) ^ (locale == null ? 0 : locale.GetHashCode());
+			}
+		}
+		
+		private static readonly IntParser INT_PARSER;
+		
+		private static readonly FloatParser FLOAT_PARSER;
+		
+		// inherit javadocs
+		public virtual int[] GetInts(IndexReader reader, System.String field)
+		{
+			return GetInts(reader, field, INT_PARSER);
+		}
+		
+		// inherit javadocs
+		public virtual int[] GetInts(IndexReader reader, System.String field, IntParser parser)
+		{
+			return (int[]) intsCache.Get(reader, new Entry(field, parser));
+		}
+		
+		internal Cache intsCache;
+		
+		// inherit javadocs
+		public virtual float[] GetFloats(IndexReader reader, System.String field)
+		{
+			return GetFloats(reader, field, FLOAT_PARSER);
+		}
+		
+		// inherit javadocs
+		public virtual float[] GetFloats(IndexReader reader, System.String field, FloatParser parser)
+		{
+			return (float[]) floatsCache.Get(reader, new Entry(field, parser));
+		}
+		
+		internal Cache floatsCache;
+		
+		// inherit javadocs
+		public virtual System.String[] GetStrings(IndexReader reader, System.String field)
+		{
+			return (System.String[]) stringsCache.Get(reader, field);
+		}
+		
+		internal Cache stringsCache;
+		
+		// inherit javadocs
+		public virtual StringIndex GetStringIndex(IndexReader reader, System.String field)
+		{
+			return (StringIndex) stringsIndexCache.Get(reader, field);
+		}
+		
+		internal Cache stringsIndexCache;
+		
+		/// <summary>The pattern used to detect integer values in a field </summary>
+		/// <summary>removed for java 1.3 compatibility
+		/// protected static final Pattern pIntegers = Pattern.compile ("[0-9\\-]+");
+		/// 
+		/// </summary>
+		
+		/// <summary>The pattern used to detect float values in a field </summary>
+		/// <summary> removed for java 1.3 compatibility
+		/// protected static final Object pFloats = Pattern.compile ("[0-9+\\-\\.eEfFdD]+");
+		/// </summary>
+		
+		// inherit javadocs
+		public virtual System.Object GetAuto(IndexReader reader, System.String field)
+		{
+			return autoCache.Get(reader, field);
+		}
+		
+		internal Cache autoCache;
+		
+		// inherit javadocs
+		public virtual System.IComparable[] GetCustom(IndexReader reader, System.String field, SortComparator comparator)
+		{
+			return (System.IComparable[]) customCache.Get(reader, new Entry(field, comparator));
+		}
+		
+		internal Cache customCache;
 		static FieldCacheImpl()
 		{
 			INT_PARSER = new AnonymousClassIntParser();

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldDoc.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/FieldDoc.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldDoc.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldDoc.cs Tue May  1 11:45:26 2007
@@ -40,7 +40,7 @@
 	/// </author>
 	/// <since>   lucene 1.4
 	/// </since>
-	/// <version>  $Id: FieldDoc.java 164865 2005-04-26 19:30:20Z cutting $
+	/// <version>  $Id: FieldDoc.java 472959 2006-11-09 16:21:50Z yonik $
 	/// </version>
 	/// <seealso cref="ScoreDoc">
 	/// </seealso>
@@ -57,7 +57,7 @@
 		/// </summary>
 		/// <seealso cref="Sort">
 		/// </seealso>
-		/// <seealso cref="Searcher.Search(Query,Filter,int,Sort)">
+		/// <seealso cref="Searcher#Search(Query,Filter,int,Sort)">
 		/// </seealso>
 		public System.IComparable[] fields;
 		

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldDocSortedHitQueue.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/FieldDocSortedHitQueue.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldDocSortedHitQueue.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldDocSortedHitQueue.cs Tue May  1 11:45:26 2007
@@ -16,6 +16,7 @@
  */
 
 using System;
+
 using PriorityQueue = Lucene.Net.Util.PriorityQueue;
 
 namespace Lucene.Net.Search
@@ -31,7 +32,7 @@
 	/// </author>
 	/// <since>   lucene 1.4
 	/// </since>
-	/// <version>  $Id: FieldDocSortedHitQueue.java 332431 2005-11-11 03:13:10Z yonik $
+	/// <version>  $Id: FieldDocSortedHitQueue.java 472959 2006-11-09 16:21:50Z yonik $
 	/// </version>
 	class FieldDocSortedHitQueue : PriorityQueue
 	{
@@ -46,7 +47,7 @@
 		
 		
 		/// <summary> Creates a hit queue sorted by the given list of fields.</summary>
-		/// <param name="fields">Field names, in priority order (highest priority first).
+		/// <param name="fields">Fieldable names, in priority order (highest priority first).
 		/// </param>
 		/// <param name="size"> The number of hits to retain.  Must be greater than zero.
 		/// </param>
@@ -64,7 +65,7 @@
 		/// type until the values come back.  The fields can only be set once.
 		/// This method is thread safe.
 		/// </summary>
-		/// <param name="fields">
+		/// <param name="">fields
 		/// </param>
 		internal virtual void  SetFields(SortField[] fields)
 		{
@@ -163,15 +164,12 @@
 						}
 						else
 						{
-							//UPGRADE_TODO: The equivalent in .NET for method 'java.text.Collator.compare' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
 							c = collators[i].Compare(s1.ToString(), s2.ToString());
 						}
 						break;
 					
 					case SortField.FLOAT: 
-						//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
 						float f1 = (float) ((System.Single) docA.fields[i]);
-						//UPGRADE_TODO: The equivalent in .NET for method 'java.lang.Float.floatValue' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
 						float f2 = (float) ((System.Single) docB.fields[i]);
 						if (f1 < f2)
 							c = - 1;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldSortedHitQueue.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/FieldSortedHitQueue.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldSortedHitQueue.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldSortedHitQueue.cs Tue May  1 11:45:26 2007
@@ -16,6 +16,7 @@
  */
 
 using System;
+
 using IndexReader = Lucene.Net.Index.IndexReader;
 using PriorityQueue = Lucene.Net.Util.PriorityQueue;
 
@@ -32,29 +33,58 @@
 	/// </author>
 	/// <since>   lucene 1.4
 	/// </since>
-	/// <version>  $Id: FieldSortedHitQueue.java 354819 2005-12-07 17:48:37Z yonik $
+	/// <version>  $Id: FieldSortedHitQueue.java 477084 2006-11-20 07:10:04Z otis $
 	/// </version>
-	/// <seealso cref="Searcher.Search(Query,Filter,int,Sort)">
+	/// <seealso cref="Searcher#Search(Query,Filter,int,Sort)">
 	/// </seealso>
 	/// <seealso cref="FieldCache">
 	/// </seealso>
 	public class FieldSortedHitQueue : PriorityQueue
 	{
-		internal static void Close(IndexReader reader) 
-		{ 
-			lock (Comparators.SyncRoot) 
-			{ 
-				System.Collections.Hashtable readerCache = (System.Collections.Hashtable) Comparators[reader]; 
-				if (readerCache != null) 
-				{ 
-					readerCache.Clear(); 
-					readerCache = null;
-				} 
-
-				Comparators.Remove(reader);
-			} 
+		internal class AnonymousClassCache : FieldCacheImpl.Cache
+		{
+			
+			protected internal override System.Object CreateValue(IndexReader reader, System.Object entryKey)
+			{
+				FieldCacheImpl.Entry entry = (FieldCacheImpl.Entry) entryKey;
+				System.String fieldname = entry.field;
+				int type = entry.type;
+				System.Globalization.CultureInfo locale = entry.locale;
+				SortComparatorSource factory = (SortComparatorSource) entry.custom;
+				ScoreDocComparator comparator;
+				switch (type)
+				{
+					
+					case SortField.AUTO: 
+						comparator = Lucene.Net.Search.FieldSortedHitQueue.ComparatorAuto(reader, fieldname);
+						break;
+					
+					case SortField.INT: 
+						comparator = Lucene.Net.Search.FieldSortedHitQueue.comparatorInt(reader, fieldname);
+						break;
+					
+					case SortField.FLOAT: 
+						comparator = Lucene.Net.Search.FieldSortedHitQueue.comparatorFloat(reader, fieldname);
+						break;
+					
+					case SortField.STRING: 
+						if (locale != null)
+							comparator = Lucene.Net.Search.FieldSortedHitQueue.comparatorStringLocale(reader, fieldname, locale);
+						else
+							comparator = Lucene.Net.Search.FieldSortedHitQueue.comparatorString(reader, fieldname);
+						break;
+					
+					case SortField.CUSTOM: 
+						comparator = factory.NewComparator(reader, fieldname);
+						break;
+					
+					default: 
+						throw new System.SystemException("unknown field type: " + type);
+					
+				}
+				return comparator;
+			}
 		}
-
 		private class AnonymousClassScoreDocComparator : ScoreDocComparator
 		{
 			public AnonymousClassScoreDocComparator(int[] fieldOrder)
@@ -65,8 +95,7 @@
 			{
 				this.fieldOrder = fieldOrder;
 			}
-
-            private int[] fieldOrder;
+			private int[] fieldOrder;
 			
 			public int Compare(ScoreDoc i, ScoreDoc j)
 			{
@@ -157,21 +186,38 @@
 		}
 		private class AnonymousClassScoreDocComparator3 : ScoreDocComparator
 		{
-			public AnonymousClassScoreDocComparator3(System.Globalization.CompareInfo collator, System.String[] index)
+			public AnonymousClassScoreDocComparator3(System.String[] index, System.Globalization.CompareInfo collator)
 			{
-				InitBlock(collator, index);
+				InitBlock(index, collator);
 			}
-			private void  InitBlock(System.Globalization.CompareInfo collator, System.String[] index)
+			private void  InitBlock(System.String[] index, System.Globalization.CompareInfo collator)
 			{
-				this.collator = collator;
 				this.index = index;
+				this.collator = collator;
 			}
-			private System.Globalization.CompareInfo collator;
 			private System.String[] index;
+			private System.Globalization.CompareInfo collator;
 			
 			public int Compare(ScoreDoc i, ScoreDoc j)
 			{
-				return collator.Compare(index[i.doc].ToString(), index[j.doc].ToString());
+				System.String is_Renamed = index[i.doc];
+				System.String js = index[j.doc];
+				if ((System.Object) is_Renamed == (System.Object) js)
+				{
+					return 0;
+				}
+				else if (is_Renamed == null)
+				{
+					return - 1;
+				}
+				else if (js == null)
+				{
+					return 1;
+				}
+				else
+				{
+					return collator.Compare(is_Renamed.ToString(), js.ToString());
+				}
 			}
 			
 			public virtual System.IComparable SortValue(ScoreDoc i)
@@ -188,7 +234,7 @@
 		/// <summary> Creates a hit queue sorted by the given list of fields.</summary>
 		/// <param name="reader"> Index to use.
 		/// </param>
-		/// <param name="fields">Field names, in priority order (highest priority first).  Cannot be <code>null</code> or empty.
+		/// <param name="fields">Fieldable names, in priority order (highest priority first).  Cannot be <code>null</code> or empty.
 		/// </param>
 		/// <param name="size"> The number of hits to retain.  Must be greater than zero.
 		/// </param>
@@ -284,7 +330,7 @@
 		/// </param>
 		/// <returns>  The same FieldDoc passed in.
 		/// </returns>
-		/// <seealso cref="Searchable.Search(Weight,Filter,int,Sort)">
+		/// <seealso cref="Searchable#Search(Weight,Filter,int,Sort)">
 		/// </seealso>
 		internal virtual FieldDoc FillFields(FieldDoc doc)
 		{
@@ -304,96 +350,30 @@
 			return fields;
 		}
 		
-		/// <summary>Internal cache of comparators. Similar to FieldCache, only
-		/// caches comparators instead of term values. 
-		/// </summary>
-		internal static readonly System.Collections.IDictionary Comparators = new System.Collections.Hashtable();
-		
-		/// <summary>Returns a comparator if it is in the cache. </summary>
-		internal static ScoreDocComparator Lookup(IndexReader reader, System.String field, int type, System.Globalization.CultureInfo locale, System.Object factory)
-		{
-			FieldCacheImpl.Entry entry = (factory != null) ? new FieldCacheImpl.Entry(field, factory) : new FieldCacheImpl.Entry(field, type, locale);
-			lock (Comparators.SyncRoot)
-			{
-				System.Collections.Hashtable readerCache = (System.Collections.Hashtable) Comparators[reader];
-				if (readerCache == null)
-					return null;
-				return (ScoreDocComparator) readerCache[entry];
-			}
-		}
-		
-		/// <summary>Stores a comparator into the cache. </summary>
-		internal static System.Object Store(IndexReader reader, System.String field, int type, System.Globalization.CultureInfo locale, System.Object factory, System.Object value_Renamed)
-		{
-			FieldCacheImpl.Entry entry = (factory != null) ? new FieldCacheImpl.Entry(field, factory) : new FieldCacheImpl.Entry(field, type, locale);
-			lock (Comparators.SyncRoot)
-			{
-				System.Collections.Hashtable readerCache = (System.Collections.Hashtable) Comparators[reader];
-				if (readerCache == null)
-				{
-					readerCache = new System.Collections.Hashtable();
-					Comparators[reader] = readerCache;
-				}
-				System.Object tempObject;
-				tempObject = readerCache[entry];
-				readerCache[entry] = value_Renamed;
-				return tempObject;
-			}
-		}
-		
-		internal static ScoreDocComparator GetCachedComparator(IndexReader reader, System.String fieldname, int type, System.Globalization.CultureInfo locale, SortComparatorSource factory)
+		internal static ScoreDocComparator GetCachedComparator(IndexReader reader, System.String field, int type, System.Globalization.CultureInfo locale, SortComparatorSource factory)
 		{
 			if (type == SortField.DOC)
 				return Lucene.Net.Search.ScoreDocComparator_Fields.INDEXORDER;
 			if (type == SortField.SCORE)
 				return Lucene.Net.Search.ScoreDocComparator_Fields.RELEVANCE;
-			ScoreDocComparator comparator = Lookup(reader, fieldname, type, locale, factory);
-			if (comparator == null)
-			{
-				switch (type)
-				{
-					
-					case SortField.AUTO: 
-						comparator = ComparatorAuto(reader, fieldname);
-						break;
-					
-					case SortField.INT: 
-						comparator = ComparatorInt(reader, fieldname);
-						break;
-					
-					case SortField.FLOAT: 
-						comparator = ComparatorFloat(reader, fieldname);
-						break;
-					
-					case SortField.STRING: 
-						if (locale != null)
-							comparator = ComparatorStringLocale(reader, fieldname, locale);
-						else
-							comparator = ComparatorString(reader, fieldname);
-						break;
-					
-					case SortField.CUSTOM: 
-						comparator = factory.NewComparator(reader, fieldname);
-						break;
-					
-					default: 
-						throw new System.SystemException("unknown field type: " + type);
-					
-				}
-				Store(reader, fieldname, type, locale, factory, comparator);
-			}
-			return comparator;
+			FieldCacheImpl.Entry entry = (factory != null) ? new FieldCacheImpl.Entry(field, factory) : new FieldCacheImpl.Entry(field, type, locale);
+			return (ScoreDocComparator) Comparators.Get(reader, entry);
 		}
 		
+		/// <summary>Internal cache of comparators. Similar to FieldCache, only
+		/// caches comparators instead of term values. 
+		/// </summary>
+		internal static readonly FieldCacheImpl.Cache Comparators;
+		
 		/// <summary> Returns a comparator for sorting hits according to a field containing integers.</summary>
 		/// <param name="reader"> Index to use.
 		/// </param>
-		/// <param name="fieldname"> Field containg integer values.
+		/// <param name="fieldname"> Fieldable containg integer values.
 		/// </param>
 		/// <returns>  Comparator for sorting hits.
 		/// </returns>
 		/// <throws>  IOException If an error occurs reading the index. </throws>
-		internal static ScoreDocComparator ComparatorInt(IndexReader reader, System.String fieldname)
+		internal static ScoreDocComparator comparatorInt(IndexReader reader, System.String fieldname)
 		{
 			System.String field = String.Intern(fieldname);
 			int[] fieldOrder = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetInts(reader, field);
@@ -403,12 +383,12 @@
 		/// <summary> Returns a comparator for sorting hits according to a field containing floats.</summary>
 		/// <param name="reader"> Index to use.
 		/// </param>
-		/// <param name="fieldname"> Field containg float values.
+		/// <param name="fieldname"> Fieldable containg float values.
 		/// </param>
 		/// <returns>  Comparator for sorting hits.
 		/// </returns>
 		/// <throws>  IOException If an error occurs reading the index. </throws>
-		internal static ScoreDocComparator ComparatorFloat(IndexReader reader, System.String fieldname)
+		internal static ScoreDocComparator comparatorFloat(IndexReader reader, System.String fieldname)
 		{
 			System.String field = String.Intern(fieldname);
 			float[] fieldOrder = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetFloats(reader, field);
@@ -418,12 +398,12 @@
 		/// <summary> Returns a comparator for sorting hits according to a field containing strings.</summary>
 		/// <param name="reader"> Index to use.
 		/// </param>
-		/// <param name="fieldname"> Field containg string values.
+		/// <param name="fieldname"> Fieldable containg string values.
 		/// </param>
 		/// <returns>  Comparator for sorting hits.
 		/// </returns>
 		/// <throws>  IOException If an error occurs reading the index. </throws>
-		internal static ScoreDocComparator ComparatorString(IndexReader reader, System.String fieldname)
+		internal static ScoreDocComparator comparatorString(IndexReader reader, System.String fieldname)
 		{
 			System.String field = String.Intern(fieldname);
 			Lucene.Net.Search.StringIndex index = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetStringIndex(reader, field);
@@ -433,17 +413,17 @@
 		/// <summary> Returns a comparator for sorting hits according to a field containing strings.</summary>
 		/// <param name="reader"> Index to use.
 		/// </param>
-		/// <param name="fieldname"> Field containg string values.
+		/// <param name="fieldname"> Fieldable containg string values.
 		/// </param>
 		/// <returns>  Comparator for sorting hits.
 		/// </returns>
 		/// <throws>  IOException If an error occurs reading the index. </throws>
-		internal static ScoreDocComparator ComparatorStringLocale(IndexReader reader, System.String fieldname, System.Globalization.CultureInfo locale)
+		internal static ScoreDocComparator comparatorStringLocale(IndexReader reader, System.String fieldname, System.Globalization.CultureInfo locale)
 		{
 			System.Globalization.CompareInfo collator = locale.CompareInfo;
 			System.String field = String.Intern(fieldname);
 			System.String[] index = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetStrings(reader, field);
-			return new AnonymousClassScoreDocComparator3(collator, index);
+			return new AnonymousClassScoreDocComparator3(index, collator);
 		}
 		
 		/// <summary> Returns a comparator for sorting hits according to values in the given field.
@@ -453,7 +433,7 @@
 		/// </summary>
 		/// <param name="reader"> Index to use.
 		/// </param>
-		/// <param name="fieldname"> Field containg values.
+		/// <param name="fieldname"> Fieldable containg values.
 		/// </param>
 		/// <returns>  Comparator for sorting hits.
 		/// </returns>
@@ -464,24 +444,28 @@
 			System.Object lookupArray = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetAuto(reader, field);
 			if (lookupArray is Lucene.Net.Search.StringIndex)
 			{
-				return ComparatorString(reader, field);
+				return comparatorString(reader, field);
 			}
 			else if (lookupArray is int[])
 			{
-				return ComparatorInt(reader, field);
+				return comparatorInt(reader, field);
 			}
 			else if (lookupArray is float[])
 			{
-				return ComparatorFloat(reader, field);
+				return comparatorFloat(reader, field);
 			}
 			else if (lookupArray is System.String[])
 			{
-				return ComparatorString(reader, field);
+				return comparatorString(reader, field);
 			}
 			else
 			{
 				throw new System.SystemException("unknown data type in field '" + field + "'");
 			}
+		}
+		static FieldSortedHitQueue()
+		{
+			Comparators = new AnonymousClassCache();
 		}
 	}
 }

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Filter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Filter.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Filter.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Filter.cs Tue May  1 11:45:26 2007
@@ -16,6 +16,7 @@
  */
 
 using System;
+
 using IndexReader = Lucene.Net.Index.IndexReader;
 
 namespace Lucene.Net.Search

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FilteredQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/FilteredQuery.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FilteredQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FilteredQuery.cs Tue May  1 11:45:26 2007
@@ -16,6 +16,7 @@
  */
 
 using System;
+
 using IndexReader = Lucene.Net.Index.IndexReader;
 using ToStringUtils = Lucene.Net.Util.ToStringUtils;
 
@@ -36,7 +37,7 @@
 	/// </author>
 	/// <since>   1.4
 	/// </since>
-	/// <version>  $Id: FilteredQuery.java 331113 2005-11-06 15:55:45Z yonik $
+	/// <version>  $Id: FilteredQuery.java 472959 2006-11-09 16:21:50Z yonik $
 	/// </version>
 	/// <seealso cref="CachingWrapperFilter">
 	/// </seealso>
@@ -58,10 +59,10 @@
 					this.scorer = scorer;
 					this.enclosingInstance = enclosingInstance;
 				}
-                private System.Collections.BitArray bitset;
-                private Lucene.Net.Search.Scorer scorer;
-                private AnonymousClassWeight enclosingInstance;
-                public AnonymousClassWeight Enclosing_Instance
+				private System.Collections.BitArray bitset;
+				private Lucene.Net.Search.Scorer scorer;
+				private AnonymousClassWeight enclosingInstance;
+				public AnonymousClassWeight Enclosing_Instance
 				{
 					get
 					{
@@ -69,33 +70,33 @@
 					}
 					
 				}
-				internal AnonymousClassScorer(System.Collections.BitArray bitset, Lucene.Net.Search.Scorer scorer, AnonymousClassWeight enclosingInstance, Lucene.Net.Search.Similarity Param1) : base(Param1)
+				internal AnonymousClassScorer(System.Collections.BitArray bitset, Lucene.Net.Search.Scorer scorer, AnonymousClassWeight enclosingInstance, Lucene.Net.Search.Similarity Param1):base(Param1)
 				{
 					InitBlock(bitset, scorer, enclosingInstance);
 				}
 				
 				public override bool Next()
 				{
-                    do 
-                    {
-                        if (!scorer.Next())
-                        {
-                            return false;
-                        }
-                    }
-                    while (!bitset.Get(scorer.Doc()));
-                    /* When skipTo() is allowed on scorer it should be used here
-                    * in combination with bitset.nextSetBit(...)
-                    * See the while loop in skipTo() below.
-                    */
-                    return true;
-                }
+					do 
+					{
+						if (!scorer.Next())
+						{
+							return false;
+						}
+					}
+					while (!bitset.Get(scorer.Doc()));
+					/* When skipTo() is allowed on scorer it should be used here
+					* in combination with bitset.nextSetBit(...)
+					* See the while loop in skipTo() below.
+					*/
+					return true;
+				}
 				public override int Doc()
 				{
 					return scorer.Doc();
 				}
 				
-                public override bool SkipTo(int i)
+				public override bool SkipTo(int i)
 				{
 					if (!scorer.SkipTo(i))
 					{
@@ -118,8 +119,8 @@
 				
 				public override float Score()
 				{
-                    return scorer.Score();
-                }
+					return scorer.Score();
+				}
 				
 				// add an explanation about whether the document was filtered
 				public override Explanation Explain(int i)
@@ -165,7 +166,14 @@
 			}
 			public virtual Explanation Explain(IndexReader ir, int i)
 			{
-				return weight.Explain(ir, i);
+				Explanation inner = weight.Explain(ir, i);
+				Filter f = Enclosing_Instance.filter;
+				System.Collections.BitArray matches = f.Bits(ir);
+				if (matches.Get(i))
+					return inner;
+				Explanation result = new Explanation(0.0f, "failure to match filter: " + f.ToString());
+				result.AddDetail(inner);
+				return result;
 			}
 			
 			// return this query
@@ -174,8 +182,8 @@
 				return Enclosing_Instance;
 			}
 			
-            // return a filtering scorer
-            public virtual Scorer Scorer(IndexReader indexReader)
+			// return a filtering scorer
+			public virtual Scorer Scorer(IndexReader indexReader)
 			{
 				Scorer scorer = weight.Scorer(indexReader);
 				System.Collections.BitArray bitset = Enclosing_Instance.filter.Bits(indexReader);
@@ -261,7 +269,7 @@
 			if (o is FilteredQuery)
 			{
 				FilteredQuery fq = (FilteredQuery) o;
-				return (query.Equals(fq.query) && filter.Equals(fq.filter));
+				return (query.Equals(fq.query) && filter.Equals(fq.filter) && GetBoost() == fq.GetBoost());
 			}
 			return false;
 		}
@@ -269,16 +277,16 @@
 		/// <summary>Returns a hash code value for this object. </summary>
 		public override int GetHashCode()
 		{
-			return query.GetHashCode() ^ filter.GetHashCode();
+			return query.GetHashCode() ^ filter.GetHashCode() + System.Convert.ToInt32(GetBoost());
 		}
 
-        public override System.Object Clone()
-        {
+		override public System.Object Clone()
+		{
             // {{Aroush-2.0}} is this Clone() OK?
             FilteredQuery clone = (FilteredQuery) base.Clone();
             clone.filter = this.filter;
             clone.query = this.query;
             return clone;
         }
-    }
+	}
 }

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FilteredTermEnum.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/FilteredTermEnum.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FilteredTermEnum.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FilteredTermEnum.cs Tue May  1 11:45:26 2007
@@ -16,6 +16,7 @@
  */
 
 using System;
+
 using Term = Lucene.Net.Index.Term;
 using TermEnum = Lucene.Net.Index.TermEnum;
 
@@ -26,7 +27,7 @@
 	/// <p>Term enumerations are always ordered by Term.compareTo().  Each term in
 	/// the enumeration is greater than all that precede it.  
 	/// </summary>
-	public abstract class FilteredTermEnum:TermEnum
+	public abstract class FilteredTermEnum : TermEnum
 	{
 		private Term currentTerm = null;
 		private TermEnum actualEnum = null;

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FuzzyQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/FuzzyQuery.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FuzzyQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FuzzyQuery.cs Tue May  1 11:45:26 2007
@@ -16,6 +16,7 @@
  */
 
 using System;
+
 using IndexReader = Lucene.Net.Index.IndexReader;
 using Term = Lucene.Net.Index.Term;
 using PriorityQueue = Lucene.Net.Util.PriorityQueue;
@@ -28,7 +29,7 @@
 	/// is based on the Levenshtein (edit distance) algorithm.
 	/// </summary>
 	[Serializable]
-	public sealed class FuzzyQuery : MultiTermQuery
+	public class FuzzyQuery : MultiTermQuery
 	{
 		
 		public const float defaultMinSimilarity = 0.5f;
@@ -83,7 +84,7 @@
 		/// <summary> Returns the minimum similarity that is required for this query to match.</summary>
 		/// <returns> float value between 0.0 and 1.0
 		/// </returns>
-		public float GetMinSimilarity()
+		public virtual float GetMinSimilarity()
 		{
 			return minimumSimilarity;
 		}
@@ -92,7 +93,7 @@
 		/// of a term that must be identical (not fuzzy) to the query term if the query
 		/// is to match that term. 
 		/// </summary>
-		public int GetPrefixLength()
+		public virtual int GetPrefixLength()
 		{
 			return prefixLength;
 		}
@@ -163,7 +164,7 @@
 			return buffer.ToString();
 		}
 		
-		private class ScoreTerm
+		protected internal class ScoreTerm
 		{
 			public Term term;
 			public float score;
@@ -175,7 +176,7 @@
 			}
 		}
 		
-		private class ScoreTermQueue : PriorityQueue
+		protected internal class ScoreTermQueue:PriorityQueue
 		{
 			
 			public ScoreTermQueue(int size)
@@ -184,7 +185,7 @@
 			}
 			
 			/* (non-Javadoc)
-			* @see Lucene.Net.util.PriorityQueue#lessThan(java.lang.Object, java.lang.Object)
+			* @see Lucene.Net.Util.PriorityQueue#lessThan(java.lang.Object, java.lang.Object)
 			*/
 			public override bool LessThan(System.Object a, System.Object b)
 			{
@@ -219,7 +220,7 @@
 		public override int GetHashCode()
 		{
 			int result = base.GetHashCode();
-            result = 29 * result + minimumSimilarity != + 0.0f ? BitConverter.ToInt32(BitConverter.GetBytes(minimumSimilarity), 0) : 0;
+			result = 29 * result + minimumSimilarity != + 0.0f ? BitConverter.ToInt32(BitConverter.GetBytes(minimumSimilarity), 0) : 0;
 			result = 29 * result + prefixLength;
 			return result;
 		}

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FuzzyTermEnum.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/FuzzyTermEnum.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FuzzyTermEnum.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FuzzyTermEnum.cs Tue May  1 11:45:26 2007
@@ -16,6 +16,7 @@
  */
 
 using System;
+
 using IndexReader = Lucene.Net.Index.IndexReader;
 using Term = Lucene.Net.Index.Term;
 
@@ -60,12 +61,12 @@
 		/// valid term if such a term exists. 
 		/// 
 		/// </summary>
-		/// <param name="reader">
+		/// <param name="">reader
 		/// </param>
-		/// <param name="term">
+		/// <param name="">term
 		/// </param>
 		/// <throws>  IOException </throws>
-		/// <seealso cref="FuzzyTermEnum(IndexReader, Term, float, int)">
+		/// <seealso cref="Term, float, int)">
 		/// </seealso>
 		public FuzzyTermEnum(IndexReader reader, Term term) : this(reader, term, FuzzyQuery.defaultMinSimilarity, FuzzyQuery.defaultPrefixLength)
 		{
@@ -77,14 +78,14 @@
 		/// valid term if such a term exists. 
 		/// 
 		/// </summary>
-		/// <param name="reader">
+		/// <param name="">reader
 		/// </param>
-		/// <param name="term">
+		/// <param name="">term
 		/// </param>
-		/// <param name="minSimilarity">
+		/// <param name="">minSimilarity
 		/// </param>
 		/// <throws>  IOException </throws>
-		/// <seealso cref="FuzzyTermEnum(IndexReader, Term, float, int)">
+		/// <seealso cref="Term, float, int)">
 		/// </seealso>
 		public FuzzyTermEnum(IndexReader reader, Term term, float minSimilarity) : this(reader, term, minSimilarity, FuzzyQuery.defaultPrefixLength)
 		{
@@ -325,7 +326,7 @@
 		/// </returns>
 		private int GetMaxDistance(int m)
 		{
-			return (m < maxDistances.Length)?maxDistances[m]:CalculateMaxDistance(m);
+			return (m < maxDistances.Length) ? maxDistances[m] : CalculateMaxDistance(m);
 		}
 		
 		private void  InitializeMaxDistances()

Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Hit.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Hit.cs?view=diff&rev=534192&r1=534191&r2=534192
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Hit.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Hit.cs Tue May  1 11:45:26 2007
@@ -16,6 +16,7 @@
  */
 
 using System;
+
 using Document = Lucene.Net.Documents.Document;
 
 namespace Lucene.Net.Search
@@ -52,7 +53,7 @@
 		/// <summary> Returns document for this hit.
 		/// 
 		/// </summary>
-		/// <seealso cref="Hits.Doc(int)">
+		/// <seealso cref="Hits#Doc(int)">
 		/// </seealso>
 		public virtual Document GetDocument()
 		{
@@ -64,7 +65,7 @@
 		/// <summary> Returns score for this hit.
 		/// 
 		/// </summary>
-		/// <seealso cref="Hits.Score(int)">
+		/// <seealso cref="Hits#Score(int)">
 		/// </seealso>
 		public virtual float GetScore()
 		{
@@ -74,7 +75,7 @@
 		/// <summary> Returns id for this hit.
 		/// 
 		/// </summary>
-		/// <seealso cref="Hits.Id(int)">
+		/// <seealso cref="Hits#Id(int)">
 		/// </seealso>
 		public virtual int GetId()
 		{
@@ -92,7 +93,7 @@
 		/// <summary> Returns the boost factor for this hit on any field of the underlying document.
 		/// 
 		/// </summary>
-		/// <seealso cref="Document.GetBoost()">
+		/// <seealso cref="Document#GetBoost()">
 		/// </seealso>
 		public virtual float GetBoost()
 		{
@@ -105,7 +106,7 @@
 		/// exist, returns null.
 		/// 
 		/// </summary>
-		/// <seealso cref="Document.Get(String)">
+		/// <seealso cref="Document#Get(String)">
 		/// </seealso>
 		public virtual System.String Get(System.String name)
 		{