TermScorer.cs
上传用户:zhangkuixh
上传日期:2013-09-30
资源大小:5473k
文件大小:6k
源码类别:

搜索引擎

开发平台:

C#

  1. /*
  2.  * Copyright 2004 The Apache Software Foundation
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  * 
  8.  * http://www.apache.org/licenses/LICENSE-2.0
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. using System;
  17. using TermDocs = Lucene.Net.Index.TermDocs;
  18. namespace Lucene.Net.Search
  19. {
  20. /// <summary>Expert: A <code>Scorer</code> for documents matching a <code>Term</code>.</summary>
  21. sealed class TermScorer : Scorer
  22. {
  23. private Weight weight;
  24. private TermDocs termDocs;
  25. private byte[] norms;
  26. private float weightValue;
  27. private int doc;
  28. private int[] docs = new int[32]; // buffered doc numbers
  29. private int[] freqs = new int[32]; // buffered term freqs
  30. private int pointer;
  31. private int pointerMax;
  32. private const int SCORE_CACHE_SIZE = 32;
  33. private float[] scoreCache = new float[SCORE_CACHE_SIZE];
  34. /// <summary>Construct a <code>TermScorer</code>.</summary>
  35. /// <param name="weight">The weight of the <code>Term</code> in the query.
  36. /// </param>
  37. /// <param name="td">An iterator over the documents matching the <code>Term</code>.
  38. /// </param>
  39. /// <param name="similarity">The </code>Similarity</code> implementation to be used for score computations.
  40. /// </param>
  41. /// <param name="norms">The field norms of the document fields for the <code>Term</code>.
  42. /// </param>
  43. internal TermScorer(Weight weight, TermDocs td, Similarity similarity, byte[] norms) : base(similarity)
  44. {
  45. this.weight = weight;
  46. this.termDocs = td;
  47. this.norms = norms;
  48. this.weightValue = weight.GetValue();
  49. for (int i = 0; i < SCORE_CACHE_SIZE; i++)
  50. scoreCache[i] = GetSimilarity().Tf(i) * weightValue;
  51. }
  52. public override void  Score(HitCollector hc)
  53. {
  54. Next();
  55. Score(hc, System.Int32.MaxValue);
  56. }
  57. protected internal override bool Score(HitCollector c, int end)
  58. {
  59. Similarity similarity = GetSimilarity(); // cache sim in local
  60. float[] normDecoder = Similarity.GetNormDecoder();
  61. while (doc < end)
  62. {
  63. // for docs in window
  64. int f = freqs[pointer];
  65. float score = f < SCORE_CACHE_SIZE?scoreCache[f]:similarity.Tf(f) * weightValue; // cache miss
  66. score *= normDecoder[norms[doc] & 0xFF]; // normalize for field
  67. c.Collect(doc, score); // collect score
  68. if (++pointer >= pointerMax)
  69. {
  70. pointerMax = termDocs.Read(docs, freqs); // refill buffers
  71. if (pointerMax != 0)
  72. {
  73. pointer = 0;
  74. }
  75. else
  76. {
  77. termDocs.Close(); // close stream
  78. doc = System.Int32.MaxValue; // set to sentinel value
  79. return false;
  80. }
  81. }
  82. doc = docs[pointer];
  83. }
  84. return true;
  85. }
  86. /// <summary>Returns the current document number matching the query.
  87. /// Initially invalid, until {@link #Next()} is called the first time.
  88. /// </summary>
  89. public override int Doc()
  90. {
  91. return doc;
  92. }
  93. /// <summary>Advances to the next document matching the query.
  94. /// <br>The iterator over the matching documents is buffered using
  95. /// {@link TermDocs#Read(int[],int[])}.
  96. /// </summary>
  97. /// <returns> true iff there is another document matching the query.
  98. /// </returns>
  99. public override bool Next()
  100. {
  101. pointer++;
  102. if (pointer >= pointerMax)
  103. {
  104. pointerMax = termDocs.Read(docs, freqs); // refill buffer
  105. if (pointerMax != 0)
  106. {
  107. pointer = 0;
  108. }
  109. else
  110. {
  111. termDocs.Close(); // close stream
  112. doc = System.Int32.MaxValue; // set to sentinel value
  113. return false;
  114. }
  115. }
  116. doc = docs[pointer];
  117. return true;
  118. }
  119. public override float Score()
  120. {
  121. int f = freqs[pointer];
  122. float raw = f < SCORE_CACHE_SIZE ? scoreCache[f] : GetSimilarity().Tf(f) * weightValue; // cache miss
  123. return raw * Similarity.DecodeNorm(norms[doc]); // normalize for field
  124. }
  125. /// <summary>Skips to the first match beyond the current whose document number is
  126. /// greater than or equal to a given target. 
  127. /// <br>The implementation uses {@link TermDocs#SkipTo(int)}.
  128. /// </summary>
  129. /// <param name="target">The target document number.
  130. /// </param>
  131. /// <returns> true iff there is such a match.
  132. /// </returns>
  133. public override bool SkipTo(int target)
  134. {
  135. // first scan in cache
  136. for (pointer++; pointer < pointerMax; pointer++)
  137. {
  138. if (docs[pointer] >= target)
  139. {
  140. doc = docs[pointer];
  141. return true;
  142. }
  143. }
  144. // not found in cache, seek underlying stream
  145. bool result = termDocs.SkipTo(target);
  146. if (result)
  147. {
  148. pointerMax = 1;
  149. pointer = 0;
  150. docs[pointer] = doc = termDocs.Doc();
  151. freqs[pointer] = termDocs.Freq();
  152. }
  153. else
  154. {
  155. doc = System.Int32.MaxValue;
  156. }
  157. return result;
  158. }
  159. /// <summary>Returns an explanation of the score for a document.
  160. /// <br>When this method is used, the {@link #Next()} method
  161. /// and the {@link #Score(HitCollector)} method should not be used.
  162. /// </summary>
  163. /// <param name="doc">The document number for the explanation.
  164. /// </param>
  165. /// <todo>  Modify to make use of {@link TermDocs#SkipTo(int)}. </todo>
  166. public override Explanation Explain(int doc)
  167. {
  168. TermQuery query = (TermQuery) weight.GetQuery();
  169. Explanation tfExplanation = new Explanation();
  170. int tf = 0;
  171. while (pointer < pointerMax)
  172. {
  173. if (docs[pointer] == doc)
  174. tf = freqs[pointer];
  175. pointer++;
  176. }
  177. if (tf == 0)
  178. {
  179. while (termDocs.Next())
  180. {
  181. if (termDocs.Doc() == doc)
  182. {
  183. tf = termDocs.Freq();
  184. }
  185. }
  186. }
  187. termDocs.Close();
  188. tfExplanation.SetValue(GetSimilarity().Tf(tf));
  189. tfExplanation.SetDescription("tf(termFreq(" + query.GetTerm() + ")=" + tf + ")");
  190. return tfExplanation;
  191. }
  192. /// <summary>Returns a string representation of this <code>TermScorer</code>. </summary>
  193. public override System.String ToString()
  194. {
  195. return "scorer(" + weight + ")";
  196. }
  197. }
  198. }