FileDocCategorySizeDatePackage
ConjunctionScorer.javaAPI DocApache Lucene 2.1.04045Wed Feb 14 10:46:40 GMT 2007org.apache.lucene.search

ConjunctionScorer.java

package org.apache.lucene.search;

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;

/** Scorer for conjunctions, sets of queries, all of which are required. */
class ConjunctionScorer extends Scorer {
  private Scorer[] scorers = new Scorer[2];
  private int length = 0;
  private int first = 0;
  private int last = -1;
  private boolean firstTime = true;
  private boolean more = true;
  private float coord;

  public ConjunctionScorer(Similarity similarity) {
    super(similarity);
  }

  final void add(Scorer scorer) {
    if (length >= scorers.length) {
      // grow the array
      Scorer[] temps = new Scorer[scorers.length * 2];
      System.arraycopy(scorers, 0, temps, 0, length);
      scorers = temps;
    }
    last += 1;
    length += 1;
    scorers[last] = scorer;
  }

  public int doc() { return scorers[first].doc(); }

  public boolean next() throws IOException {
    if (firstTime) {
      init(true);
    } else if (more) {
      more = scorers[last].next();                   // trigger further scanning
    }
    return doNext();
  }
  
  private boolean doNext() throws IOException {
    while (more && scorers[first].doc() < scorers[last].doc()) { // find doc w/ all clauses
      more = scorers[first].skipTo(scorers[last].doc());      // skip first upto last
      last = first; // move first to last
      first = (first == length-1) ? 0 : first+1;
    }
    return more;                                // found a doc with all clauses
  }

  public boolean skipTo(int target) throws IOException {
    if(firstTime) {
      init(false);
    }
    
    for (int i = 0, pos = first; i < length; i++) {
      if (!more) break; 
      more = scorers[pos].skipTo(target);
      pos = (pos == length-1) ? 0 : pos+1;
    }
    
    if (more)
      sortScorers();                              // re-sort scorers
    
    return doNext();
  }

  public float score() throws IOException {
    float sum = 0.0f;
    for (int i = 0; i < length; i++) {
      sum += scorers[i].score();
    }
    return sum * coord;
  }
  
  private void init(boolean initScorers) throws IOException {
    //  compute coord factor
    coord = getSimilarity().coord(length, length);
   
    more = length > 0;

    if(initScorers){
      // move each scorer to its first entry
      for (int i = 0, pos = first; i < length; i++) {
        if (!more) break; 
        more = scorers[pos].next();
        pos = (pos == length-1) ? 0 : pos+1;
      }
      // initial sort of simulated list
      if (more) 
        sortScorers();
    }

    firstTime = false;
  }

  private void sortScorers() {
    // squeeze the array down for the sort
    if (length != scorers.length) {
      Scorer[] temps = new Scorer[length];
      System.arraycopy(scorers, 0, temps, 0, length);
      scorers = temps;
    }
    
    // note that this comparator is not consistent with equals!
    Arrays.sort(scorers, new Comparator() {         // sort the array
        public int compare(Object o1, Object o2) {
          return ((Scorer)o1).doc() - ((Scorer)o2).doc();
        }
      });
   
    first = 0;
    last = length - 1;
  }

  public Explanation explain(int doc) {
    throw new UnsupportedOperationException();
  }

}