lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ccurr...@apache.org
Subject [Lucene.Net] svn commit: r1294875 [26/45] - in /incubator/lucene.net/trunk: ./ build/ build/vs2010/contrib/ build/vs2010/test/ doc/ src/ src/contrib/Analyzers/ src/contrib/Analyzers/AR/ src/contrib/Analyzers/BR/ src/contrib/Analyzers/CJK/ src/contrib/Analyzers/Cn/ ...
Date Tue, 28 Feb 2012 22:43:28 GMT
Modified: incubator/lucene.net/trunk/src/core/Search/MultiPhraseQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Search/MultiPhraseQuery.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Search/MultiPhraseQuery.cs (original)
+++ incubator/lucene.net/trunk/src/core/Search/MultiPhraseQuery.cs Tue Feb 28 22:43:08 2012
@@ -16,7 +16,7 @@
  */
 
 using System;
-
+using Lucene.Net.Support;
 using IndexReader = Lucene.Net.Index.IndexReader;
 using MultipleTermPositions = Lucene.Net.Index.MultipleTermPositions;
 using Term = Lucene.Net.Index.Term;
@@ -40,8 +40,8 @@ namespace Lucene.Net.Search
 	public class MultiPhraseQuery:Query
 	{
 		private System.String field;
-		private System.Collections.ArrayList termArrays = new System.Collections.ArrayList();
-		private System.Collections.ArrayList positions = new System.Collections.ArrayList();
+        private System.Collections.Generic.List<Term[]> termArrays = new System.Collections.Generic.List<Term[]>();
+        private System.Collections.Generic.List<int> positions = new System.Collections.Generic.List<int>();
 		
 		private int slop = 0;
 		
@@ -79,7 +79,7 @@ namespace Lucene.Net.Search
 		{
 			int position = 0;
 			if (positions.Count > 0)
-				position = ((System.Int32) positions[positions.Count - 1]) + 1;
+				position = positions[positions.Count - 1] + 1;
 			
 			Add(terms, position);
 		}
@@ -107,36 +107,32 @@ namespace Lucene.Net.Search
 			}
 			
 			termArrays.Add(terms);
-			positions.Add((System.Int32) position);
+			positions.Add(position);
 		}
 
         /// <summary> Returns a List&lt;Term[]&gt; of the terms in the multiphrase.
 		/// Do not modify the List or its contents.
 		/// </summary>
-		public virtual System.Collections.IList GetTermArrays()
-		{
-			return (System.Collections.IList) System.Collections.ArrayList.ReadOnly(new System.Collections.ArrayList(termArrays));
-		}
+		public virtual System.Collections.Generic.IList<Term[]> GetTermArrays()
+        {
+            return termArrays.AsReadOnly();
+        }
 		
 		/// <summary> Returns the relative positions of terms in this phrase.</summary>
 		public virtual int[] GetPositions()
 		{
 			int[] result = new int[positions.Count];
 			for (int i = 0; i < positions.Count; i++)
-				result[i] = ((System.Int32) positions[i]);
+				result[i] = positions[i];
 			return result;
 		}
 		
 		// inherit javadoc
-		public override void  ExtractTerms(System.Collections.Hashtable terms)
+		public override void ExtractTerms(System.Collections.Generic.ISet<Term> terms)
 		{
-			for (System.Collections.IEnumerator iter = termArrays.GetEnumerator(); iter.MoveNext(); )
+			foreach(Term[] arr in termArrays)
 			{
-				Term[] arr = (Term[]) iter.Current;
-				for (int i = 0; i < arr.Length; i++)
-				{
-					SupportClass.CollectionsHelper.AddIfNotContains(terms, arr[i]);
-				}
+			    terms.UnionWith(arr);
 			}
 		}
 		
@@ -169,15 +165,14 @@ namespace Lucene.Net.Search
 				this.similarity = Enclosing_Instance.GetSimilarity(searcher);
 				
 				// compute idf
-				System.Collections.IEnumerator i = Enclosing_Instance.termArrays.GetEnumerator();
-				while (i.MoveNext())
-				{
-					Term[] terms = (Term[]) i.Current;
-					for (int j = 0; j < terms.Length; j++)
-					{
-						idf += Enclosing_Instance.GetSimilarity(searcher).Idf(terms[j], searcher);
-					}
-				}
+			    int maxDoc = searcher.MaxDoc();
+                foreach (Term[] terms in enclosingInstance.termArrays)
+                {
+                    foreach (Term term in terms)
+                    {
+                        idf += similarity.Idf(searcher.DocFreq(term), maxDoc);
+                    }
+                }
 			}
 			
 			public override Query GetQuery()
@@ -211,7 +206,7 @@ namespace Lucene.Net.Search
 				TermPositions[] tps = new TermPositions[Enclosing_Instance.termArrays.Count];
 				for (int i = 0; i < tps.Length; i++)
 				{
-					Term[] terms = (Term[]) Enclosing_Instance.termArrays[i];
+					Term[] terms = Enclosing_Instance.termArrays[i];
 					
 					TermPositions p;
 					if (terms.Length > 1)
@@ -234,13 +229,13 @@ namespace Lucene.Net.Search
 			public override Explanation Explain(IndexReader reader, int doc)
 			{
 				ComplexExplanation result = new ComplexExplanation();
-				result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");
+				result.Description = "weight(" + GetQuery() + " in " + doc + "), product of:";
 				
 				Explanation idfExpl = new Explanation(idf, "idf(" + GetQuery() + ")");
 				
 				// explain query weight
 				Explanation queryExpl = new Explanation();
-				queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");
+				queryExpl.Description = "queryWeight(" + GetQuery() + "), product of:";
 				
 				Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");
 				if (Enclosing_Instance.GetBoost() != 1.0f)
@@ -251,41 +246,45 @@ namespace Lucene.Net.Search
 				Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");
 				queryExpl.AddDetail(queryNormExpl);
 				
-				queryExpl.SetValue(boostExpl.GetValue() * idfExpl.GetValue() * queryNormExpl.GetValue());
+				queryExpl.Value = boostExpl.Value * idfExpl.Value * queryNormExpl.Value;
 				
 				result.AddDetail(queryExpl);
 				
 				// explain field weight
 				ComplexExplanation fieldExpl = new ComplexExplanation();
-				fieldExpl.SetDescription("fieldWeight(" + GetQuery() + " in " + doc + "), product of:");
-				
-				Scorer scorer = Scorer(reader, true, false);
+				fieldExpl.Description = "fieldWeight(" + GetQuery() + " in " + doc + "), product of:";
+
+                PhraseScorer scorer = (PhraseScorer)Scorer(reader, true, false);
 				if (scorer == null)
 				{
 					return new Explanation(0.0f, "no matching docs");
 				}
-				Explanation tfExpl = scorer.Explain(doc);
-				fieldExpl.AddDetail(tfExpl);
+				Explanation tfExplanation = new Explanation();
+			    int d = scorer.Advance(doc);
+			    float phraseFreq = (d == doc) ? scorer.CurrentFreq() : 0.0f;
+                tfExplanation.Value = similarity.Tf(phraseFreq);
+                tfExplanation.Description = "tf(phraseFreq=" + phraseFreq + ")";
+                fieldExpl.AddDetail(tfExplanation);
 				fieldExpl.AddDetail(idfExpl);
 				
 				Explanation fieldNormExpl = new Explanation();
 				byte[] fieldNorms = reader.Norms(Enclosing_Instance.field);
 				float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]):1.0f;
-				fieldNormExpl.SetValue(fieldNorm);
-				fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")");
+				fieldNormExpl.Value = fieldNorm;
+				fieldNormExpl.Description = "fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")";
 				fieldExpl.AddDetail(fieldNormExpl);
 				
-				fieldExpl.SetMatch(tfExpl.IsMatch());
-				fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());
+				fieldExpl.Match = tfExplanation.IsMatch();
+                fieldExpl.Value = tfExplanation.Value * idfExpl.Value * fieldNormExpl.Value;
 				
 				result.AddDetail(fieldExpl);
-				System.Boolean? tempAux = fieldExpl.GetMatch();
-				result.SetMatch(tempAux);
+				System.Boolean? tempAux = fieldExpl.Match;
+				result.Match = tempAux;
 				
 				// combine them
-				result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue());
+				result.Value = queryExpl.Value * fieldExpl.Value;
 				
-				if (queryExpl.GetValue() == 1.0f)
+				if (queryExpl.Value == 1.0f)
 					return fieldExpl;
 				
 				return result;
