add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / src / java / org / apache / lucene / search / TermScorer.java
1 package org.apache.lucene.search;
2
3 /**
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
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 import java.io.IOException;
21
22 import org.apache.lucene.index.TermDocs;
23
24 /** Expert: A <code>Scorer</code> for documents matching a <code>Term</code>.
25  */
26 final class TermScorer extends Scorer {
27   private TermDocs termDocs;
28   private byte[] norms;
29   private float weightValue;
30   private int doc = -1;
31   private int freq;
32
33   private final int[] docs = new int[32];         // buffered doc numbers
34   private final int[] freqs = new int[32];        // buffered term freqs
35   private int pointer;
36   private int pointerMax;
37
38   private static final int SCORE_CACHE_SIZE = 32;
39   private float[] scoreCache = new float[SCORE_CACHE_SIZE];
40
41   /**
42    * Construct a <code>TermScorer</code>.
43    * 
44    * @param weight
45    *          The weight of the <code>Term</code> in the query.
46    * @param td
47    *          An iterator over the documents matching the <code>Term</code>.
48    * @param similarity
49    *          The </code>Similarity</code> implementation to be used for score
50    *          computations.
51    * @param norms
52    *          The field norms of the document fields for the <code>Term</code>.
53    */
54   TermScorer(Weight weight, TermDocs td, Similarity similarity, byte[] norms) {
55     super(similarity, weight);
56     
57     this.termDocs = td;
58     this.norms = norms;
59     this.weightValue = weight.getValue();
60
61     for (int i = 0; i < SCORE_CACHE_SIZE; i++)
62       scoreCache[i] = getSimilarity().tf(i) * weightValue;
63   }
64
65   @Override
66   public void score(Collector c) throws IOException {
67     score(c, Integer.MAX_VALUE, nextDoc());
68   }
69
70   // firstDocID is ignored since nextDoc() sets 'doc'
71   @Override
72   protected boolean score(Collector c, int end, int firstDocID) throws IOException {
73     c.setScorer(this);
74     while (doc < end) {                           // for docs in window
75       c.collect(doc);                      // collect score
76         
77       if (++pointer >= pointerMax) {
78         pointerMax = termDocs.read(docs, freqs);  // refill buffers
79         if (pointerMax != 0) {
80           pointer = 0;
81         } else {
82           termDocs.close();                       // close stream
83           doc = Integer.MAX_VALUE;                // set to sentinel value
84           return false;
85         }
86       } 
87       doc = docs[pointer];
88       freq = freqs[pointer];
89     }
90     return true;
91   }
92
93   @Override
94   public int docID() { return doc; }
95
96   @Override
97   public float freq() {
98     return freq;
99   }
100
101   /**
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[])}.
105    * 
106    * @return the document matching the query or NO_MORE_DOCS if there are no more documents.
107    */
108   @Override
109   public int nextDoc() throws IOException {
110     pointer++;
111     if (pointer >= pointerMax) {
112       pointerMax = termDocs.read(docs, freqs);    // refill buffer
113       if (pointerMax != 0) {
114         pointer = 0;
115       } else {
116         termDocs.close();                         // close stream
117         return doc = NO_MORE_DOCS;
118       }
119     } 
120     doc = docs[pointer];
121     freq = freqs[pointer];
122     return doc;
123   }
124   
125   @Override
126   public float score() {
127     assert doc != -1;
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
132
133     return norms == null ? raw : raw * getSimilarity().decodeNormValue(norms[doc]); // normalize for field
134   }
135
136   /**
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)}.
140    * 
141    * @param target
142    *          The target document number.
143    * @return the matching document or NO_MORE_DOCS if none exist.
144    */
145   @Override
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];
152       }
153     }
154
155     // not found in cache, seek underlying stream
156     boolean result = termDocs.skipTo(target);
157     if (result) {
158       pointerMax = 1;
159       pointer = 0;
160       docs[pointer] = doc = termDocs.doc();
161       freqs[pointer] = freq = termDocs.freq();
162     } else {
163       doc = NO_MORE_DOCS;
164     }
165     return doc;
166   }
167   
168   /** Returns a string representation of this <code>TermScorer</code>. */
169   @Override
170   public String toString() { return "scorer(" + weight + ")"; }
171
172 }