add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / src / java / org / apache / lucene / search / Scorer.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.search.BooleanClause.Occur;
23
24 /**
25  * Expert: Common scoring functionality for different types of queries.
26  *
27  * <p>
28  * A <code>Scorer</code> iterates over documents matching a
29  * query in increasing order of doc Id.
30  * </p>
31  * <p>
32  * Document scores are computed using a given <code>Similarity</code>
33  * implementation.
34  * </p>
35  *
36  * <p><b>NOTE</b>: The values Float.Nan,
37  * Float.NEGATIVE_INFINITY and Float.POSITIVE_INFINITY are
38  * not valid scores.  Certain collectors (eg {@link
39  * TopScoreDocCollector}) will not properly collect hits
40  * with these scores.
41  */
42 public abstract class Scorer extends DocIdSetIterator {
43   private final Similarity similarity;
44   protected final Weight weight;
45
46   /**
47    * Constructs a Scorer
48    * @param weight The scorers <code>Weight</code>.
49    */
50   protected Scorer(Weight weight) {
51     this(null, weight);
52   }
53   
54   /** Constructs a Scorer.
55    * @param similarity The <code>Similarity</code> implementation used by this scorer.
56    * @deprecated Use {@link #Scorer(Weight)} instead.
57    */
58   @Deprecated
59   protected Scorer(Similarity similarity) {
60     this(similarity, null);
61   }
62   
63   /**
64    * Constructs a Scorer
65    * @param similarity The <code>Similarity</code> implementation used by this scorer.
66    * @param weight The scorers <code>Weight</code>
67    * @deprecated Use {@link #Scorer(Weight)} instead.
68    */
69   @Deprecated
70   protected Scorer(Similarity similarity, Weight weight) {
71     this.similarity = similarity;
72     this.weight = weight;
73   }
74
75   /** Returns the Similarity implementation used by this scorer. 
76    * @deprecated Store any Similarity you might need privately in your implementation instead.
77    */
78   @Deprecated
79   public Similarity getSimilarity() {
80     return this.similarity;
81   }
82
83   /** Scores and collects all matching documents.
84    * @param collector The collector to which all matching documents are passed.
85    */
86   public void score(Collector collector) throws IOException {
87     collector.setScorer(this);
88     int doc;
89     while ((doc = nextDoc()) != NO_MORE_DOCS) {
90       collector.collect(doc);
91     }
92   }
93
94   /**
95    * Expert: Collects matching documents in a range. Hook for optimization.
96    * Note, <code>firstDocID</code> is added to ensure that {@link #nextDoc()}
97    * was called before this method.
98    *
99    * <p><b>NOTE:</b> Because of backwards compatibility, this method is still
100    * declared as <b>protected</b>, but it is intended to be <b>public</b>,
101    * because it's called from other classes (like BooleanScorer).
102    * If you subclass {@code Scorer}, you should declare the overridden method
103    * as public to ease transition to Lucene 4.0, where it will be public.</p>
104    * 
105    * @param collector
106    *          The collector to which all matching documents are passed.
107    * @param max
108    *          Do not score documents past this.
109    * @param firstDocID
110    *          The first document ID (ensures {@link #nextDoc()} is called before
111    *          this method.
112    * @return true if more matching documents may remain.
113    */
114   protected boolean score(Collector collector, int max, int firstDocID) throws IOException {
115     collector.setScorer(this);
116     int doc = firstDocID;
117     while (doc < max) {
118       collector.collect(doc);
119       doc = nextDoc();
120     }
121     return doc != NO_MORE_DOCS;
122   }
123   
124   /** Returns the score of the current document matching the query.
125    * Initially invalid, until {@link #nextDoc()} or {@link #advance(int)}
126    * is called the first time, or when called from within
127    * {@link Collector#collect}.
128    */
129   public abstract float score() throws IOException;
130
131   /** Returns number of matches for the current document.
132    *  This returns a float (not int) because
133    *  SloppyPhraseScorer discounts its freq according to how
134    *  "sloppy" the match was.
135    *
136    * @lucene.experimental */
137   public float freq() throws IOException {
138     throw new UnsupportedOperationException(this + " does not implement freq()");
139   }
140
141   /**
142    * A callback to gather information from a scorer and its sub-scorers. Each
143    * the top-level scorer as well as each of its sub-scorers are passed to
144    * either one of the visit methods depending on their boolean relationship in
145    * the query.
146    * @lucene.experimental
147    */
148   public static abstract class ScorerVisitor<P extends Query, C extends Query, S extends Scorer> {
149     /**
150      * Invoked for all optional scorer 
151      * 
152      * @param parent the parent query of the child query or <code>null</code> if the child is a top-level query
153      * @param child the query of the currently visited scorer
154      * @param scorer the current scorer
155      */
156     public void visitOptional(P parent, C child, S scorer) {}
157     
158     /**
159      * Invoked for all required scorer 
160      * 
161      * @param parent the parent query of the child query or <code>null</code> if the child is a top-level query
162      * @param child the query of the currently visited scorer
163      * @param scorer the current scorer
164      */
165     public void visitRequired(P parent, C child, S scorer) {}
166     
167     /**
168      * Invoked for all prohibited scorer 
169      * 
170      * @param parent the parent query of the child query or <code>null</code> if the child is a top-level query
171      * @param child the query of the currently visited scorer
172      * @param scorer the current scorer
173      */
174     public void visitProhibited(P parent, C child, S scorer) {}
175   } 
176
177   /**
178    * Expert: call this to gather details for all sub-scorers for this query.
179    * This can be used, in conjunction with a custom {@link Collector} to gather
180    * details about how each sub-query matched the current hit.
181    * 
182    * @param visitor a callback executed for each sub-scorer
183    * @lucene.experimental
184    */
185   public void visitScorers(ScorerVisitor<Query, Query, Scorer> visitor) {
186     visitSubScorers(null, Occur.MUST/*must id default*/, visitor);
187   }
188
189   /**
190    * {@link Scorer} subclasses should implement this method if the subclass
191    * itself contains multiple scorers to support gathering details for
192    * sub-scorers via {@link ScorerVisitor}
193    * <p>
194    * Note: this method will throw {@link UnsupportedOperationException} if no
195    * associated {@link Weight} instance is provided to
196    * {@link #Scorer(Weight)}
197    * </p>
198    * 
199    * @lucene.experimental
200    */
201   protected void visitSubScorers(Query parent, Occur relationship,
202       ScorerVisitor<Query, Query, Scorer> visitor) {
203     if (weight == null)
204       throw new UnsupportedOperationException();
205
206     final Query q = weight.getQuery();
207     switch (relationship) {
208     case MUST:
209       visitor.visitRequired(parent, q, this);
210       break;
211     case MUST_NOT:
212       visitor.visitProhibited(parent, q, this);
213       break;
214     case SHOULD:
215       visitor.visitOptional(parent, q, this);
216       break;
217     }
218   }
219 }