lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject svn commit: r912416 - in /lucene/lucene.net/trunk/C#/src: Lucene.Net/Lucene.Net.csproj Lucene.Net/Search/Function/CustomScoreProvider.cs Lucene.Net/Search/Function/CustomScoreQuery.cs Test/Search/Function/TestCustomScoreQuery.cs
Date Sun, 21 Feb 2010 22:07:02 GMT
Author: digy
Date: Sun Feb 21 22:07:02 2010
New Revision: 912416

URL: http://svn.apache.org/viewvc?rev=912416&view=rev
Log:
Changes for "LUCENE-2190: Added a new class CustomScoreProvider to function package that can
be subclassed to provide custom scoring to CustomScoreQuery"

Added:
    lucene/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/CustomScoreProvider.cs
Modified:
    lucene/lucene.net/trunk/C#/src/Lucene.Net/Lucene.Net.csproj
    lucene/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/CustomScoreQuery.cs
    lucene/lucene.net/trunk/C#/src/Test/Search/Function/TestCustomScoreQuery.cs

Modified: lucene/lucene.net/trunk/C#/src/Lucene.Net/Lucene.Net.csproj
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/src/Lucene.Net/Lucene.Net.csproj?rev=912416&r1=912415&r2=912416&view=diff
==============================================================================
--- lucene/lucene.net/trunk/C#/src/Lucene.Net/Lucene.Net.csproj (original)
+++ lucene/lucene.net/trunk/C#/src/Lucene.Net/Lucene.Net.csproj Sun Feb 21 22:07:02 2010
@@ -563,6 +563,7 @@
     </Compile>
     <Compile Include="Search\FilterManager.cs" />
     <Compile Include="Search\Function\ByteFieldSource.cs" />
+    <Compile Include="Search\Function\CustomScoreProvider.cs" />
     <Compile Include="Search\Function\CustomScoreQuery.cs" />
     <Compile Include="Search\Function\DocValues.cs" />
     <Compile Include="Search\Function\FieldCacheSource.cs" />

