KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > lucene > search > BooleanScorer


1 package org.apache.lucene.search;
2
3 /**
4  * Copyright 2004 The Apache Software Foundation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import java.io.IOException JavaDoc;
20
21 final class BooleanScorer extends Scorer {
22   private SubScorer scorers = null;
23   private BucketTable bucketTable = new BucketTable(this);
24
25   private int maxCoord = 1;
26   private float[] coordFactors = null;
27
28   private int requiredMask = 0;
29   private int prohibitedMask = 0;
30   private int nextMask = 1;
31
32   BooleanScorer(Similarity similarity) {
33     super(similarity);
34   }
35
36   static final class SubScorer {
37     public Scorer scorer;
38     public boolean done;
39     public boolean required = false;
40     public boolean prohibited = false;
41     public HitCollector collector;
42     public SubScorer next;
43
44     public SubScorer(Scorer scorer, boolean required, boolean prohibited,
45                      HitCollector collector, SubScorer next)
46       throws IOException JavaDoc {
47       this.scorer = scorer;
48       this.done = !scorer.next();
49       this.required = required;
50       this.prohibited = prohibited;
51       this.collector = collector;
52       this.next = next;
53     }
54   }
55
56   final void add(Scorer scorer, boolean required, boolean prohibited)
57     throws IOException JavaDoc {
58     int mask = 0;
59     if (required || prohibited) {
60       if (nextMask == 0)
61         throw new IndexOutOfBoundsException JavaDoc
62           ("More than 32 required/prohibited clauses in query.");
63       mask = nextMask;
64       nextMask = nextMask << 1;
65     } else
66       mask = 0;
67
68     if (!prohibited)
69       maxCoord++;
70
71     if (prohibited)
72       prohibitedMask |= mask; // update prohibited mask
73
else if (required)
74       requiredMask |= mask; // update required mask
75

76     scorers = new SubScorer(scorer, required, prohibited,
77                             bucketTable.newCollector(mask), scorers);
78   }
79
80   private final void computeCoordFactors() {
81     coordFactors = new float[maxCoord];
82     for (int i = 0; i < maxCoord; i++)
83       coordFactors[i] = getSimilarity().coord(i, maxCoord-1);
84   }
85
86   private int end;
87   private Bucket current;
88
89   public void score(HitCollector hc) throws IOException JavaDoc {
90     next();
91     score(hc, Integer.MAX_VALUE);
92   }
93
94   protected boolean score(HitCollector hc, int max) throws IOException JavaDoc {
95     if (coordFactors == null)
96       computeCoordFactors();
97
98     boolean more;
99     Bucket tmp;
100     
101     do {
102       bucketTable.first = null;
103       
104       while (current != null) { // more queued
105

106         // check prohibited & required
107
if ((current.bits & prohibitedMask) == 0 &&
108             (current.bits & requiredMask) == requiredMask) {
109           
110           if (current.doc >= max){
111             tmp = current;
112             current = current.next;
113             tmp.next = bucketTable.first;
114             bucketTable.first = tmp;
115             continue;
116           }
117           
118           hc.collect(current.doc, current.score * coordFactors[current.coord]);
119         }
120         
121         current = current.next; // pop the queue
122
}
123       
124       if( bucketTable.first != null){
125         current = bucketTable.first;
126         bucketTable.first = current.next;
127         return true;
128       }
129
130       // refill the queue
131
more = false;
132       end += BucketTable.SIZE;
133       for (SubScorer sub = scorers; sub != null; sub = sub.next) {
134         if (!sub.done) {
135           sub.done = !sub.scorer.score(sub.collector, end);
136           if (!sub.done)
137             more = true;
138         }
139       }
140       current = bucketTable.first;
141       
142     } while (current != null || more);
143
144     return false;
145   }
146
147   public int doc() { return current.doc; }
148
149   public boolean next() throws IOException JavaDoc {
150     boolean more;
151     do {
152       while (bucketTable.first != null) { // more queued
153
current = bucketTable.first;
154         bucketTable.first = current.next; // pop the queue
155

156         // check prohibited & required
157
if ((current.bits & prohibitedMask) == 0 &&
158             (current.bits & requiredMask) == requiredMask) {
159           return true;
160         }
161       }
162
163       // refill the queue
164
more = false;
165       end += BucketTable.SIZE;
166       for (SubScorer sub = scorers; sub != null; sub = sub.next) {
167         Scorer scorer = sub.scorer;
168         while (!sub.done && scorer.doc() < end) {
169           sub.collector.collect(scorer.doc(), scorer.score());
170           sub.done = !scorer.next();
171         }
172         if (!sub.done) {
173           more = true;
174         }
175       }
176     } while (bucketTable.first != null || more);
177
178     return false;
179   }
180
181   public float score() {
182     if (coordFactors == null)
183       computeCoordFactors();
184     return current.score * coordFactors[current.coord];
185   }
186
187   static final class Bucket {
188     int doc = -1; // tells if bucket is valid
189
float score; // incremental score
190
int bits; // used for bool constraints
191
int coord; // count of terms in score
192
Bucket next; // next valid bucket
193
}
194
195   /** A simple hash table of document scores within a range. */
196   static final class BucketTable {
197     public static final int SIZE = 1 << 11;
198     public static final int MASK = SIZE - 1;
199
200     final Bucket[] buckets = new Bucket[SIZE];
201     Bucket first = null; // head of valid list
202

203     private BooleanScorer scorer;
204
205     public BucketTable(BooleanScorer scorer) {
206       this.scorer = scorer;
207     }
208
209     public final int size() { return SIZE; }
210
211     public HitCollector newCollector(int mask) {
212       return new Collector(mask, this);
213     }
214   }
215
216   static final class Collector extends HitCollector {
217     private BucketTable bucketTable;
218     private int mask;
219     public Collector(int mask, BucketTable bucketTable) {
220       this.mask = mask;
221       this.bucketTable = bucketTable;
222     }
223     public final void collect(final int doc, final float score) {
224       final BucketTable table = bucketTable;
225       final int i = doc & BucketTable.MASK;
226       Bucket bucket = table.buckets[i];
227       if (bucket == null)
228         table.buckets[i] = bucket = new Bucket();
229       
230       if (bucket.doc != doc) { // invalid bucket
231
bucket.doc = doc; // set doc
232
bucket.score = score; // initialize score
233
bucket.bits = mask; // initialize mask
234
bucket.coord = 1; // initialize coord
235

236         bucket.next = table.first; // push onto valid list
237
table.first = bucket;
238       } else { // valid bucket
239
bucket.score += score; // increment score
240
bucket.bits |= mask; // add bits in mask
241
bucket.coord++; // increment coord
242
}
243     }
244   }
245
246   public boolean skipTo(int target) {
247     throw new UnsupportedOperationException JavaDoc();
248   }
249
250   public Explanation explain(int doc) {
251     throw new UnsupportedOperationException JavaDoc();
252   }
253
254   public String JavaDoc toString() {
255     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
256     buffer.append("boolean(");
257     for (SubScorer sub = scorers; sub != null; sub = sub.next) {
258       buffer.append(sub.scorer.toString());
259       buffer.append(" ");
260     }
261     buffer.append(")");
262     return buffer.toString();
263   }
264
265
266 }
267
Popular Tags