@@ -297,7 +296,7 @@ namespace Lucene.Net.Search
 			if (termArrays.Count == 1)
 			{
 				// optimize one-term case
-				Term[] terms = (Term[]) termArrays[0];
+				Term[] terms = termArrays[0];
 				BooleanQuery boq = new BooleanQuery(true);
 				for (int i = 0; i < terms.Length; i++)
 				{
@@ -328,7 +327,7 @@ namespace Lucene.Net.Search
 			}
 			
 			buffer.Append("\"");
-			System.Collections.IEnumerator i = termArrays.GetEnumerator();
+			System.Collections.Generic.IEnumerator<Term[]> i = termArrays.GetEnumerator();
             bool first = true;
 			while (i.MoveNext())
 			{
@@ -341,7 +340,7 @@ namespace Lucene.Net.Search
                     buffer.Append(" ");
                 }
 
-				Term[] terms = (Term[]) i.Current;
+				Term[] terms = i.Current;
 				if (terms.Length > 1)
 				{
 					buffer.Append("(");
@@ -391,7 +390,7 @@ namespace Lucene.Net.Search
 
             for (int i = 0; i < this.termArrays.Count; i++)
             {
-                if (!SupportClass.Compare.CompareTermArrays((Term[])this.termArrays[i], (Term[])other.termArrays[i]))
+                if (!Compare.CompareTermArrays((Term[])this.termArrays[i], (Term[])other.termArrays[i]))
                 {
                     return false;
                 }
@@ -430,11 +429,10 @@ namespace Lucene.Net.Search
 		private int TermArraysHashCode()
 		{
 			int hashCode = 1;
-			System.Collections.IEnumerator iterator = termArrays.GetEnumerator();
-			while (iterator.MoveNext())
+			foreach(Term[] termArray in termArrays)
 			{
-				Term[] termArray = (Term[]) iterator.Current;
-				hashCode = 31 * hashCode + (termArray == null?0:ArraysHashCode(termArray));
+                // Java uses Arrays.hashCode(termArray)
+			    hashCode = 31*hashCode + (termArray == null ? 0 : ArraysHashCode(termArray));
 			}
 			return hashCode;
 		}
@@ -456,18 +454,18 @@ namespace Lucene.Net.Search
 		}
 		
 		// Breakout calculation of the termArrays equals
-		private bool TermArraysEquals(System.Collections.IList termArrays1, System.Collections.IList termArrays2)
+        private bool TermArraysEquals(System.Collections.Generic.List<Term[]> termArrays1, System.Collections.Generic.List<Term[]> termArrays2)
 		{
 			if (termArrays1.Count != termArrays2.Count)
 			{
 				return false;
 			}
-			System.Collections.IEnumerator iterator1 = termArrays1.GetEnumerator();
-			System.Collections.IEnumerator iterator2 = termArrays2.GetEnumerator();
+			var iterator1 = termArrays1.GetEnumerator();
+			var iterator2 = termArrays2.GetEnumerator();
 			while (iterator1.MoveNext())
 			{
-				Term[] termArray1 = (Term[]) iterator1.Current;
-				Term[] termArray2 = (Term[]) iterator2.Current;
+				Term[] termArray1 = iterator1.Current;
+				Term[] termArray2 = iterator2.Current;
 				if (!(termArray1 == null ? termArray2 == null : TermEquals(termArray1, termArray2)))
 				{
 					return false;

Modified: incubator/lucene.net/trunk/src/core/Search/MultiSearcher.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Search/MultiSearcher.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Search/MultiSearcher.cs (original)
+++ incubator/lucene.net/trunk/src/core/Search/MultiSearcher.cs Tue Feb 28 22:43:08 2012
@@ -16,7 +16,9 @@
  */
 
 using System;
-
+using System.Collections.Generic;
+using System.Linq;
+using Lucene.Net.Util;
 using Document = Lucene.Net.Documents.Document;
 using FieldSelector = Lucene.Net.Documents.FieldSelector;
 using CorruptIndexException = Lucene.Net.Index.CorruptIndexException;
@@ -29,8 +31,8 @@ namespace Lucene.Net.Search
 	
 	/// <summary>Implements search over a set of <c>Searchables</c>.
 	/// 
-	/// <p/>Applications usually need only call the inherited <see cref="Searcher.Search(Query)" />
-	/// or <see cref="Searcher.Search(Query,Filter)" /> methods.
+	/// <p/>Applications usually need only call the inherited <see cref="Searcher.Search(Query, int)" />
+	/// or <see cref="Searcher.Search(Query,Filter, int)" /> methods.
 	/// </summary>
 	public class MultiSearcher:Searcher
 	{
@@ -81,10 +83,10 @@ namespace Lucene.Net.Search
 		/// </summary>
 		private class CachedDfSource:Searcher
 		{
-			private System.Collections.IDictionary dfMap; // Map from Terms to corresponding doc freqs
-			private int maxDoc; // document count
+			private readonly Dictionary<Term,int> dfMap; // Map from Terms to corresponding doc freqs
+			private readonly int maxDoc; // document count
 			
-			public CachedDfSource(System.Collections.IDictionary dfMap, int maxDoc, Similarity similarity)
+			public CachedDfSource(Dictionary<Term,int> dfMap, int maxDoc, Similarity similarity)
 			{
 				this.dfMap = dfMap;
 				this.maxDoc = maxDoc;
@@ -96,9 +98,9 @@ namespace Lucene.Net.Search
 				int df;
 				try
 				{
-					df = ((System.Int32) dfMap[term]);
+					df = dfMap[term];
 				}
-				catch (System.NullReferenceException e)
+				catch (KeyNotFoundException e) // C# equiv. of java code.
 				{
 					throw new System.ArgumentException("df for term " + term.Text() + " not available");
 				}
@@ -128,18 +130,11 @@ namespace Lucene.Net.Search
 				// Therefore we just return the unmodified query here
 				return query;
 			}
-			
-			public override void  Close()
-			{
-				throw new System.NotSupportedException();
-			}
 
-            /// <summary>
-            /// .NET
-            /// </summary>
-            public override void Dispose()
+            // TODO: This probably shouldn't throw an exception?
+            protected override void Dispose(bool disposing)
             {
-                Close();
+                throw new System.NotSupportedException();
             }
 			
 			public override Document Doc(int i)
@@ -176,9 +171,11 @@ namespace Lucene.Net.Search
 		private Searchable[] searchables;
 		private int[] starts;
 		private int maxDoc = 0;
+
+	    private bool isDisposed;
 		
 		/// <summary>Creates a searcher which searches <i>searchers</i>. </summary>
-		public MultiSearcher(Searchable[] searchables)
+		public MultiSearcher(params Searchable[] searchables)
 		{
 			this.searchables = searchables;
 			
@@ -201,20 +198,18 @@ namespace Lucene.Net.Search
 		{
 			return starts;
 		}
-		
-		// inherit javadoc
-		public override void  Close()
-		{
-			for (int i = 0; i < searchables.Length; i++)
-				searchables[i].Close();
-		}
 
-        /// <summary>
-        /// .NET
-        /// </summary>
-        public override void Dispose()
+        protected override void Dispose(bool disposing)
         {
-            Close();
+            if (isDisposed) return;
+
+            if (disposing)
+            {
+                for (int i = 0; i < searchables.Length; i++)
+                    searchables[i].Close();
+            }
+
+            isDisposed = true;
         }
 
 		public override int DocFreq(Term term)
@@ -263,30 +258,21 @@ namespace Lucene.Net.Search
 		
 		public override TopDocs Search(Weight weight, Filter filter, int nDocs)
 		{
-			
 			HitQueue hq = new HitQueue(nDocs, false);
 			int totalHits = 0;
 			
 			for (int i = 0; i < searchables.Length; i++)
 			{
 				// search each searcher
-				TopDocs docs = searchables[i].Search(weight, filter, nDocs);
+                // use new object() for lock, we don't care about synchronization for these
+                TopDocs docs = MultiSearcherCallableNoSort(new object(), searchables[i], weight, filter, nDocs, hq, i, starts);
 				totalHits += docs.TotalHits; // update totalHits
-				ScoreDoc[] scoreDocs = docs.ScoreDocs;
-				for (int j = 0; j < scoreDocs.Length; j++)
-				{
-					// merge scoreDocs into hq
-					ScoreDoc scoreDoc = scoreDocs[j];
-					scoreDoc.doc += starts[i]; // convert doc
-					if (!hq.Insert(scoreDoc))
-						break; // no more scores > minScore
-				}
 			}
 			
 			ScoreDoc[] scoreDocs2 = new ScoreDoc[hq.Size()];
 			for (int i = hq.Size() - 1; i >= 0; i--)
 			// put docs in array
-				scoreDocs2[i] = (ScoreDoc) hq.Pop();
+				scoreDocs2[i] = hq.Pop();
 			
 			float maxScore = (totalHits == 0)?System.Single.NegativeInfinity:scoreDocs2[0].score;
 			
@@ -295,7 +281,7 @@ namespace Lucene.Net.Search
 		
 		public override TopFieldDocs Search(Weight weight, Filter filter, int n, Sort sort)
 		{
-			FieldDocSortedHitQueue hq = null;
+			var hq = new FieldDocSortedHitQueue(n);
 			int totalHits = 0;
 			
 			float maxScore = System.Single.NegativeInfinity;
@@ -303,47 +289,22 @@ namespace Lucene.Net.Search
 			for (int i = 0; i < searchables.Length; i++)
 			{
 				// search each searcher
-				TopFieldDocs docs = searchables[i].Search(weight, filter, n, sort);
-				// If one of the Sort fields is FIELD_DOC, need to fix its values, so that
-				// it will break ties by doc Id properly. Otherwise, it will compare to
-				// 'relative' doc Ids, that belong to two different searchers.
-				for (int j = 0; j < docs.fields.Length; j++)
-				{
-					if (docs.fields[j].GetType() == SortField.DOC)
-					{
-						// iterate over the score docs and change their fields value
-						for (int j2 = 0; j2 < docs.ScoreDocs.Length; j2++)
-						{
-							FieldDoc fd = (FieldDoc) docs.ScoreDocs[j2];
-							fd.fields[j] = (System.Int32) (((System.Int32) fd.fields[j]) + starts[i]);
-						}
-						break;
-					}
-				}
-				if (hq == null)
-					hq = new FieldDocSortedHitQueue(docs.fields, n);
-				totalHits += docs.TotalHits; // update totalHits
+                // use new object() for lock, we don't care about synchronization for these
+			    TopFieldDocs docs = MultiSearcherCallableWithSort(new object(), searchables[i], weight, filter, n, hq, sort,
+			                                          i, starts);
+			    totalHits += docs.TotalHits;
 				maxScore = System.Math.Max(maxScore, docs.GetMaxScore());
-				ScoreDoc[] scoreDocs = docs.ScoreDocs;
-				for (int j = 0; j < scoreDocs.Length; j++)
-				{
-					// merge scoreDocs into hq
-					ScoreDoc scoreDoc = scoreDocs[j];
-					scoreDoc.doc += starts[i]; // convert doc
-					if (!hq.Insert(scoreDoc))
-						break; // no more scores > minScore
-				}
 			}
 			
 			ScoreDoc[] scoreDocs2 = new ScoreDoc[hq.Size()];
 			for (int i = hq.Size() - 1; i >= 0; i--)
 			// put docs in array
-				scoreDocs2[i] = (ScoreDoc) hq.Pop();
+				scoreDocs2[i] = hq.Pop();
 			
 			return new TopFieldDocs(totalHits, scoreDocs2, hq.GetFields(), maxScore);
 		}
 		
-		// inherit javadoc
+		///<inheritdoc />
 		public override void  Search(Weight weight, Filter filter, Collector collector)
 		{
 			for (int i = 0; i < searchables.Length; i++)
@@ -394,15 +355,11 @@ namespace Lucene.Net.Search
 			Query rewrittenQuery = Rewrite(original);
 			
 			// step 2
-			System.Collections.Hashtable terms = new System.Collections.Hashtable();
+			ISet<Term> terms = new HashSet<Term>();
 			rewrittenQuery.ExtractTerms(terms);
 			
 			// step3
-			Term[] allTermsArray = new Term[terms.Count];
-            int index = 0;
-            System.Collections.IEnumerator e = terms.Keys.GetEnumerator();
-            while (e.MoveNext())
-                allTermsArray[index++] = e.Current as Term;
+		    Term[] allTermsArray = terms.ToArray();
             int[] aggregatedDfs = new int[terms.Count];
 			for (int i = 0; i < searchables.Length; i++)
 			{
@@ -413,10 +370,10 @@ namespace Lucene.Net.Search
 				}
 			}
 			
-			System.Collections.Hashtable dfMap = new System.Collections.Hashtable();
+			var dfMap = new Dictionary<Term, int>();
 			for (int i = 0; i < allTermsArray.Length; i++)
 			{
-				dfMap[allTermsArray[i]] = (System.Int32) aggregatedDfs[i];
+				dfMap[allTermsArray[i]] = aggregatedDfs[i];
 			}
 			
 			// step4
@@ -425,5 +382,66 @@ namespace Lucene.Net.Search
 			
 			return rewrittenQuery.Weight(cacheSim);
 		}
+
+	    internal Func<object, Searchable, Weight, Filter, int, HitQueue, int, int[], TopDocs> MultiSearcherCallableNoSort =
+	        (theLock, searchable, weight, filter, nDocs, hq, i, starts) =>
+	            {
+	                TopDocs docs = searchable.Search(weight, filter, nDocs);
+	                ScoreDoc[] scoreDocs = docs.ScoreDocs;
+                    for(int j = 0; j < scoreDocs.Length; j++) // merge scoreDocs into hq
+                    {
+                        ScoreDoc scoreDoc = scoreDocs[j];
+                        scoreDoc.doc += starts[i]; //convert doc
+                        //it would be so nice if we had a thread-safe insert
+                        lock (theLock)
+                        {
+                            if (scoreDoc == hq.InsertWithOverflow(scoreDoc))
+                                break;
+                        }
+                    }
+	                return docs;
+	            };
+
+        internal Func<object, Searchable, Weight, Filter, int, FieldDocSortedHitQueue, Sort, int, int[], TopFieldDocs>
+	        MultiSearcherCallableWithSort = (theLock, searchable, weight, filter, nDocs, hq, sort, i, starts) =>
+	                                            {
+	                                                TopFieldDocs docs = searchable.Search(weight, filter, nDocs, sort);
+                                                    // if one of the Sort fields is FIELD_DOC, need to fix its values, so that
+                                                    // it will break ties by doc Id properly.  Otherwise, it will compare to
+                                                    // 'relative' doc Ids, that belong to two different searchables.
+                                                    for (int j = 0; j < docs.fields.Length; j++)
+                                                    {
+                                                        if (docs.fields[j].GetType() == SortField.DOC)
+                                                        {
+                                                            // iterate over the score docs and change their fields value
+                                                            for (int j2 = 0; j2 < docs.ScoreDocs.Length; j2++)
+                                                            {
+                                                                FieldDoc fd = (FieldDoc) docs.ScoreDocs[j2];
+                                                                fd.fields[j] = (int)fd.fields[j] + starts[i];
+                                                            }
+                                                            break;
+                                                        }
+                                                    }
+
+                                                    lock (theLock)
+                                                    {
+                                                        hq.SetFields(docs.fields);
+                                                    }
+
+	                                                ScoreDoc[] scoreDocs = docs.ScoreDocs;
+                                                    for (int j = 0; j < scoreDocs.Length; j++) // merge scoreDocs into hq
+                                                    {
+                                                        FieldDoc fieldDoc = (FieldDoc) scoreDocs[j];
+                                                        fieldDoc.doc += starts[i]; //convert doc
+                                                        //it would be so nice if we had a thread-safe insert
+                                                        lock (theLock)
+                                                        {
+                                                            if (fieldDoc == hq.InsertWithOverflow(fieldDoc))
+                                                                break;
+
+                                                        }
+                                                    }
+	                                                return docs;
+	                                            };
 	}
 }
\ No newline at end of file

Modified: incubator/lucene.net/trunk/src/core/Search/MultiTermQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Search/MultiTermQuery.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Search/MultiTermQuery.cs (original)
+++ incubator/lucene.net/trunk/src/core/Search/MultiTermQuery.cs Tue Feb 28 22:43:08 2012
@@ -16,7 +16,7 @@
  */
 
 using System;
-
+using System.Collections.Generic;
 using System.Runtime.InteropServices;
 using IndexReader = Lucene.Net.Index.IndexReader;
 using Term = Lucene.Net.Index.Term;
@@ -76,8 +76,6 @@ namespace Lucene.Net.Search
 				return Lucene.Net.Search.MultiTermQuery.CONSTANT_SCORE_AUTO_REWRITE_DEFAULT;
 			}
 		}
-		// @deprecated move to sub class
-		protected internal Term term;
 		protected internal RewriteMethod rewriteMethod = CONSTANT_SCORE_AUTO_REWRITE_DEFAULT;
 		[NonSerialized]
 		internal int numberOfTerms = 0;
@@ -94,7 +92,7 @@ namespace Lucene.Net.Search
 		{
 			public override Query Rewrite(IndexReader reader, MultiTermQuery query)
 			{
-				Query result = new ConstantScoreQuery(new MultiTermQueryWrapperFilter(query));
+				Query result = new ConstantScoreQuery(new MultiTermQueryWrapperFilter<MultiTermQuery>(query));
 				result.SetBoost(query.GetBoost());
 				return result;
 			}
@@ -285,7 +283,7 @@ namespace Lucene.Net.Search
 				// exhaust the enum before hitting either of the
 				// cutoffs, we use ConstantBooleanQueryRewrite; else,
 				// ConstantFilterRewrite:
-				System.Collections.ArrayList pendingTerms = new System.Collections.ArrayList();
+				ICollection<Term> pendingTerms = new List<Term>();
 				int docCountCutoff = (int) ((docCountPercent / 100.0) * reader.MaxDoc());
 				int termCountLimit = System.Math.Min(BooleanQuery.GetMaxClauseCount(), termCountCutoff);
 				int docVisitCount = 0;
@@ -309,7 +307,7 @@ namespace Lucene.Net.Search
 						if (pendingTerms.Count >= termCountLimit || docVisitCount >= docCountCutoff)
 						{
 							// Too many terms -- make a filter.
-							Query result = new ConstantScoreQuery(new MultiTermQueryWrapperFilter(query));
+							Query result = new ConstantScoreQuery(new MultiTermQueryWrapperFilter<MultiTermQuery>(query));
 							result.SetBoost(query.GetBoost());
 							return result;
 						}
@@ -318,11 +316,10 @@ namespace Lucene.Net.Search
 							// Enumeration is done, and we hit a small
 							// enough number of terms & docs -- just make a
 							// BooleanQuery, now
-							System.Collections.IEnumerator it = pendingTerms.GetEnumerator();
 							BooleanQuery bq = new BooleanQuery(true);
-							while (it.MoveNext())
+							foreach(Term term in pendingTerms)
 							{
-								TermQuery tq = new TermQuery((Term) it.Current);
+								TermQuery tq = new TermQuery(term);
 								bq.Add(tq, BooleanClause.Occur.SHOULD);
 							}
 							// Strip scores
@@ -384,33 +381,13 @@ namespace Lucene.Net.Search
 		/// </summary>
 		public static readonly RewriteMethod CONSTANT_SCORE_AUTO_REWRITE_DEFAULT;
 		
-		/// <summary> Constructs a query for terms matching <c>term</c>.</summary>
-		/// <deprecated> check sub class for possible term access - the Term does not
-		/// make sense for all MultiTermQuerys and will be removed.
-		/// </deprecated>
-        [Obsolete("check sub class for possible term access - the Term does not make sense for all MultiTermQuerys and will be removed.")]
-		public MultiTermQuery(Term term)
-		{
-			this.term = term;
-		}
-		
 		/// <summary> Constructs a query matching terms that cannot be represented with a single
 		/// Term.
 		/// </summary>
-		public MultiTermQuery()
+		protected MultiTermQuery()
 		{
 		}
 		
-		/// <summary> Returns the pattern term.</summary>
-		/// <deprecated> check sub class for possible term access - getTerm does not
-		/// make sense for all MultiTermQuerys and will be removed.
-		/// </deprecated>
-        [Obsolete("check sub class for possible term access - getTerm does not make sense for all MultiTermQuerys and will be removed.")]
-		public virtual Term GetTerm()
-		{
-			return term;
-		}
-		
 		/// <summary>Construct the enumeration to be used, expanding the pattern term. </summary>
 		public /*protected internal*/ abstract FilteredTermEnum GetEnum(IndexReader reader);
 		
@@ -454,31 +431,6 @@ namespace Lucene.Net.Search
 			return rewriteMethod.Rewrite(reader, this);
 		}
 		
-		
-		/* Prints a user-readable version of this query.
-		* Implemented for back compat in case MultiTermQuery
-		* subclasses do no implement.
-		*/
-		public override System.String ToString(System.String field)
-		{
-			System.Text.StringBuilder buffer = new System.Text.StringBuilder();
-			if (term != null)
-			{
-				if (!term.Field().Equals(field))
-				{
-					buffer.Append(term.Field());
-					buffer.Append(":");
-				}
-				buffer.Append(term.Text());
-			}
-			else
-			{
-				buffer.Append("termPattern:unknown");
-			}
-			buffer.Append(ToStringUtils.Boost(GetBoost()));
-			return buffer.ToString();
-		}
-		
 		/// <seealso cref="SetRewriteMethod">
 		/// </seealso>
 		public virtual RewriteMethod GetRewriteMethod()

Modified: incubator/lucene.net/trunk/src/core/Search/MultiTermQueryWrapperFilter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Search/MultiTermQueryWrapperFilter.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Search/MultiTermQueryWrapperFilter.cs (original)
+++ incubator/lucene.net/trunk/src/core/Search/MultiTermQueryWrapperFilter.cs Tue Feb 28 22:43:08 2012
@@ -40,66 +40,13 @@ namespace Lucene.Net.Search
 	/// this is why it is not abstract.
 	/// </summary>
 	[Serializable]
-	public class MultiTermQueryWrapperFilter:Filter
+    public class MultiTermQueryWrapperFilter<T> : Filter
+        where T : MultiTermQuery
 	{
-		private class AnonymousClassTermGenerator:TermGenerator
-		{
-			public AnonymousClassTermGenerator(System.Collections.BitArray bitSet, MultiTermQueryWrapperFilter enclosingInstance)
-			{
-				InitBlock(bitSet, enclosingInstance);
-			}
-			private void  InitBlock(System.Collections.BitArray bitSet, MultiTermQueryWrapperFilter enclosingInstance)
-			{
-				this.bitSet = bitSet;
-				this.enclosingInstance = enclosingInstance;
-			}
-			private System.Collections.BitArray bitSet;
-			private MultiTermQueryWrapperFilter enclosingInstance;
-			public MultiTermQueryWrapperFilter Enclosing_Instance
-			{
-				get
-				{
-					return enclosingInstance;
-				}
-				
-			}
-			public override void  HandleDoc(int doc)
-			{
-				bitSet.Set(doc, true);
-			}
-		}
-
-		private class AnonymousClassTermGenerator1:TermGenerator
-		{
-			public AnonymousClassTermGenerator1(Lucene.Net.Util.OpenBitSet bitSet, MultiTermQueryWrapperFilter enclosingInstance)
-			{
-				InitBlock(bitSet, enclosingInstance);
-			}
-			private void  InitBlock(Lucene.Net.Util.OpenBitSet bitSet, MultiTermQueryWrapperFilter enclosingInstance)
-			{
-				this.bitSet = bitSet;
-				this.enclosingInstance = enclosingInstance;
-			}
-			private Lucene.Net.Util.OpenBitSet bitSet;
-			private MultiTermQueryWrapperFilter enclosingInstance;
-			public MultiTermQueryWrapperFilter Enclosing_Instance
-			{
-				get
-				{
-					return enclosingInstance;
-				}
-				
-			}
-			public override void  HandleDoc(int doc)
-			{
-				bitSet.Set(doc);
-			}
-		}
-		
-		protected internal MultiTermQuery query;
+        protected internal T query;
 		
 		/// <summary> Wrap a <see cref="MultiTermQuery" /> as a Filter.</summary>
-		protected internal MultiTermQueryWrapperFilter(MultiTermQuery query)
+        protected internal MultiTermQueryWrapperFilter(T query)
 		{
 			this.query = query;
 		}
@@ -120,7 +67,7 @@ namespace Lucene.Net.Search
 				return false;
 			if (this.GetType().Equals(o.GetType()))
 			{
-				return this.query.Equals(((MultiTermQueryWrapperFilter) o).query);
+				return this.query.Equals(((MultiTermQueryWrapperFilter<T>) o).query);
 			}
 			return false;
 		}
@@ -155,90 +102,54 @@ namespace Lucene.Net.Search
 		{
 			query.ClearTotalNumberOfTerms();
 		}
-		
-		internal abstract class TermGenerator
-		{
-            public virtual void Generate(MultiTermQuery query, IndexReader reader, TermEnum enumerator)
-			{
-				int[] docs = new int[32];
-				int[] freqs = new int[32];
-				TermDocs termDocs = reader.TermDocs();
-				try
-				{
-					int termCount = 0;
-					do 
-					{
-						Term term = enumerator.Term();
-						if (term == null)
-							break;
-						termCount++;
-						termDocs.Seek(term);
-						while (true)
-						{
-							int count = termDocs.Read(docs, freqs);
-							if (count != 0)
-							{
-								for (int i = 0; i < count; i++)
-								{
-									HandleDoc(docs[i]);
-								}
-							}
-							else
-							{
-								break;
-							}
-						}
-					}
-					while (enumerator.Next());
-					
-					query.IncTotalNumberOfTerms(termCount); // {{Aroush-2.9}} is the use of 'temp' as is right?
-				}
-				finally
-				{
-					termDocs.Close();
-				}
-			}
-			abstract public void  HandleDoc(int doc);
-		}
-		
-		/// <summary> Returns a BitSet with true for documents which should be
-		/// permitted in search results, and false for those that should
-		/// not.
-		/// </summary>
-		/// <deprecated> Use <see cref="GetDocIdSet(IndexReader)" /> instead.
-		/// </deprecated>
-		//@Override
-        [Obsolete("Use GetDocIdSet(IndexReader) instead.")]
-		public override System.Collections.BitArray Bits(IndexReader reader)
-		{
-			TermEnum enumerator = query.GetEnum(reader);
-			try
-			{
-				System.Collections.BitArray bitSet = new System.Collections.BitArray((reader.MaxDoc() % 64 == 0?reader.MaxDoc() / 64:reader.MaxDoc() / 64 + 1) * 64);
-				new AnonymousClassTermGenerator(bitSet, this).Generate(query, reader, enumerator);
-				return bitSet;
-			}
-			finally
-			{
-				enumerator.Close();
-			}
-		}
-		
-		/// <summary> Returns a DocIdSet with documents that should be
-		/// permitted in search results.
-		/// </summary>
-		//@Override
-		public override DocIdSet GetDocIdSet(IndexReader reader)
-		{
-			TermEnum enumerator = query.GetEnum(reader);
-			try
-			{
-				// if current term in enum is null, the enum is empty -> shortcut
-				if (enumerator.Term() == null)
-					return DocIdSet.EMPTY_DOCIDSET;
-				// else fill into a OpenBitSet
-				OpenBitSet bitSet = new OpenBitSet(reader.MaxDoc());
-				new AnonymousClassTermGenerator1(bitSet, this).Generate(query, reader, enumerator);
+
+        public override DocIdSet GetDocIdSet(IndexReader reader)
+        {
+            TermEnum enumerator = query.GetEnum(reader);
+            try
+            {
+                // if current term in enum is null, the enum is empty -> shortcut
+                if (enumerator.Term() == null)
+                    return DocIdSet.EMPTY_DOCIDSET;
+                // else fill into an OpenBitSet
+                OpenBitSet bitSet = new OpenBitSet(reader.MaxDoc());
+                int[] docs = new int[32];
+                int[] freqs = new int[32];
+                TermDocs termDocs = reader.TermDocs();
+                try
+                {
+                    int termCount = 0;
+                    do
+                    {
+                        Term term = enumerator.Term();
+                        if (term == null)
+                            break;
+                        termCount++;
+                        termDocs.Seek(term);
+                        while (true)
+                        {
+                            int count = termDocs.Read(docs, freqs);
+                            if (count != 0)
+                            {
+                                for (int i = 0; i < count; i++)
+                                {
+                                    bitSet.Set(docs[i]);
+                                }
+                            }
+                            else
+                            {
+                                break;
+                            }
+                        }
+                    } while (enumerator.Next());
+
+                    query.IncTotalNumberOfTerms(termCount); // {{Aroush-2.9}} is the use of 'temp' as is right?
+                }
+                finally
+                {
+                    termDocs.Close();
+                }
+
 				return bitSet;
 			}
 			finally

Modified: incubator/lucene.net/trunk/src/core/Search/NumericRangeFilter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Search/NumericRangeFilter.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Search/NumericRangeFilter.cs (original)
+++ incubator/lucene.net/trunk/src/core/Search/NumericRangeFilter.cs Tue Feb 28 22:43:08 2012
@@ -23,158 +23,163 @@ using NumericUtils = Lucene.Net.Util.Num
 
 namespace Lucene.Net.Search
 {
-	
-	/// <summary> A <see cref="Filter" /> that only accepts numeric values within
-	/// a specified range. To use this, you must first index the
-	/// numeric values using <see cref="NumericField" /> (expert: <see cref="NumericTokenStream" />
-	///).
-	/// 
-	/// <p/>You create a new NumericRangeFilter with the static
-	/// factory methods, eg:
-	/// 
+
+    /// <summary> A <see cref="Filter" /> that only accepts numeric values within
+    /// a specified range. To use this, you must first index the
+    /// numeric values using <see cref="NumericField" /> (expert: <see cref="NumericTokenStream" />
+    ///).
+    /// 
+    /// <p/>You create a new NumericRangeFilter with the static
+    /// factory methods, eg:
+    /// 
     /// <code>
-	/// Filter f = NumericRangeFilter.newFloatRange("weight",
-	///             new Float(0.3f), new Float(0.10f),
-	///             true, true);
+    /// Filter f = NumericRangeFilter.newFloatRange("weight",
+    ///             new Float(0.3f), new Float(0.10f),
+    ///             true, true);
     /// </code>
-	/// 
-	/// accepts all documents whose float valued "weight" field
-	/// ranges from 0.3 to 0.10, inclusive.
-	/// See <see cref="NumericRangeQuery" /> for details on how Lucene
-	/// indexes and searches numeric valued fields.
-	/// 
-	/// <p/><font color="red"><b>NOTE:</b> This API is experimental and
-	/// might change in incompatible ways in the next
-	/// release.</font>
-	/// 
-	/// </summary>
-	/// <since> 2.9
-	/// 
-	/// </since>
-	[Serializable]
-	public sealed class NumericRangeFilter:MultiTermQueryWrapperFilter
-	{
-		
-		private NumericRangeFilter(NumericRangeQuery query):base(query)
-		{
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeFilter</c>, that filters a <c>long</c>
-		/// range using the given <a href="NumericRangeQuery.html#precisionStepDesc"><c>precisionStep</c></a>.
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeFilter NewLongRange(System.String field, int precisionStep, System.ValueType min, System.ValueType max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeFilter(NumericRangeQuery.NewLongRange(field, precisionStep, min, max, minInclusive, maxInclusive));
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeFilter</c>, that queries a <c>long</c>
-		/// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeFilter NewLongRange(System.String field, System.ValueType min, System.ValueType max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeFilter(NumericRangeQuery.NewLongRange(field, min, max, minInclusive, maxInclusive));
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeFilter</c>, that filters a <c>int</c>
-		/// range using the given <a href="NumericRangeQuery.html#precisionStepDesc"><c>precisionStep</c></a>.
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeFilter NewIntRange(System.String field, int precisionStep, System.ValueType min, System.ValueType max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeFilter(NumericRangeQuery.NewIntRange(field, precisionStep, min, max, minInclusive, maxInclusive));
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeFilter</c>, that queries a <c>int</c>
-		/// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeFilter NewIntRange(System.String field, System.ValueType min, System.ValueType max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeFilter(NumericRangeQuery.NewIntRange(field, min, max, minInclusive, maxInclusive));
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeFilter</c>, that filters a <c>double</c>
-		/// range using the given <a href="NumericRangeQuery.html#precisionStepDesc"><c>precisionStep</c></a>.
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeFilter NewDoubleRange(System.String field, int precisionStep, System.Double min, System.Double max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeFilter(NumericRangeQuery.NewDoubleRange(field, precisionStep, min, max, minInclusive, maxInclusive));
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeFilter</c>, that queries a <c>double</c>
-		/// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeFilter NewDoubleRange(System.String field, System.Double min, System.Double max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeFilter(NumericRangeQuery.NewDoubleRange(field, min, max, minInclusive, maxInclusive));
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeFilter</c>, that filters a <c>float</c>
-		/// range using the given <a href="NumericRangeQuery.html#precisionStepDesc"><c>precisionStep</c></a>.
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeFilter NewFloatRange(System.String field, int precisionStep, System.Single min, System.Single max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeFilter(NumericRangeQuery.NewFloatRange(field, precisionStep, min, max, minInclusive, maxInclusive));
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeFilter</c>, that queries a <c>float</c>
-		/// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeFilter NewFloatRange(System.String field, System.Single min, System.Single max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeFilter(NumericRangeQuery.NewFloatRange(field, min, max, minInclusive, maxInclusive));
-		}
-		
-		/// <summary>Returns the field name for this filter </summary>
+    /// 
+    /// accepts all documents whose float valued "weight" field
+    /// ranges from 0.3 to 0.10, inclusive.
+    /// See <see cref="NumericRangeQuery{T}" /> for details on how Lucene
+    /// indexes and searches numeric valued fields.
+    /// 
+    /// <p/><font color="red"><b>NOTE:</b> This API is experimental and
+    /// might change in incompatible ways in the next
+    /// release.</font>
+    /// 
+    /// </summary>
+    /// <since> 2.9
+    /// 
+    /// </since>
+    [Serializable]
+    public sealed class NumericRangeFilter<T> : MultiTermQueryWrapperFilter<NumericRangeQuery<T>>
+        where T : struct, IComparable<T>
+        // real numbers in C# are structs and IComparable with themselves, best constraint we have
+    {
+        internal NumericRangeFilter(NumericRangeQuery<T> query)
+            : base(query)
+        {
+        }
+
+        /// <summary>Returns the field name for this filter </summary>
 		public System.String GetField()
 		{
-			return ((NumericRangeQuery) query).GetField();
+			return query.GetField();
 		}
 		
 		/// <summary>Returns <c>true</c> if the lower endpoint is inclusive </summary>
 		public bool IncludesMin()
 		{
-			return ((NumericRangeQuery) query).IncludesMin();
+			return query.IncludesMin();
 		}
 		
 		/// <summary>Returns <c>true</c> if the upper endpoint is inclusive </summary>
 		public bool IncludesMax()
 		{
-			return ((NumericRangeQuery) query).IncludesMax();
+			return query.IncludesMax();
 		}
 		
 		/// <summary>Returns the lower value of this range filter </summary>
-		public System.ValueType GetMin()
+		public T? GetMin()
 		{
-			return ((NumericRangeQuery) query).GetMin();
+			return query.GetMin();
 		}
 		
 		/// <summary>Returns the upper value of this range filter </summary>
-		public System.ValueType GetMax()
+		public T? GetMax()
 		{
-			return ((NumericRangeQuery) query).GetMax();
+			return query.GetMax();
 		}
 	}
+
+    public static class NumericRangeFilter
+    {
+        /// <summary> Factory that creates a <c>NumericRangeFilter</c>, that filters a <c>long</c>
+        /// range using the given <a href="NumericRangeQuery.html#precisionStepDesc"><c>precisionStep</c></a>.
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeFilter<long> NewLongRange(System.String field, int precisionStep, long? min, long? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeFilter<long>(NumericRangeQuery.NewLongRange(field, precisionStep, min, max, minInclusive, maxInclusive));
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeFilter</c>, that queries a <c>long</c>
+        /// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeFilter<long> NewLongRange(System.String field, long? min, long? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeFilter<long>(NumericRangeQuery.NewLongRange(field, min, max, minInclusive, maxInclusive));
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeFilter</c>, that filters a <c>int</c>
+        /// range using the given <a href="NumericRangeQuery.html#precisionStepDesc"><c>precisionStep</c></a>.
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeFilter<int> NewIntRange(System.String field, int precisionStep, int? min, int? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeFilter<int>(NumericRangeQuery.NewIntRange(field, precisionStep, min, max, minInclusive, maxInclusive));
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeFilter</c>, that queries a <c>int</c>
+        /// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeFilter<int> NewIntRange(System.String field, int? min, int? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeFilter<int>(NumericRangeQuery.NewIntRange(field, min, max, minInclusive, maxInclusive));
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeFilter</c>, that filters a <c>double</c>
+        /// range using the given <a href="NumericRangeQuery.html#precisionStepDesc"><c>precisionStep</c></a>.
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeFilter<double> NewDoubleRange(System.String field, int precisionStep, double? min, double? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeFilter<double>(NumericRangeQuery.NewDoubleRange(field, precisionStep, min, max, minInclusive, maxInclusive));
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeFilter</c>, that queries a <c>double</c>
+        /// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeFilter<double> NewDoubleRange(System.String field, double? min, double? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeFilter<double>(NumericRangeQuery.NewDoubleRange(field, min, max, minInclusive, maxInclusive));
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeFilter</c>, that filters a <c>float</c>
+        /// range using the given <a href="NumericRangeQuery.html#precisionStepDesc"><c>precisionStep</c></a>.
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeFilter<float> NewFloatRange(System.String field, int precisionStep, float? min, float? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeFilter<float>(NumericRangeQuery.NewFloatRange(field, precisionStep, min, max, minInclusive, maxInclusive));
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeFilter</c>, that queries a <c>float</c>
+        /// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeFilter<float> NewFloatRange(System.String field, float? min, float? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeFilter<float>(NumericRangeQuery.NewFloatRange(field, min, max, minInclusive, maxInclusive));
+        }
+    }
 }
\ No newline at end of file

Modified: incubator/lucene.net/trunk/src/core/Search/NumericRangeQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/src/core/Search/NumericRangeQuery.cs?rev=1294875&r1=1294874&r2=1294875&view=diff
==============================================================================
--- incubator/lucene.net/trunk/src/core/Search/NumericRangeQuery.cs (original)
+++ incubator/lucene.net/trunk/src/core/Search/NumericRangeQuery.cs Tue Feb 28 22:43:08 2012
@@ -16,7 +16,8 @@
  */
 
 using System;
-
+using System.Collections.Generic;
+using Lucene.Net.Index;
 using NumericTokenStream = Lucene.Net.Analysis.NumericTokenStream;
 using NumericField = Lucene.Net.Documents.NumericField;
 using IndexReader = Lucene.Net.Index.IndexReader;
@@ -32,7 +33,7 @@ namespace Lucene.Net.Search
 	/// specified range.  To use this, you must first index the
 	/// numeric values using <see cref="NumericField" /> (expert: <see cref="NumericTokenStream" />
 	///).  If your terms are instead textual,
-	/// you should use <see cref="TermRangeQuery" />.  <see cref="NumericRangeFilter" />
+	/// you should use <see cref="TermRangeQuery" />.  <see cref="NumericRangeFilter{T}" />
 	/// is the filter equivalent of this
 	/// query.<p/>
 	/// 
@@ -152,10 +153,11 @@ namespace Lucene.Net.Search
 	/// 
 	/// </since>
 	[Serializable]
-	public sealed class NumericRangeQuery:MultiTermQuery
+	public sealed class NumericRangeQuery<T> : MultiTermQuery
+        where T : struct, IComparable<T> // best equiv constraint for java's number class
 	{
 		
-		private NumericRangeQuery(System.String field, int precisionStep, int valSize, System.ValueType min, System.ValueType max, bool minInclusive, bool maxInclusive)
+		internal NumericRangeQuery(System.String field, int precisionStep, int valSize, T? min, T? max, bool minInclusive, bool maxInclusive)
 		{
 			System.Diagnostics.Debug.Assert((valSize == 32 || valSize == 64));
 			if (precisionStep < 1)
@@ -196,94 +198,6 @@ namespace Lucene.Net.Search
 			}
 		}
 		
-		/// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>long</c>
-		/// range using the given <a href="#precisionStepDesc"><c>precisionStep</c></a>.
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeQuery NewLongRange(System.String field, int precisionStep, System.ValueType min, System.ValueType max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeQuery(field, precisionStep, 64, min, max, minInclusive, maxInclusive);
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>long</c>
-		/// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeQuery NewLongRange(System.String field, System.ValueType min, System.ValueType max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeQuery(field, NumericUtils.PRECISION_STEP_DEFAULT, 64, min, max, minInclusive, maxInclusive);
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>int</c>
-		/// range using the given <a href="#precisionStepDesc"><c>precisionStep</c></a>.
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeQuery NewIntRange(System.String field, int precisionStep, System.ValueType min, System.ValueType max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeQuery(field, precisionStep, 32, min, max, minInclusive, maxInclusive);
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>int</c>
-		/// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeQuery NewIntRange(System.String field, System.ValueType min, System.ValueType max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeQuery(field, NumericUtils.PRECISION_STEP_DEFAULT, 32, min, max, minInclusive, maxInclusive);
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>double</c>
-		/// range using the given <a href="#precisionStepDesc"><c>precisionStep</c></a>.
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeQuery NewDoubleRange(System.String field, int precisionStep, System.Double min, System.Double max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeQuery(field, precisionStep, 64, min, max, minInclusive, maxInclusive);
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>double</c>
-		/// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeQuery NewDoubleRange(System.String field, System.Double min, System.Double max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeQuery(field, NumericUtils.PRECISION_STEP_DEFAULT, 64, min, max, minInclusive, maxInclusive);
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>float</c>
-		/// range using the given <a href="#precisionStepDesc"><c>precisionStep</c></a>.
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeQuery NewFloatRange(System.String field, int precisionStep, System.Single min, System.Single max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeQuery(field, precisionStep, 32, min, max, minInclusive, maxInclusive);
-		}
-		
-		/// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>float</c>
-		/// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
-        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
-		/// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
-		/// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
-		/// </summary>
-		public static NumericRangeQuery NewFloatRange(System.String field, System.Single min, System.Single max, bool minInclusive, bool maxInclusive)
-		{
-			return new NumericRangeQuery(field, NumericUtils.PRECISION_STEP_DEFAULT, 32, min, max, minInclusive, maxInclusive);
-		}
-		
 		//@Override
 		public /*protected internal*/ override FilteredTermEnum GetEnum(IndexReader reader)
 		{
@@ -309,13 +223,13 @@ namespace Lucene.Net.Search
 		}
 		
 		/// <summary>Returns the lower value of this range query </summary>
-		public System.ValueType GetMin()
+		public T? GetMin()
 		{
 			return min;
 		}
 		
 		/// <summary>Returns the upper value of this range query </summary>
-		public System.ValueType GetMax()
+		public T? GetMax()
 		{
 			return max;
 		}
@@ -326,8 +240,8 @@ namespace Lucene.Net.Search
 			System.Text.StringBuilder sb = new System.Text.StringBuilder();
 			if (!this.field.Equals(field))
 				sb.Append(this.field).Append(':');
-			return sb.Append(minInclusive?'[':'{').Append((min == null)?"*":min.ToString()).Append(" TO ").Append((max == null)?"*":max.ToString()).Append(maxInclusive?']':'}').Append(ToStringUtils.Boost(GetBoost())).ToString();
-		}
+            return sb.Append(minInclusive ? '[' : '{').Append((min == null) ? "*" : min.ToString()).Append(" TO ").Append((max == null) ? "*" : max.ToString()).Append(maxInclusive ? ']' : '}').Append(ToStringUtils.Boost(GetBoost())).ToString();
+        }
 		
 		//@Override
 		public  override bool Equals(System.Object o)
@@ -336,11 +250,11 @@ namespace Lucene.Net.Search
 				return true;
 			if (!base.Equals(o))
 				return false;
-			if (o is NumericRangeQuery)
+			if (o is NumericRangeQuery<T>)
 			{
-				NumericRangeQuery q = (NumericRangeQuery) o;
-				return ((System.Object) field == (System.Object) q.field && (q.min == null?min == null:q.min.Equals(min)) && (q.max == null?max == null:q.max.Equals(max)) && minInclusive == q.minInclusive && maxInclusive == q.maxInclusive && precisionStep == q.precisionStep);
-			}
+                NumericRangeQuery<T> q = (NumericRangeQuery<T>)o;
+                return ((System.Object)field == (System.Object)q.field && (q.min == null ? min == null : q.min.Equals(min)) && (q.max == null ? max == null : q.max.Equals(max)) && minInclusive == q.minInclusive && maxInclusive == q.maxInclusive && precisionStep == q.precisionStep);
+            }
 			return false;
 		}
 		
@@ -348,11 +262,11 @@ namespace Lucene.Net.Search
 		public override int GetHashCode()
 		{
 			int hash = base.GetHashCode();
-			hash += (field.GetHashCode() ^ 0x4565fd66 + precisionStep ^ 0x64365465);
-			if (min != null)
-				hash += (min.GetHashCode() ^ 0x14fa55fb);
-			if (max != null)
-				hash += (max.GetHashCode() ^ 0x733fa5fe);
+            hash += (field.GetHashCode() ^ 0x4565fd66 + precisionStep ^ 0x64365465);
+            if (min != null)
+                hash += (min.GetHashCode() ^ 0x14fa55fb);
+            if (max != null)
+                hash += (max.GetHashCode() ^ 0x733fa5fe);
 			return hash + (minInclusive.GetHashCode() ^ 0x14fa55fb) + (maxInclusive.GetHashCode() ^ 0x733fa5fe);
 		}
 
@@ -374,8 +288,8 @@ namespace Lucene.Net.Search
 		internal System.String field;
 		internal int precisionStep;
 		internal int valSize;
-		internal System.ValueType min;
-		internal System.ValueType max;
+		internal T? min;
+		internal T? max;
 		internal bool minInclusive;
 		internal bool maxInclusive;
 		
@@ -412,8 +326,8 @@ namespace Lucene.Net.Search
 				//@Override
 				public override void  AddRange(System.String minPrefixCoded, System.String maxPrefixCoded)
 				{
-					Enclosing_Instance.rangeBounds.Add(minPrefixCoded);
-					Enclosing_Instance.rangeBounds.Add(maxPrefixCoded);
+					Enclosing_Instance.rangeBounds.AddLast(minPrefixCoded);
+                    Enclosing_Instance.rangeBounds.AddLast(maxPrefixCoded);
 				}
 			}
 			private class AnonymousClassIntRangeBuilder:NumericUtils.IntRangeBuilder
@@ -438,16 +352,17 @@ namespace Lucene.Net.Search
 				//@Override
 				public override void  AddRange(System.String minPrefixCoded, System.String maxPrefixCoded)
 				{
-					Enclosing_Instance.rangeBounds.Add(minPrefixCoded);
-					Enclosing_Instance.rangeBounds.Add(maxPrefixCoded);
+                    Enclosing_Instance.rangeBounds.AddLast(minPrefixCoded);
+                    Enclosing_Instance.rangeBounds.AddLast(maxPrefixCoded);
 				}
 			}
-			private void  InitBlock(NumericRangeQuery enclosingInstance)
+			private void  InitBlock(NumericRangeQuery<T> enclosingInstance)
 			{
 				this.enclosingInstance = enclosingInstance;
+                termTemplate = new Term(Enclosing_Instance.field);
 			}
-			private NumericRangeQuery enclosingInstance;
-			public NumericRangeQuery Enclosing_Instance
+            private NumericRangeQuery<T> enclosingInstance;
+            public NumericRangeQuery<T> Enclosing_Instance
 			{
 				get
 				{
@@ -457,29 +372,36 @@ namespace Lucene.Net.Search
 			}
 			
 			private IndexReader reader;
-			private System.Collections.ArrayList rangeBounds = new System.Collections.ArrayList();
+            private LinkedList<string> rangeBounds = new LinkedList<string>();
+		    private Term termTemplate;
 			private System.String currentUpperBound = null;
-			
-			internal NumericRangeTermEnum(NumericRangeQuery enclosingInstance, IndexReader reader)
+
+		    private bool isDisposed;
+
+            internal NumericRangeTermEnum(NumericRangeQuery<T> enclosingInstance, IndexReader reader)
 			{
 				InitBlock(enclosingInstance);
 				this.reader = reader;
 				
+				Type rangeType = Nullable.GetUnderlyingType(typeof(T?));
 				switch (Enclosing_Instance.valSize)
 				{
-					
 					case 64:  {
 							// lower
 							long minBound = System.Int64.MinValue;
-							if (Enclosing_Instance.min is System.Int64)
-							{
-								minBound = System.Convert.ToInt64(Enclosing_Instance.min);
-							}
-							else if (Enclosing_Instance.min is System.Double)
-							{
-								minBound = NumericUtils.DoubleToSortableLong(System.Convert.ToDouble(Enclosing_Instance.min));
+                            if (rangeType == typeof(System.Int64))
+                            {
+                                // added in these checks to emulate java.  passing null give it no type (in old code), 
+                                // but .net can identifies it with generics and sets the bounds to 0, causing tests to fail
+                                if (Enclosing_Instance.min != null) 
+								    minBound = System.Convert.ToInt64(Enclosing_Instance.min);
+							}
+                            else if (rangeType == typeof(System.Double))
+                            {
+                                if (Enclosing_Instance.min != null)
+								    minBound = NumericUtils.DoubleToSortableLong(System.Convert.ToDouble(Enclosing_Instance.min));
 							}
-							if (!Enclosing_Instance.minInclusive && Enclosing_Instance.min != null)
+                            if (!Enclosing_Instance.minInclusive && Enclosing_Instance.min != null)
 							{
 								if (minBound == System.Int64.MaxValue)
 									break;
@@ -488,15 +410,17 @@ namespace Lucene.Net.Search
 							
 							// upper
 							long maxBound = System.Int64.MaxValue;
-							if (Enclosing_Instance.max is System.Int64)
-							{
-								maxBound = System.Convert.ToInt64(Enclosing_Instance.max);
-							}
-							else if (Enclosing_Instance.max is System.Double)
-							{
-								maxBound = NumericUtils.DoubleToSortableLong(System.Convert.ToDouble(Enclosing_Instance.max));
+                            if (rangeType == typeof(System.Int64))
+                            {
+                                if (Enclosing_Instance.max != null)
+								    maxBound = System.Convert.ToInt64(Enclosing_Instance.max);
+							}
+                            else if (rangeType == typeof(System.Double))
+                            {
+                                if (Enclosing_Instance.max != null)
+								    maxBound = NumericUtils.DoubleToSortableLong(System.Convert.ToDouble(Enclosing_Instance.max));
 							}
-							if (!Enclosing_Instance.maxInclusive && Enclosing_Instance.max != null)
+                            if (!Enclosing_Instance.maxInclusive && Enclosing_Instance.max != null)
 							{
 								if (maxBound == System.Int64.MinValue)
 									break;
@@ -511,15 +435,17 @@ namespace Lucene.Net.Search
 					case 32:  {
 							// lower
 							int minBound = System.Int32.MinValue;
-							if (Enclosing_Instance.min is System.Int32)
-							{
-								minBound = System.Convert.ToInt32(Enclosing_Instance.min);
-							}
-							else if (Enclosing_Instance.min is System.Single)
+                            if (rangeType == typeof(System.Int32))
 							{
-								minBound = NumericUtils.FloatToSortableInt(System.Convert.ToSingle(Enclosing_Instance.min));
+                                if (Enclosing_Instance.min != null)
+								    minBound = System.Convert.ToInt32(Enclosing_Instance.min);
+                            }
+                            else if (rangeType == typeof(System.Single))
+                            {
+                                if (Enclosing_Instance.min != null)
+								    minBound = NumericUtils.FloatToSortableInt(System.Convert.ToSingle(Enclosing_Instance.min));
 							}
-							if (!Enclosing_Instance.minInclusive && Enclosing_Instance.min != null)
+                            if (!Enclosing_Instance.minInclusive && Enclosing_Instance.min != null)
 							{
 								if (minBound == System.Int32.MaxValue)
 									break;
@@ -527,16 +453,18 @@ namespace Lucene.Net.Search
 							}
 							
 							// upper
-							int maxBound = System.Int32.MaxValue;
-							if (Enclosing_Instance.max is System.Int32)
-							{
-								maxBound = System.Convert.ToInt32(Enclosing_Instance.max);
+                            int maxBound = System.Int32.MaxValue;
+                            if (rangeType == typeof(System.Int32))
+                            {
+                                if (Enclosing_Instance.max != null)
+								    maxBound = System.Convert.ToInt32(Enclosing_Instance.max);
+							}
+                            else if (rangeType == typeof(System.Single))
+                            {
+                                if (Enclosing_Instance.max != null)
+								    maxBound = NumericUtils.FloatToSortableInt(System.Convert.ToSingle(Enclosing_Instance.max));
 							}
-							else if (Enclosing_Instance.max is System.Single)
-							{
-								maxBound = NumericUtils.FloatToSortableInt(System.Convert.ToSingle(Enclosing_Instance.max));
-							}
-							if (!Enclosing_Instance.maxInclusive && Enclosing_Instance.max != null)
+                            if (!Enclosing_Instance.maxInclusive && Enclosing_Instance.max != null)
 							{
 								if (maxBound == System.Int32.MinValue)
 									break;
@@ -568,9 +496,14 @@ namespace Lucene.Net.Search
 			//@Override
 			public override bool EndEnum()
 			{
-				System.Diagnostics.Debug.Assert(false); // should never be called
-				return (currentTerm != null);
+			    throw new NotSupportedException("not implemented");
 			}
+
+            /// <summary>this is a dummy, it is not used by this class. </summary>
+            protected internal override void SetEnum(TermEnum tenum)
+            {
+                throw new NotSupportedException("not implemented");
+            }
 			
 			/// <summary> Compares if current upper bound is reached,
 			/// this also updates the term count for statistics.
@@ -581,60 +514,156 @@ namespace Lucene.Net.Search
 			//@Override
 			public /*protected internal*/ override bool TermCompare(Term term)
 			{
-				return ((System.Object) term.Field() == (System.Object) Enclosing_Instance.field && String.CompareOrdinal(term.Text(), currentUpperBound) <= 0);
+				return (term.Field() == Enclosing_Instance.field && String.CompareOrdinal(term.Text(), currentUpperBound) <= 0);
 			}
 			
 			/// <summary>Increments the enumeration to the next element.  True if one exists. </summary>
 			//@Override
-			public override bool Next()
+            public override bool Next()
 			{
-				// if a current term exists, the actual enum is initialized:
-				// try change to next term, if no such term exists, fall-through
-				if (currentTerm != null)
-				{
-					System.Diagnostics.Debug.Assert(actualEnum != null);
-					if (actualEnum.Next())
-					{
-						currentTerm = actualEnum.Term();
-						if (TermCompare(currentTerm))
-							return true;
-					}
-				}
-				// if all above fails, we go forward to the next enum,
-				// if one is available
-				currentTerm = null;
-				if (rangeBounds.Count < 2)
-					return false;
-				// close the current enum and read next bounds
-				if (actualEnum != null)
-				{
-					actualEnum.Close();
-					actualEnum = null;
-				}
-				System.Object tempObject;
-				tempObject = rangeBounds[0];
-				rangeBounds.RemoveAt(0);
-				System.String lowerBound = (System.String) tempObject;
-				System.Object tempObject2;
-				tempObject2 = rangeBounds[0];
-				rangeBounds.RemoveAt(0);
-				this.currentUpperBound = ((System.String) tempObject2);
-				// this call recursively uses next(), if no valid term in
-				// next enum found.
-				// if this behavior is changed/modified in the superclass,
-				// this enum will not work anymore!
-				SetEnum(reader.Terms(new Term(Enclosing_Instance.field, lowerBound)));
-				return (currentTerm != null);
-			}
-			
-			/// <summary>Closes the enumeration to further activity, freeing resources.  </summary>
-			//@Override
-			public override void  Close()
-			{
-				rangeBounds.Clear();
-				currentUpperBound = null;
-				base.Close();
+			    // if a current term exists, the actual enum is initialized:
+			    // try change to next term, if no such term exists, fall-through
+			    if (currentTerm != null)
+			    {
+			        System.Diagnostics.Debug.Assert(actualEnum != null);
+			        if (actualEnum.Next())
+			        {
+			            currentTerm = actualEnum.Term();
+			            if (TermCompare(currentTerm))
+			                return true;
+			        }
+			    }
+			    // if all above fails, we go forward to the next enum,
+			    // if one is available
+			    currentTerm = null;
+			    while (rangeBounds.Count >= 2)
+			    {
+			        // close the current enum and read next bounds
+			        if (actualEnum != null)
+			        {
+			            actualEnum.Close();
+			            actualEnum = null;
+			        }
+			        string lowerBound = rangeBounds.First.Value;
+			        rangeBounds.RemoveFirst();
+			        this.currentUpperBound = rangeBounds.First.Value;
+			        rangeBounds.RemoveFirst();
+			        // create a new enum
+			        actualEnum = reader.Terms(termTemplate.CreateTerm(lowerBound));
+			        currentTerm = actualEnum.Term();
+			        if (currentTerm != null && TermCompare(currentTerm))
+			            return true;
+			        // clear the current term for next iteration
+			        currentTerm = null;
+			    }
+
+			    // no more sub-range enums available
+			    System.Diagnostics.Debug.Assert(rangeBounds.Count == 0 && currentTerm == null);
+			    return false;
 			}
+
+		    /// <summary>Closes the enumeration to further activity, freeing resources.  </summary>
+            protected override void Dispose(bool disposing)
+            {
+                if (isDisposed) return;
+
+                rangeBounds.Clear();
+                currentUpperBound = null;
+
+		        isDisposed = true;
+                base.Dispose(disposing);
+            }
 		}
 	}
+
+    public static class NumericRangeQuery
+    {
+        /// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>long</c>
+        /// range using the given <a href="#precisionStepDesc"><c>precisionStep</c></a>.
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeQuery<long> NewLongRange(System.String field, int precisionStep, long? min, long? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeQuery<long>(field, precisionStep, 64, min, max, minInclusive, maxInclusive);
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>long</c>
+        /// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeQuery<long> NewLongRange(System.String field, long? min, long? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeQuery<long>(field, NumericUtils.PRECISION_STEP_DEFAULT, 64, min, max, minInclusive, maxInclusive);
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>int</c>
+        /// range using the given <a href="#precisionStepDesc"><c>precisionStep</c></a>.
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeQuery<int> NewIntRange(System.String field, int precisionStep, int? min, int? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeQuery<int>(field, precisionStep, 32, min, max, minInclusive, maxInclusive);
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>int</c>
+        /// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeQuery<int> NewIntRange(System.String field, int? min, int? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeQuery<int>(field, NumericUtils.PRECISION_STEP_DEFAULT, 32, min, max, minInclusive, maxInclusive);
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>double</c>
+        /// range using the given <a href="#precisionStepDesc"><c>precisionStep</c></a>.
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeQuery<double> NewDoubleRange(System.String field, int precisionStep, double? min, double? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeQuery<double>(field, precisionStep, 64, min, max, minInclusive, maxInclusive);
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>double</c>
+        /// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeQuery<double> NewDoubleRange(System.String field, double? min, double? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeQuery<double>(field, NumericUtils.PRECISION_STEP_DEFAULT, 64, min, max, minInclusive, maxInclusive);
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>float</c>
+        /// range using the given <a href="#precisionStepDesc"><c>precisionStep</c></a>.
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeQuery<float> NewFloatRange(System.String field, int precisionStep, float? min, float? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeQuery<float>(field, precisionStep, 32, min, max, minInclusive, maxInclusive);
+        }
+
+        /// <summary> Factory that creates a <c>NumericRangeQuery</c>, that queries a <c>float</c>
+        /// range using the default <c>precisionStep</c> <see cref="NumericUtils.PRECISION_STEP_DEFAULT" /> (4).
+        /// You can have half-open ranges (which are in fact &lt;/&#8804; or &gt;/&#8805; queries)
+        /// by setting the min or max value to <c>null</c>. By setting inclusive to false, it will
+        /// match all documents excluding the bounds, with inclusive on, the boundaries are hits, too.
+        /// </summary>
+        public static NumericRangeQuery<float> NewFloatRange(System.String field, float? min, float? max, bool minInclusive, bool maxInclusive)
+        {
+            return new NumericRangeQuery<float>(field, NumericUtils.PRECISION_STEP_DEFAULT, 32, min, max, minInclusive, maxInclusive);
+        }
+    }
 }
\ No newline at end of file



Mime
View raw message