Added: lucene/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/CustomScoreProvider.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/src/Lucene.Net/Search/Function/CustomScoreProvider.cs?rev=912416&view=auto
==============================================================================
--- lucene/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/CustomScoreProvider.cs (added)
+++ lucene/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/CustomScoreProvider.cs Sun Feb
21 22:07:02 2010
@@ -0,0 +1,175 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Lucene.Net.Index;
+
+namespace Lucene.Net.Search.Function
+{
+    /**
+ * An instance of this subclass should be returned by
+ * {@link CustomScoreQuery#getCustomScoreProvider}, if you want
+ * to modify the custom score calculation of a {@link CustomScoreQuery}.
+ * <p>Since Lucene 2.9, queries operate on each segment of an Index separately,
+ * so overriding the similar (now deprecated) methods in {@link CustomScoreQuery}
+ * is no longer suitable, as the supplied <code>doc</code> ID is per-segment
+ * and without knowledge of the IndexReader you cannot access the
+ * document or {@link FieldCache}.
+ * 
+ * @lucene.experimental
+ * @since 2.9.2
+ */
+    public class CustomScoreProvider
+    {
+
+        protected IndexReader reader;
+
+        /// <summary>
+        /// Creates a new instance of the provider class for the given IndexReader.
+        /// </summary>
+        public CustomScoreProvider(IndexReader reader)
+        {
+            this.reader = reader;
+        }
+
+        /// <summary>
+        /// * Compute a custom score by the subQuery score and a number of 
+        /// ValueSourceQuery scores.
+        /// <p/> 
+        /// Subclasses can override this method to modify the custom score.  
+        /// <p/>
+        /// If your custom scoring is different than the default herein you 
+        /// should override at least one of the two customScore() methods.
+        /// If the number of ValueSourceQueries is always &lt; 2 it is 
+        /// sufficient to override the other 
+        /// {@link #customScore(int, float, float) customScore()} 
+        /// method, which is simpler. 
+        /// <p/>
+        /// The default computation herein is a multiplication of given scores:
+        /// <pre>
+        ///     ModifiedScore = valSrcScore * valSrcScores[0] * valSrcScores[1] * ...
+        /// </pre>
+        /// </summary>
+        /// <param name="doc">id of scored doc</param>
+        /// <param name="subQueryScore">score of that doc by the subQuery</param>
+        /// <param name="valSrcScores">scores of that doc by the ValueSourceQuery</param>
+        /// <returns>custom score</returns>
+        public virtual float CustomScore(int doc, float subQueryScore, float[] valSrcScores)
+        {
+            if (valSrcScores.Length == 1)
+            {
+                return CustomScore(doc, subQueryScore, valSrcScores[0]);
+            }
+            if (valSrcScores.Length == 0)
+            {
+                return CustomScore(doc, subQueryScore, 1);
+            }
+            float score = subQueryScore;
+            for (int i = 0; i < valSrcScores.Length; i++)
+            {
+                score *= valSrcScores[i];
+            }
+            return score;
+        }
+                
+        /// <summary>
+        /// Compute a custom score by the subQuery score and the ValueSourceQuery score.
+        /// <p/> 
+        /// Subclasses can override this method to modify the custom score.
+        /// <p/>
+        /// If your custom scoring is different than the default herein you 
+        /// should override at least one of the two customScore() methods.
+        /// If the number of ValueSourceQueries is always < 2 it is 
+        /// sufficient to override this customScore() method, which is simpler. 
+        /// <p/>
+        /// The default computation herein is a multiplication of the two scores:
+        /// <pre>
+        ///     ModifiedScore = subQueryScore /// valSrcScore
+        /// </pre>
+        /// </summary>
+        /// <param name="doc">id of scored doc</param>
+        /// <param name="subQueryScore">score of that doc by the subQuery</param>
+        /// <param name="valSrcScore">score of that doc by the ValueSourceQuery</param>
+        /// <returns>custom score</returns>
+        public virtual float CustomScore(int doc, float subQueryScore, float valSrcScore)
+        {
+            return subQueryScore * valSrcScore;
+        }
+
+        /// <summary>
+        /// Explain the custom score.
+        /// Whenever overriding {@link #customScore(int, float, float[])}, 
+        /// this method should also be overridden to provide the correct explanation
+        /// for the part of the custom scoring.
+        /// </summary>
+        /// <param name="doc">doc being explained</param>
+        /// <param name="subQueryExpl">explanation for the sub-query part</param>
+        /// <param name="valSrcExpls">explanation for the value source part</param>
+        /// <returns>an explanation for the custom score</returns>
+        public virtual Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation[]
valSrcExpls)
+        {
+            if (valSrcExpls.Length == 1)
+            {
+                return CustomExplain(doc, subQueryExpl, valSrcExpls[0]);
+            }
+            if (valSrcExpls.Length == 0)
+            {
+                return subQueryExpl;
+            }
+            float valSrcScore = 1;
+            for (int i = 0; i < valSrcExpls.Length; i++)
+            {
+                valSrcScore *= valSrcExpls[i].GetValue();
+            }
+            Explanation exp = new Explanation(valSrcScore * subQueryExpl.GetValue(), "custom
score: product of:");
+            exp.AddDetail(subQueryExpl);
+            for (int i = 0; i < valSrcExpls.Length; i++)
+            {
+                exp.AddDetail(valSrcExpls[i]);
+            }
+            return exp;
+        }
+                
+        /// <summary>
+        /// Explain the custom score.
+        /// Whenever overriding {@link #customScore(int, float, float)}, 
+        /// this method should also be overridden to provide the correct explanation
+        /// for the part of the custom scoring.
+        /// 
+        /// </summary>
+        /// <param name="doc">doc being explained</param>
+        /// <param name="subQueryExpl">explanation for the sub-query part</param>
+        /// <param name="valSrcExpl">explanation for the value source part</param>
+        /// <returns>an explanation for the custom score</returns>
+        public virtual Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation
valSrcExpl)
+        {
+            float valSrcScore = 1;
+            if (valSrcExpl != null)
+            {
+                valSrcScore *= valSrcExpl.GetValue();
+            }
+            Explanation exp = new Explanation(valSrcScore * subQueryExpl.GetValue(), "custom
score: product of:");
+            exp.AddDetail(subQueryExpl);
+            exp.AddDetail(valSrcExpl);
+            return exp;
+        }
+
+    }
+}

Modified: lucene/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/CustomScoreQuery.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/src/Lucene.Net/Search/Function/CustomScoreQuery.cs?rev=912416&r1=912415&r2=912416&view=diff
==============================================================================
--- lucene/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/CustomScoreQuery.cs (original)
+++ lucene/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/CustomScoreQuery.cs Sun Feb
21 22:07:02 2010
@@ -37,7 +37,7 @@
 	/// For most simple/convenient use cases this query is likely to be a 
 	/// {@link Lucene.Net.Search.Function.FieldScoreQuery FieldScoreQuery}</li>
 	/// </ol>
