ConjunctionScorer.java
001 package gate.creole.annic.apache.lucene.search;
002 
003 /**
004  * Copyright 2004 The Apache Software Foundation
005  *
006  * Licensed under the Apache License, Version 2.0 (the "License");
007  * you may not use this file except in compliance with the License.
008  * You may obtain a copy of the License at
009  *
010  *     http://www.apache.org/licenses/LICENSE-2.0
011  *
012  * Unless required by applicable law or agreed to in writing, software
013  * distributed under the License is distributed on an "AS IS" BASIS,
014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015  * See the License for the specific language governing permissions and
016  * limitations under the License.
017  */
018 
019 import java.io.IOException;
020 import java.util.*;
021 
022 /** Scorer for conjunctions, sets of queries, all of which are required. */
023 final class ConjunctionScorer extends Scorer {
024   private LinkedList scorers = new LinkedList();
025   private boolean firstTime = true;
026   private boolean more = true;
027   private float coord;
028 
029   public ConjunctionScorer(Similarity similarity) {
030     super(similarity);
031   }
032 
033   final void add(Scorer scorerthrows IOException {
034     scorers.addLast(scorer);
035   }
036 
037   private Scorer first() { return (Scorer)scorers.getFirst()}
038   private Scorer last() { return (Scorer)scorers.getLast()}
039 
040   public int doc() { return first().doc()}
041 
042   public boolean next(Searcher searcherthrows IOException {
043     this.searcher = searcher;
044     if (firstTime) {
045       init();
046     else if (more) {
047       more = last().next(this.searcher);                       // trigger further scanning
048     }
049     return doNext();
050   }
051 
052   private boolean doNext() throws IOException {
053     while (more && first().doc() < last().doc()) { // find doc w/ all clauses
054       more = first().skipTo(last().doc());      // skip first upto last
055       scorers.addLast(scorers.removeFirst());   // move first to last
056     }
057     return more;                                // found a doc with all clauses
058   }
059 
060   public boolean skipTo(int targetthrows IOException {
061     Iterator i = scorers.iterator();
062     while (more && i.hasNext()) {
063       more = ((Scorer)i.next()).skipTo(target);
064     }
065     if (more)
066       sortScorers();                              // re-sort scorers
067     return doNext();
068   }
069   
070   public float score(Searcher searcherthrows IOException {
071     this.searcher = searcher;
072     float score = 0.0f;                           // sum scores
073     Iterator i = scorers.iterator();
074     while (i.hasNext())
075       score += ((Scorer)i.next()).score(this.searcher);
076     score *= coord;
077     return score;
078   }
079 
080   private void init() throws IOException {
081     more = scorers.size() 0;
082 
083     // compute coord factor
084     coord = getSimilarity().coord(scorers.size(), scorers.size());
085 
086     // move each scorer to its first entry
087     Iterator i = scorers.iterator();
088     while (more && i.hasNext()) {
089       more = ((Scorer)i.next()).next(this.searcher);
090     }
091     if (more)
092       sortScorers();                              // initial sort of list
093 
094     firstTime = false;
095   }
096 
097   private void sortScorers() throws IOException {
098     // move scorers to an array
099     Scorer[] array = (Scorer[])scorers.toArray(new Scorer[scorers.size()]);
100     scorers.clear();                              // empty the list
101 
102     // note that this comparator is not consistent with equals!
103     Arrays.sort(array, new Comparator() {         // sort the array
104         public int compare(Object o1, Object o2) {
105           return ((Scorer)o1).doc() ((Scorer)o2).doc();
106         }
107         public boolean equals(Object o1, Object o2) {
108           return ((Scorer)o1).doc() == ((Scorer)o2).doc();
109         }
110       });
111 
112     for (int i = 0; i < array.length; i++) {
113       scorers.addLast(array[i]);                  // re-build list, now sorted
114     }
115   }
116 
117   public Explanation explain(int docthrows IOException {
118     throw new UnsupportedOperationException();
119   }
120 
121 }