Lucene.Net  3.0.3
Lucene.Net is a port of the Lucene search engine library, written in C# and targeted at .NET runtime users.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Pages
TermScorer.cs
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 using System;
19 
20 using TermDocs = Lucene.Net.Index.TermDocs;
21 
22 namespace Lucene.Net.Search
23 {
24 
25  /// <summary>Expert: A <c>Scorer</c> for documents matching a <c>Term</c>.</summary>
26  public sealed class TermScorer:Scorer
27  {
28 
29  private static readonly float[] SIM_NORM_DECODER;
30 
31  private Weight weight;
32  private TermDocs termDocs;
33  private byte[] norms;
34  private float weightValue;
35  private int doc = - 1;
36 
37  private int[] docs = new int[32]; // buffered doc numbers
38  private int[] freqs = new int[32]; // buffered term freqs
39  private int pointer;
40  private int pointerMax;
41 
42  private const int SCORE_CACHE_SIZE = 32;
43  private float[] scoreCache = new float[SCORE_CACHE_SIZE];
44 
45  /// <summary> Construct a <c>TermScorer</c>.
46  ///
47  /// </summary>
48  /// <param name="weight">The weight of the <c>Term</c> in the query.
49  /// </param>
50  /// <param name="td">An iterator over the documents matching the <c>Term</c>.
51  /// </param>
52  /// <param name="similarity">The <c>Similarity</c> implementation to be used for score
53  /// computations.
54  /// </param>
55  /// <param name="norms">The field norms of the document fields for the <c>Term</c>.
56  /// </param>
57  public /*internal*/ TermScorer(Weight weight, TermDocs td, Similarity similarity, byte[] norms):base(similarity)
58  {
59  this.weight = weight;
60  this.termDocs = td;
61  this.norms = norms;
62  this.weightValue = weight.Value;
63 
64  for (int i = 0; i < SCORE_CACHE_SIZE; i++)
65  scoreCache[i] = Similarity.Tf(i) * weightValue;
66  }
67 
68  public override void Score(Collector c)
69  {
70  Score(c, System.Int32.MaxValue, NextDoc());
71  }
72 
73  // firstDocID is ignored since nextDoc() sets 'doc'
74  public /*protected internal*/ override bool Score(Collector c, int end, int firstDocID)
75  {
76  c.SetScorer(this);
77  while (doc < end)
78  {
79  // for docs in window
80  c.Collect(doc); // collect score
81 
82  if (++pointer >= pointerMax)
83  {
84  pointerMax = termDocs.Read(docs, freqs); // refill buffers
85  if (pointerMax != 0)
86  {
87  pointer = 0;
88  }
89  else
90  {
91  termDocs.Close(); // close stream
92  doc = System.Int32.MaxValue; // set to sentinel value
93  return false;
94  }
95  }
96  doc = docs[pointer];
97  }
98  return true;
99  }
100 
101  public override int DocID()
102  {
103  return doc;
104  }
105 
106  /// <summary> Advances to the next document matching the query. <br/>
107  /// The iterator over the matching documents is buffered using
108  /// <see cref="TermDocs.Read(int[],int[])" />.
109  ///
110  /// </summary>
111  /// <returns> the document matching the query or -1 if there are no more documents.
112  /// </returns>
113  public override int NextDoc()
114  {
115  pointer++;
116  if (pointer >= pointerMax)
117  {
118  pointerMax = termDocs.Read(docs, freqs); // refill buffer
119  if (pointerMax != 0)
120  {
121  pointer = 0;
122  }
123  else
124  {
125  termDocs.Close(); // close stream
126  return doc = NO_MORE_DOCS;
127  }
128  }
129  doc = docs[pointer];
130  return doc;
131  }
132 
133  public override float Score()
134  {
135  System.Diagnostics.Debug.Assert(doc != - 1);
136  int f = freqs[pointer];
137  float raw = f < SCORE_CACHE_SIZE?scoreCache[f]:Similarity.Tf(f) * weightValue; // cache miss
138 
139  return norms == null?raw:raw * SIM_NORM_DECODER[norms[doc] & 0xFF]; // normalize for field
140  }
141 
142  /// <summary> Advances to the first match beyond the current whose document number is
143  /// greater than or equal to a given target. <br/>
144  /// The implementation uses <see cref="TermDocs.SkipTo(int)" />.
145  ///
146  /// </summary>
147  /// <param name="target">The target document number.
148  /// </param>
149  /// <returns> the matching document or -1 if none exist.
150  /// </returns>
151  public override int Advance(int target)
152  {
153  // first scan in cache
154  for (pointer++; pointer < pointerMax; pointer++)
155  {
156  if (docs[pointer] >= target)
157  {
158  return doc = docs[pointer];
159  }
160  }
161 
162  // not found in cache, seek underlying stream
163  bool result = termDocs.SkipTo(target);
164  if (result)
165  {
166  pointerMax = 1;
167  pointer = 0;
168  docs[pointer] = doc = termDocs.Doc;
169  freqs[pointer] = termDocs.Freq;
170  }
171  else
172  {
173  doc = NO_MORE_DOCS;
174  }
175  return doc;
176  }
177 
178  /// <summary>Returns a string representation of this <c>TermScorer</c>. </summary>
179  public override System.String ToString()
180  {
181  return "scorer(" + weight + ")";
182  }
183  static TermScorer()
184  {
185  SIM_NORM_DECODER = Search.Similarity.GetNormDecoder();
186  }
187  }
188 }