-	/// Subclasses can modify the computation by overriding {@link #CustomScore(int, float,
float)}.
+    /// Subclasses can modify the computation by overriding {@link #getCustomScoreProvider}.
 	/// 
 	/// <p/><font color="#FF0000">
 	/// WARNING: The status of the <b>Search.Function</b> package is experimental.

@@ -65,7 +65,7 @@
 		/// <param name="valSrcQuery">a value source query whose scores are used in the custom
score
 		/// computation. For most simple/convineient use case this would be a 
 		/// {@link Lucene.Net.Search.Function.FieldScoreQuery FieldScoreQuery}.
-		/// This parameter is optional - it can be null.
+        /// This parameter is optional - it can be null or even an empty array.
 		/// </param>
 		public CustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery):this(subQuery, valSrcQuery
!= null?new ValueSourceQuery[]{valSrcQuery}:new ValueSourceQuery[0])
 		{
@@ -79,7 +79,7 @@
 		/// {@link Lucene.Net.Search.Function.FieldScoreQuery FieldScoreQueries}.
 		/// This parameter is optional - it can be null or even an empty array.
 		/// </param>
-		public CustomScoreQuery(Query subQuery, ValueSourceQuery[] valSrcQueries):base()
+		public CustomScoreQuery(Query subQuery, ValueSourceQuery[] valSrcQueries)
 		{
 			this.subQuery = subQuery;
 			this.valSrcQueries = valSrcQueries != null?valSrcQueries:new ValueSourceQuery[0];
@@ -88,15 +88,29 @@
 		}
 		
 		/*(non-Javadoc) @see Lucene.Net.Search.Query#rewrite(Lucene.Net.Index.IndexReader) */
-		public override Query Rewrite(IndexReader reader)
-		{
-			subQuery = subQuery.Rewrite(reader);
-			for (int i = 0; i < valSrcQueries.Length; i++)
-			{
-				valSrcQueries[i] = (ValueSourceQuery) valSrcQueries[i].Rewrite(reader);
-			}
-			return this;
-		}
+        public override Query Rewrite(IndexReader reader)
+        {
+            CustomScoreQuery clone = null;
+
+            Query sq = subQuery.Rewrite(reader);
+            if (sq != subQuery)
+            {
+                clone = (CustomScoreQuery)Clone();
+                clone.subQuery = sq;
+            }
+
+            for (int i = 0; i < valSrcQueries.Length; i++)
+            {
+                ValueSourceQuery v = (ValueSourceQuery)valSrcQueries[i].Rewrite(reader);
+                if (v != valSrcQueries[i])
+                {
+                    if (clone == null) clone = (CustomScoreQuery)Clone();
+                    clone.valSrcQueries[i] = v;
+                }
+            }
+
+            return (clone == null) ? this : clone;
+        }
 		
 		/*(non-Javadoc) @see Lucene.Net.Search.Query#extractTerms(java.util.Set) */
 		public override void  ExtractTerms(System.Collections.Hashtable terms)
@@ -143,10 +157,13 @@
 				return false;
 			}
 			CustomScoreQuery other = (CustomScoreQuery) o;
-			if (this.GetBoost() != other.GetBoost() || !this.subQuery.Equals(other.subQuery) || this.valSrcQueries.Length
!= other.valSrcQueries.Length)
-			{
-				return false;
-			}
+            if (this.GetBoost() != other.GetBoost() ||
+                !this.subQuery.Equals(other.subQuery) ||
+                this.strict != other.strict ||
+                this.valSrcQueries.Length != other.valSrcQueries.Length)
+            {
+                return false;
+            }
 			for (int i = 0; i < valSrcQueries.Length; i++)
 			{
 				//TODO simplify with Arrays.deepEquals() once moving to Java 1.5
@@ -167,35 +184,64 @@
 				//TODO simplify with Arrays.deepHashcode() once moving to Java 1.5
 				valSrcHash += valSrcQueries[i].GetHashCode();
 			}
-			return (GetType().GetHashCode() + subQuery.GetHashCode() + valSrcHash) ^ BitConverter.ToInt32(BitConverter.GetBytes(GetBoost()),
0);
+            return (GetType().GetHashCode() + subQuery.GetHashCode() + valSrcHash) ^
+                BitConverter.ToInt32(BitConverter.GetBytes(GetBoost()), 0) ^ (strict ? 1234
: 4321);
+
 		}
