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

搜索引擎

开发平台:

C#

  1. /*
  2.  * Copyright 2005 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. namespace Lucene.Net.Search
  18. {
  19. /// <summary>A Scorer for queries with a required subscorer and an excluding (prohibited) subscorer.
  20. /// <br>
  21. /// This <code>Scorer</code> implements {@link Scorer#SkipTo(int)},
  22. /// and it uses the skipTo() on the given scorers.
  23. /// </summary>
  24. public class ReqExclScorer : Scorer
  25. {
  26. private Scorer reqScorer, exclScorer;
  27. /// <summary>Construct a <code>ReqExclScorer</code>.</summary>
  28. /// <param name="reqScorer">The scorer that must match, except where
  29. /// </param>
  30. /// <param name="exclScorer">indicates exclusion.
  31. /// </param>
  32. public ReqExclScorer(Scorer reqScorer, Scorer exclScorer) : base(null)
  33. { // No similarity used.
  34. this.reqScorer = reqScorer;
  35. this.exclScorer = exclScorer;
  36. }
  37. private bool firstTime = true;
  38. public override bool Next()
  39. {
  40. if (firstTime)
  41. {
  42. if (!exclScorer.Next())
  43. {
  44. exclScorer = null; // exhausted at start
  45. }
  46. firstTime = false;
  47. }
  48. if (reqScorer == null)
  49. {
  50. return false;
  51. }
  52. if (!reqScorer.Next())
  53. {
  54. reqScorer = null; // exhausted, nothing left
  55. return false;
  56. }
  57. if (exclScorer == null)
  58. {
  59. return true; // reqScorer.next() already returned true
  60. }
  61. return ToNonExcluded();
  62. }
  63. /// <summary>Advance to non excluded doc.
  64. /// <br>On entry:
  65. /// <ul>
  66. /// <li>reqScorer != null,
  67. /// <li>exclScorer != null,
  68. /// <li>reqScorer was advanced once via next() or skipTo()
  69. /// and reqScorer.doc() may still be excluded.
  70. /// </ul>
  71. /// Advances reqScorer a non excluded required doc, if any.
  72. /// </summary>
  73. /// <returns> true iff there is a non excluded required doc.
  74. /// </returns>
  75. private bool ToNonExcluded()
  76. {
  77. int exclDoc = exclScorer.Doc();
  78. do 
  79. {
  80. int reqDoc = reqScorer.Doc(); // may be excluded
  81. if (reqDoc < exclDoc)
  82. {
  83. return true; // reqScorer advanced to before exclScorer, ie. not excluded
  84. }
  85. else if (reqDoc > exclDoc)
  86. {
  87. if (!exclScorer.SkipTo(reqDoc))
  88. {
  89. exclScorer = null; // exhausted, no more exclusions
  90. return true;
  91. }
  92. exclDoc = exclScorer.Doc();
  93. if (exclDoc > reqDoc)
  94. {
  95. return true; // not excluded
  96. }
  97. }
  98. }
  99. while (reqScorer.Next());
  100. reqScorer = null; // exhausted, nothing left
  101. return false;
  102. }
  103. public override int Doc()
  104. {
  105. return reqScorer.Doc(); // reqScorer may be null when next() or skipTo() already return false
  106. }
  107. /// <summary>Returns the score of the current document matching the query.
  108. /// Initially invalid, until {@link #Next()} is called the first time.
  109. /// </summary>
  110. /// <returns> The score of the required scorer.
  111. /// </returns>
  112. public override float Score()
  113. {
  114. return reqScorer.Score(); // reqScorer may be null when next() or skipTo() already return false
  115. }
  116. /// <summary>Skips to the first match beyond the current whose document number is
  117. /// greater than or equal to a given target.
  118. /// <br>When this method is used the {@link #Explain(int)} method should not be used.
  119. /// </summary>
  120. /// <param name="target">The target document number.
  121. /// </param>
  122. /// <returns> true iff there is such a match.
  123. /// </returns>
  124. public override bool SkipTo(int target)
  125. {
  126. if (firstTime)
  127. {
  128. firstTime = false;
  129. if (!exclScorer.SkipTo(target))
  130. {
  131. exclScorer = null; // exhausted
  132. }
  133. }
  134. if (reqScorer == null)
  135. {
  136. return false;
  137. }
  138. if (exclScorer == null)
  139. {
  140. return reqScorer.SkipTo(target);
  141. }
  142. if (!reqScorer.SkipTo(target))
  143. {
  144. reqScorer = null;
  145. return false;
  146. }
  147. return ToNonExcluded();
  148. }
  149. public override Explanation Explain(int doc)
  150. {
  151. Explanation res = new Explanation();
  152. if (exclScorer.SkipTo(doc) && (exclScorer.Doc() == doc))
  153. {
  154. res.SetDescription("excluded");
  155. }
  156. else
  157. {
  158. res.SetDescription("not excluded");
  159. res.AddDetail(reqScorer.Explain(doc));
  160. }
  161. return res;
  162. }
  163. }
  164. }