Пример #1
0
 private BulkScorerAndDoc advance(int min) throws IOException {
   assert tail.size() == minShouldMatch - 1;
   final HeadPriorityQueue head = this.head;
   final TailPriorityQueue tail = this.tail;
   BulkScorerAndDoc headTop = head.top();
   BulkScorerAndDoc tailTop = tail.top();
   while (headTop.next < min) {
     if (tailTop == null || headTop.cost <= tailTop.cost) {
       headTop.advance(min);
       headTop = head.updateTop();
     } else {
       // swap the top of head and tail
       final BulkScorerAndDoc previousHeadTop = headTop;
       tailTop.advance(min);
       headTop = head.updateTop(tailTop);
       tailTop = tail.updateTop(previousHeadTop);
     }
   }
   return headTop;
 }
Пример #2
0
  private void scoreWindowSingleScorer(
      BulkScorerAndDoc bulkScorer,
      LeafCollector collector,
      Bits acceptDocs,
      int windowMin,
      int windowMax,
      int max)
      throws IOException {
    assert tail.size() == 0;
    final int nextWindowBase = head.top().next & ~MASK;
    final int end = Math.max(windowMax, Math.min(max, nextWindowBase));

    bulkScorer.score(collector, acceptDocs, windowMin, end);

    // reset the scorer that should be used for the general case
    collector.setScorer(fakeScorer);
  }
Пример #3
0
  BooleanScorer(
      BooleanWeight weight,
      boolean disableCoord,
      int maxCoord,
      Collection<BulkScorer> scorers,
      int minShouldMatch,
      boolean needsScores) {
    if (minShouldMatch < 1 || minShouldMatch > scorers.size()) {
      throw new IllegalArgumentException(
          "minShouldMatch should be within 1..num_scorers. Got " + minShouldMatch);
    }
    if (scorers.size() <= 1) {
      throw new IllegalArgumentException(
          "This scorer can only be used with two scorers or more, got " + scorers.size());
    }
    for (int i = 0; i < buckets.length; i++) {
      buckets[i] = new Bucket();
    }
    this.leads = new BulkScorerAndDoc[scorers.size()];
    this.head = new HeadPriorityQueue(scorers.size() - minShouldMatch + 1);
    this.tail = new TailPriorityQueue(minShouldMatch - 1);
    this.minShouldMatch = minShouldMatch;
    for (BulkScorer scorer : scorers) {
      if (needsScores == false) {
        // OrCollector calls score() all the time so we have to explicitly
        // disable scoring in order to avoid decoding useless norms
        scorer = BooleanWeight.disableScoring(scorer);
      }
      final BulkScorerAndDoc evicted = tail.insertWithOverflow(new BulkScorerAndDoc(scorer));
      if (evicted != null) {
        head.add(evicted);
      }
    }
    this.cost = cost(scorers, minShouldMatch);

    coordFactors = new float[scorers.size() + 1];
    for (int i = 0; i < coordFactors.length; i++) {
      coordFactors[i] = disableCoord ? 1.0f : weight.coord(i, maxCoord);
    }
  }
Пример #4
0
  private void scoreWindowMultipleScorers(
      LeafCollector collector,
      Bits acceptDocs,
      int windowBase,
      int windowMin,
      int windowMax,
      int maxFreq)
      throws IOException {
    while (maxFreq < minShouldMatch && maxFreq + tail.size() >= minShouldMatch) {
      // a match is still possible
      final BulkScorerAndDoc candidate = tail.pop();
      candidate.advance(windowMin);
      if (candidate.next < windowMax) {
        leads[maxFreq++] = candidate;
      } else {
        head.add(candidate);
      }
    }

    if (maxFreq >= minShouldMatch) {
      // There might be matches in other scorers from the tail too
      for (int i = 0; i < tail.size(); ++i) {
        leads[maxFreq++] = tail.get(i);
      }
      tail.clear();

      scoreWindowIntoBitSetAndReplay(
          collector, acceptDocs, windowBase, windowMin, windowMax, leads, maxFreq);
    }

    // Push back scorers into head and tail
    for (int i = 0; i < maxFreq; ++i) {
      final BulkScorerAndDoc evicted = head.insertWithOverflow(leads[i]);
      if (evicted != null) {
        tail.add(evicted);
      }
    }
  }