+
+        /**
+       * Returns a {@link CustomScoreProvider} that calculates the custom scores
+       * for the given {@link IndexReader}. The default implementation returns a default
+       * implementation as specified in the docs of {@link CustomScoreProvider}.
+       * @since 2.9.2
+       */
+        protected virtual CustomScoreProvider GetCustomScoreProvider(IndexReader reader)
+        {
+            // when deprecated methods are removed, do not extend class here, just return
new default CustomScoreProvider
+            return new AnonymousCustomScoreProvider(this, reader);
+        }
+
+        class AnonymousCustomScoreProvider : CustomScoreProvider
+        {
+            CustomScoreQuery parent;
+            IndexReader reader;
+            public AnonymousCustomScoreProvider(CustomScoreQuery parent, IndexReader reader)
: base(reader)
+            {
+                this.parent = parent;
+                this.reader = reader;
+            }
+            public override float CustomScore(int doc, float subQueryScore, float[] valSrcScores)
+            {
+                return parent.CustomScore(doc, subQueryScore, valSrcScores);
+            }
+
+            public override float CustomScore(int doc, float subQueryScore, float valSrcScore)
+            {
+                return parent.CustomScore(doc, subQueryScore, valSrcScore);
+            }
+
+            public override Explanation CustomExplain(int doc, Explanation subQueryExpl,
Explanation[] valSrcExpls)
+            {
+                return parent.CustomExplain(doc, subQueryExpl, valSrcExpls);
+            }
+
+            public override Explanation CustomExplain(int doc, Explanation subQueryExpl,
Explanation valSrcExpl)
+            {
+                return parent.CustomExplain(doc, subQueryExpl, valSrcExpl);
+            }
+        }
 		
-		/// <summary> Compute a custom score by the subQuery score and a number of 
-		/// ValueSourceQuery scores.
-		/// <p/> 
-		/// Subclasses can override this method to modify the custom score.  
-		/// <p/>
-		/// If your custom scoring is different than the default herein you 
-		/// should override at least one of the two customScore() methods.
-		/// If the number of ValueSourceQueries is always &lt; 2 it is 
-		/// sufficient to override the other 
-		/// {@link #CustomScore(int, float, float) customScore()} 
-		/// method, which is simpler. 
-		/// <p/>
-		/// The default computation herein is a multiplication of given scores:
-		/// <pre>
-		/// ModifiedScore = valSrcScore * valSrcScores[0] * valSrcScores[1] * ...
-		/// </pre>        /// 
-        /// NOTE: the doc is relative to the current reader, last passed to <see cref="SetNextReader"/>
-		/// </summary>
-		/// <param name="doc">id of scored doc. 
-		/// </param>
-		/// <param name="subQueryScore">score of that doc by the subQuery.
-		/// </param>
-		/// <param name="valSrcScores">scores of that doc by the ValueSourceQuery.
-		/// </param>
-		/// <returns> custom score.
-		/// </returns>
+        /// <summary>
+        /// Compute a custom score by the subQuery score and a number of 
+        /// ValueSourceQuery scores.
+        /// 
+        /// The doc is relative to the current reader, which is
+        /// unknown to CustomScoreQuery when using per-segment search (since Lucene 2.9).
+        /// Please override {@link #getCustomScoreProvider} and return a subclass
+        /// of {@link CustomScoreProvider} for the given {@link IndexReader}.
+        /// see CustomScoreProvider#customScore(int,float,float[])
+        /// </summary>
+        [Obsolete("Will be removed in Lucene 3.1")]
 		public virtual float CustomScore(int doc, float subQueryScore, float[] valSrcScores)
 		{
 			if (valSrcScores.Length == 1)
@@ -215,56 +261,29 @@
 		}
 		
 		/// <summary> Compute a custom score by the subQuery score and the ValueSourceQuery
