001: package org.apache.lucene.search;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import org.apache.lucene.index.IndexReader;
021:
022: import java.io.IOException;
023: import java.util.BitSet;
024: import java.util.Set;
025:
026: /**
027: * A query that wraps a filter and simply returns a constant score equal to the
028: * query boost for every document in the filter.
029: *
030: *
031: * @version $Id: ConstantScoreQuery.java 564236 2007-08-09 15:21:19Z gsingers $
032: */
033: public class ConstantScoreQuery extends Query {
034: protected final Filter filter;
035:
036: public ConstantScoreQuery(Filter filter) {
037: this .filter = filter;
038: }
039:
040: /** Returns the encapsulated filter */
041: public Filter getFilter() {
042: return filter;
043: }
044:
045: public Query rewrite(IndexReader reader) throws IOException {
046: return this ;
047: }
048:
049: public void extractTerms(Set terms) {
050: // OK to not add any terms when used for MultiSearcher,
051: // but may not be OK for highlighting
052: }
053:
054: protected class ConstantWeight implements Weight {
055: private Similarity similarity;
056: private float queryNorm;
057: private float queryWeight;
058:
059: public ConstantWeight(Searcher searcher) {
060: this .similarity = getSimilarity(searcher);
061: }
062:
063: public Query getQuery() {
064: return ConstantScoreQuery.this ;
065: }
066:
067: public float getValue() {
068: return queryWeight;
069: }
070:
071: public float sumOfSquaredWeights() throws IOException {
072: queryWeight = getBoost();
073: return queryWeight * queryWeight;
074: }
075:
076: public void normalize(float norm) {
077: this .queryNorm = norm;
078: queryWeight *= this .queryNorm;
079: }
080:
081: public Scorer scorer(IndexReader reader) throws IOException {
082: return new ConstantScorer(similarity, reader, this );
083: }
084:
085: public Explanation explain(IndexReader reader, int doc)
086: throws IOException {
087:
088: ConstantScorer cs = (ConstantScorer) scorer(reader);
089: boolean exists = cs.bits.get(doc);
090:
091: ComplexExplanation result = new ComplexExplanation();
092:
093: if (exists) {
094: result.setDescription("ConstantScoreQuery(" + filter
095: + "), product of:");
096: result.setValue(queryWeight);
097: result.setMatch(Boolean.TRUE);
098: result.addDetail(new Explanation(getBoost(), "boost"));
099: result
100: .addDetail(new Explanation(queryNorm,
101: "queryNorm"));
102: } else {
103: result.setDescription("ConstantScoreQuery(" + filter
104: + ") doesn't match id " + doc);
105: result.setValue(0);
106: result.setMatch(Boolean.FALSE);
107: }
108: return result;
109: }
110: }
111:
112: protected class ConstantScorer extends Scorer {
113: final BitSet bits;
114: final float theScore;
115: int doc = -1;
116:
117: public ConstantScorer(Similarity similarity,
118: IndexReader reader, Weight w) throws IOException {
119: super (similarity);
120: theScore = w.getValue();
121: bits = filter.bits(reader);
122: }
123:
124: public boolean next() throws IOException {
125: doc = bits.nextSetBit(doc + 1);
126: return doc >= 0;
127: }
128:
129: public int doc() {
130: return doc;
131: }
132:
133: public float score() throws IOException {
134: return theScore;
135: }
136:
137: public boolean skipTo(int target) throws IOException {
138: doc = bits.nextSetBit(target); // requires JDK 1.4
139: return doc >= 0;
140: }
141:
142: public Explanation explain(int doc) throws IOException {
143: throw new UnsupportedOperationException();
144: }
145: }
146:
147: protected Weight createWeight(Searcher searcher) {
148: return new ConstantScoreQuery.ConstantWeight(searcher);
149: }
150:
151: /** Prints a user-readable version of this query. */
152: public String toString(String field) {
153: return "ConstantScore(" + filter.toString()
154: + (getBoost() == 1.0 ? ")" : "^" + getBoost());
155: }
156:
157: /** Returns true if <code>o</code> is equal to this. */
158: public boolean equals(Object o) {
159: if (this == o)
160: return true;
161: if (!(o instanceof ConstantScoreQuery))
162: return false;
163: ConstantScoreQuery other = (ConstantScoreQuery) o;
164: return this .getBoost() == other.getBoost()
165: && filter.equals(other.filter);
166: }
167:
168: /** Returns a hash code value for this object. */
169: public int hashCode() {
170: // Simple add is OK since no existing filter hashcode has a float component.
171: return filter.hashCode() + Float.floatToIntBits(getBoost());
172: }
173:
174: }
|