1 package org.apache.lucene.search;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import java.io.IOException;
22 import org.apache.lucene.index.TermDocs;
24 /** Expert: A <code>Scorer</code> for documents matching a <code>Term</code>.
26 final class TermScorer extends Scorer {
27 private final TermDocs termDocs;
28 private final byte[] norms;
29 private float weightValue;
33 private final int[] docs = new int[32]; // buffered doc numbers
34 private final int[] freqs = new int[32]; // buffered term freqs
36 private int pointerMax;
38 private static final int SCORE_CACHE_SIZE = 32;
39 private final float[] scoreCache = new float[SCORE_CACHE_SIZE];
42 * Construct a <code>TermScorer</code>.
45 * The weight of the <code>Term</code> in the query.
47 * An iterator over the documents matching the <code>Term</code>.
49 * The </code>Similarity</code> implementation to be used for score
52 * The field norms of the document fields for the <code>Term</code>.
54 TermScorer(Weight weight, TermDocs td, Similarity similarity, byte[] norms) {
55 super(similarity, weight);
59 this.weightValue = weight.getValue();
61 for (int i = 0; i < SCORE_CACHE_SIZE; i++)
62 scoreCache[i] = getSimilarity().tf(i) * weightValue;
66 public void score(Collector c) throws IOException {
67 score(c, Integer.MAX_VALUE, nextDoc());
70 // firstDocID is ignored since nextDoc() sets 'doc'
72 protected boolean score(Collector c, int end, int firstDocID) throws IOException {
74 while (doc < end) { // for docs in window
75 c.collect(doc); // collect score
77 if (++pointer >= pointerMax) {
78 pointerMax = termDocs.read(docs, freqs); // refill buffers
79 if (pointerMax != 0) {
82 termDocs.close(); // close stream
83 doc = Integer.MAX_VALUE; // set to sentinel value
88 freq = freqs[pointer];
94 public int docID() { return doc; }
102 * Advances to the next document matching the query. <br>
103 * The iterator over the matching documents is buffered using
104 * {@link TermDocs#read(int[],int[])}.
106 * @return the document matching the query or NO_MORE_DOCS if there are no more documents.
109 public int nextDoc() throws IOException {
111 if (pointer >= pointerMax) {
112 pointerMax = termDocs.read(docs, freqs); // refill buffer
113 if (pointerMax != 0) {
116 termDocs.close(); // close stream
117 return doc = NO_MORE_DOCS;
121 freq = freqs[pointer];
126 public float score() {
128 float raw = // compute tf(f)*weight
129 freq < SCORE_CACHE_SIZE // check cache
130 ? scoreCache[freq] // cache hit
131 : getSimilarity().tf(freq)*weightValue; // cache miss
133 return norms == null ? raw : raw * getSimilarity().decodeNormValue(norms[doc]); // normalize for field
137 * Advances to the first match beyond the current whose document number is
138 * greater than or equal to a given target. <br>
139 * The implementation uses {@link TermDocs#skipTo(int)}.
142 * The target document number.
143 * @return the matching document or NO_MORE_DOCS if none exist.
146 public int advance(int target) throws IOException {
147 // first scan in cache
148 for (pointer++; pointer < pointerMax; pointer++) {
149 if (docs[pointer] >= target) {
150 freq = freqs[pointer];
151 return doc = docs[pointer];
155 // not found in cache, seek underlying stream
156 boolean result = termDocs.skipTo(target);
160 docs[pointer] = doc = termDocs.doc();
161 freqs[pointer] = freq = termDocs.freq();
168 /** Returns a string representation of this <code>TermScorer</code>. */
170 public String toString() { return "scorer(" + weight + ")"; }