score.
-		/// <p/> 
-		/// Subclasses can override this method to modify the custom score.
-		/// <p/>
-		/// If your custom scoring is different than the default herein you 
-		/// should override at least one of the two customScore() methods.
-		/// If the number of ValueSourceQueries is always &lt; 2 it is 
-		/// sufficient to override this customScore() method, which is simpler. 
-		/// <p/>
-		/// The default computation herein is a multiplication of the two scores:
-		/// <pre>
-		/// ModifiedScore = subQueryScore * valSrcScore
-		/// </pre>
-		/// NOTE: the doc is relative to the current reader, last passed to <see cref="SetNextReader"/>
+        /// 
+        /// The doc is relative to the current reader, which is
+        /// unknown to CustomScoreQuery when using per-segment search (since Lucene 2.9).
+        /// Please override {@link #getCustomScoreProvider} and return a subclass
+        /// of {@link CustomScoreProvider} for the given {@link IndexReader}.
+        /// @see CustomScoreProvider#customScore(int,float,float)
 		/// </summary>
-		/// <param name="doc">id of scored doc. 
-		/// </param>
-		/// <param name="subQueryScore">score of that doc by the subQuery.
-		/// </param>
-		/// <param name="valSrcScore">score of that doc by the ValueSourceQuery.
-		/// </param>
-		/// <returns> custom score.
-		/// </returns>
+        [Obsolete("Will be removed in Lucene 3.1")]
 		public virtual float CustomScore(int doc, float subQueryScore, float valSrcScore)
 		{
 			return subQueryScore * valSrcScore;
 		}
 
-        /// <summary>
-        /// Called when the scoring switches to another reader.
-        /// </summary>
-        /// <param name="reader">The next IndexReader</param>
-        public virtual void SetNextReader(IndexReader reader)
-        {
-
-        }
+        
 		
 		/// <summary> Explain the custom score.
-		/// Whenever overriding {@link #CustomScore(int, float, float[])}, 
-		/// this method should also be overridden to provide the correct explanation
-		/// for the part of the custom scoring.
-		/// 
+        /// 
+        /// The doc is relative to the current reader, which is
+        /// unknown to CustomScoreQuery when using per-segment search (since Lucene 2.9).
+        /// Please override {@link #getCustomScoreProvider} and return a subclass
+        /// of {@link CustomScoreProvider} for the given {@link IndexReader}.
 		/// </summary>
-		/// <param name="doc">doc being explained.
-		/// </param>
-		/// <param name="subQueryExpl">explanation for the sub-query part.
-		/// </param>
-		/// <param name="valSrcExpls">explanation for the value source part.
-		/// </param>
-		/// <returns> an explanation for the custom score
-		/// </returns>
+        [Obsolete("Will be removed in Lucene 3.1.")]
 		public virtual Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation[]
valSrcExpls)
 		{
 			if (valSrcExpls.Length == 1)
@@ -290,19 +309,12 @@
 		}
 		
 		/// <summary> Explain the custom score.
-		/// Whenever overriding {@link #CustomScore(int, float, float)}, 
-		/// this method should also be overridden to provide the correct explanation
-		/// for the part of the custom scoring.
-		/// 
+        /// The doc is relative to the current reader, which is
+        /// unknown to CustomScoreQuery when using per-segment search (since Lucene 2.9).
+        /// Please override {@link #getCustomScoreProvider} and return a subclass
+        /// of {@link CustomScoreProvider} for the given {@link IndexReader}.
 		/// </summary>
-		/// <param name="doc">doc being explained.
-		/// </param>
-		/// <param name="subQueryExpl">explanation for the sub-query part.
-		/// </param>
-		/// <param name="valSrcExpl">explanation for the value source part.
-		/// </param>
-		/// <returns> an explanation for the custom score
-		/// </returns>
+        [Obsolete("Will be removed in Lucene 3.1")]
 		public virtual Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation
valSrcExpl)
 		{
 			float valSrcScore = 1;
@@ -445,7 +457,7 @@
 				{
 					valSrcExpls[i] = valSrcScorers[i].Explain(doc);
 				}
-				Explanation customExp = Enclosing_Instance.CustomExplain(doc, subQueryExpl, valSrcExpls);
+                Explanation customExp = Enclosing_Instance.GetCustomScoreProvider(reader).CustomExplain(doc,
subQueryExpl, valSrcExpls);
 				float sc = GetValue() * customExp.GetValue();
 				Explanation res = new ComplexExplanation(true, sc, Enclosing_Instance.ToString() + ",
product of:");
 				res.AddDetail(customExp);
@@ -483,6 +495,7 @@
 			private Scorer subQueryScorer;
 			private Scorer[] valSrcScorers;
 			private IndexReader reader;
+            private CustomScoreProvider provider;
 			private float[] vScores; // reused in score() to avoid allocating this array for each
doc 
 			
 			// constructor
@@ -495,7 +508,7 @@
 				this.valSrcScorers = valSrcScorers;
 				this.reader = reader;
 				this.vScores = new float[valSrcScorers.Length];
-                this.Enclosing_Instance.SetNextReader(reader);
+                this.provider = this.Enclosing_Instance.GetCustomScoreProvider(reader);
 			}
 			
 			/// <deprecated> use {@link #NextDoc()} instead. 
@@ -539,7 +552,7 @@
 				{
 					vScores[i] = valSrcScorers[i].Score();
 				}
-				return qWeight * Enclosing_Instance.CustomScore(subQueryScorer.DocID(), subQueryScorer.Score(),
vScores);
+                return qWeight * provider.CustomScore(subQueryScorer.DocID(), subQueryScorer.Score(),
vScores);
 			}
 			
 			/// <deprecated> use {@link #Advance(int)} instead. 

Modified: lucene/lucene.net/trunk/C#/src/Test/Search/Function/TestCustomScoreQuery.cs
URL: http://svn.apache.org/viewvc/lucene/lucene.net/trunk/C%23/src/Test/Search/Function/TestCustomScoreQuery.cs?rev=912416&r1=912415&r2=912416&view=diff
==============================================================================
--- lucene/lucene.net/trunk/C#/src/Test/Search/Function/TestCustomScoreQuery.cs (original)
+++ lucene/lucene.net/trunk/C#/src/Test/Search/Function/TestCustomScoreQuery.cs Sun Feb 21
22:07:02 2010
@@ -97,23 +97,37 @@
 			{
 				return "customAdd";
 			}
-			/*(non-Javadoc) @see Lucene.Net.Search.Function.CustomScoreQuery#customScore(int, float,
float) */
-			public override float CustomScore(int doc, float subQueryScore, float valSrcScore)
-			{
-				return subQueryScore + valSrcScore;
-			}
-			/* (non-Javadoc)@see Lucene.Net.Search.Function.CustomScoreQuery#customExplain(int, Lucene.Net.Search.Explanation,
Lucene.Net.Search.Explanation)*/
-			public override Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation
valSrcExpl)
-			{
-				float valSrcScore = valSrcExpl == null?0:valSrcExpl.GetValue();
-				Explanation exp = new Explanation(valSrcScore + subQueryExpl.GetValue(), "custom score:
sum of:");
-				exp.AddDetail(subQueryExpl);
-				if (valSrcExpl != null)
-				{
-					exp.AddDetail(valSrcExpl);
-				}
-				return exp;
-			}
+            protected override CustomScoreProvider GetCustomScoreProvider(IndexReader reader)
+            {
+                return new AnonymousCustomScoreProvider(reader);
+            }
+
+            class AnonymousCustomScoreProvider : CustomScoreProvider
+            {
+                IndexReader reader;
+
+                public AnonymousCustomScoreProvider(IndexReader reader) : base(reader)
+                {
+                    this.reader = reader;
+                }
+
+                public override float CustomScore(int doc, float subQueryScore, float valSrcScore)
+                {
+                    return subQueryScore + valSrcScore;
+                }
+
+                public override Explanation CustomExplain(int doc, Explanation subQueryExpl,
Explanation valSrcExpl)
+                {
+                    float valSrcScore = valSrcExpl == null ? 0 : valSrcExpl.GetValue();
+                    Explanation exp = new Explanation(valSrcScore + subQueryExpl.GetValue(),
"custom score: sum of:");
+                    exp.AddDetail(subQueryExpl);
+                    if (valSrcExpl != null)
+                    {
+                        exp.AddDetail(valSrcExpl);
+                    }
+                    return exp;
+                }
+            }
 		}
 		
 		// must have static class otherwise serialization tests fail
@@ -130,59 +144,83 @@
 				return "customMulAdd";
 			}
 			/*(non-Javadoc) @see Lucene.Net.Search.Function.CustomScoreQuery#customScore(int, float,
float) */
-			public override float CustomScore(int doc, float subQueryScore, float[] valSrcScores)
-			{
-				if (valSrcScores.Length == 0)
-				{
-					return subQueryScore;
-				}
-				if (valSrcScores.Length == 1)
-				{
-					return subQueryScore + valSrcScores[0];
-                    // confirm that skipping beyond the last doc, on the
-                    // previous reader, hits NO_MORE_DOCS
-				}
-				return (subQueryScore + valSrcScores[0]) * valSrcScores[1]; // we know there are two
-			}
-			/* (non-Javadoc)@see Lucene.Net.Search.Function.CustomScoreQuery#customExplain(int, Lucene.Net.Search.Explanation,
Lucene.Net.Search.Explanation)*/
-			public override Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation[]
valSrcExpls)
-			{
-				if (valSrcExpls.Length == 0)
-				{
-					return subQueryExpl;
-				}
-				Explanation exp = new Explanation(valSrcExpls[0].GetValue() + subQueryExpl.GetValue(),
"sum of:");
-				exp.AddDetail(subQueryExpl);
-				exp.AddDetail(valSrcExpls[0]);
-				if (valSrcExpls.Length == 1)
-				{
-					exp.SetDescription("CustomMulAdd, sum of:");
-					return exp;
-				}
-				Explanation exp2 = new Explanation(valSrcExpls[1].GetValue() * exp.GetValue(), "custom
score: product of:");
-				exp2.AddDetail(valSrcExpls[1]);
-				exp2.AddDetail(exp);
-				return exp2;
-			}
+            protected override CustomScoreProvider GetCustomScoreProvider(IndexReader reader)
+            {
+                return new AnonymousCustomScoreProvider(reader);
+            }
+
+            class AnonymousCustomScoreProvider : CustomScoreProvider
+            {
+                IndexReader reader;
+
+                public AnonymousCustomScoreProvider(IndexReader reader) : base(reader)
+                {
+                    this.reader = reader;
+                }
+
+                public override float CustomScore(int doc, float subQueryScore, float[] valSrcScores)
+                {
+                    if (valSrcScores.Length == 0)
+                    {
+                        return subQueryScore;
+                    }
+                    if (valSrcScores.Length == 1)
+                    {
+                        return subQueryScore + valSrcScores[0];
+                        // confirm that skipping beyond the last doc, on the
+                        // previous reader, hits NO_MORE_DOCS
+                    }
+                    return (subQueryScore + valSrcScores[0]) * valSrcScores[1]; // we know
there are two
+                }
+
+                public override Explanation CustomExplain(int doc, Explanation subQueryExpl,
Explanation[] valSrcExpls)
+                {
+                    if (valSrcExpls.Length == 0)
+                    {
+                        return subQueryExpl;
+                    }
+                    Explanation exp = new Explanation(valSrcExpls[0].GetValue() + subQueryExpl.GetValue(),
"sum of:");
+                    exp.AddDetail(subQueryExpl);
+                    exp.AddDetail(valSrcExpls[0]);
+                    if (valSrcExpls.Length == 1)
+                    {
+                        exp.SetDescription("CustomMulAdd, sum of:");
+                        return exp;
+                    }
+                    Explanation exp2 = new Explanation(valSrcExpls[1].GetValue() * exp.GetValue(),
"custom score: product of:");
+                    exp2.AddDetail(valSrcExpls[1]);
+                    exp2.AddDetail(exp);
+                    return exp2;
+                }
+            }
 		}
 
         private class CustomExternalQuery : CustomScoreQuery 
         {
-            private IndexReader reader;
-            private int[] values;
-
-            public override float CustomScore(int doc, float subScore, float valSrcScore)

+            protected override CustomScoreProvider GetCustomScoreProvider(IndexReader reader)

             {
-                Assert.IsTrue(doc <= reader.MaxDoc());
-                return (float) values[doc];
+                int[] values = FieldCache_Fields.DEFAULT.GetInts(reader, INT_FIELD);
+                return new AnonymousCustomScoreProvider(reader,values);
             }
-
-            public override void SetNextReader(IndexReader r)
+            
+            class AnonymousCustomScoreProvider : CustomScoreProvider 
             {
-                reader = r;
-                values = FieldCache_Fields.DEFAULT.GetInts(r, INT_FIELD);
-            }
+                IndexReader reader;
+                int[] values = null;
+
+                public AnonymousCustomScoreProvider(IndexReader reader, int[] values) : base(reader)
+                {
+                    this.reader = reader;
+                    this.values = values;
+                }
 
+                public override float CustomScore(int doc, float subScore, float valSrcScore)
+                {
+                    Assert.IsTrue(doc <= reader.MaxDoc());
+                    return (float)values[doc];
+                }
+            }
+            
             public CustomExternalQuery(Query q) : base(q)
             {  }
         }



Mime
View raw message