pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.4.0 / lucene / src / java / org / apache / lucene / search / TopFieldCollector.java
diff --git a/lucene-java-3.4.0/lucene/src/java/org/apache/lucene/search/TopFieldCollector.java b/lucene-java-3.4.0/lucene/src/java/org/apache/lucene/search/TopFieldCollector.java
deleted file mode 100644 (file)
index 76f9b71..0000000
+++ /dev/null
@@ -1,999 +0,0 @@
-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 org.apache.lucene.index.IndexReader;
-import org.apache.lucene.search.FieldValueHitQueue.Entry;
-import org.apache.lucene.util.PriorityQueue;
-
-/**
- * A {@link Collector} that sorts by {@link SortField} using
- * {@link FieldComparator}s.
- * <p/>
- * See the {@link #create(org.apache.lucene.search.Sort, int, boolean, boolean, boolean, boolean)} method
- * for instantiating a TopFieldCollector.
- * 
- * @lucene.experimental
- */
-public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
-  
-  // TODO: one optimization we could do is to pre-fill
-  // the queue with sentinel value that guaranteed to
-  // always compare lower than a real hit; this would
-  // save having to check queueFull on each insert
-
-  /*
-   * Implements a TopFieldCollector over one SortField criteria, without
-   * tracking document scores and maxScore.
-   */
-  private static class OneComparatorNonScoringCollector extends 
-      TopFieldCollector {
-
-    final FieldComparator comparator;
-    final int reverseMul;
-    
-    public OneComparatorNonScoringCollector(FieldValueHitQueue<Entry> queue,
-        int numHits, boolean fillFields) throws IOException {
-      super(queue, numHits, fillFields);
-      comparator = queue.getComparators()[0];
-      reverseMul = queue.getReverseMul()[0];
-    }
-    
-    final void updateBottom(int doc) {
-      // bottom.score is already set to Float.NaN in add().
-      bottom.doc = docBase + doc;
-      bottom = pq.updateTop();
-    }
-
-    @Override
-    public void collect(int doc) throws IOException {
-      ++totalHits;
-      if (queueFull) {
-        if ((reverseMul * comparator.compareBottom(doc)) <= 0) {
-          // since docs are visited in doc Id order, if compare is 0, it means
-          // this document is largest than anything else in the queue, and
-          // therefore not competitive.
-          return;
-        }
-        
-        // This hit is competitive - replace bottom element in queue & adjustTop
-        comparator.copy(bottom.slot, doc);
-        updateBottom(doc);
-        comparator.setBottom(bottom.slot);
-      } else {
-        // Startup transient: queue hasn't gathered numHits yet
-        final int slot = totalHits - 1;
-        // Copy hit into queue
-        comparator.copy(slot, doc);
-        add(slot, doc, Float.NaN);
-        if (queueFull) {
-          comparator.setBottom(bottom.slot);
-        }
-      }
-    }
-    
-    @Override
-    public void setNextReader(IndexReader reader, int docBase) throws IOException {
-      this.docBase = docBase;
-      comparator.setNextReader(reader, docBase);
-    }
-    
-    @Override
-    public void setScorer(Scorer scorer) throws IOException {
-      comparator.setScorer(scorer);
-    }
-    
-  }
-
-  /*
-   * Implements a TopFieldCollector over one SortField criteria, without
-   * tracking document scores and maxScore, and assumes out of orderness in doc
-   * Ids collection.
-   */
-  private static class OutOfOrderOneComparatorNonScoringCollector extends
-      OneComparatorNonScoringCollector {
-
-    public OutOfOrderOneComparatorNonScoringCollector(FieldValueHitQueue<Entry> queue,
-        int numHits, boolean fillFields) throws IOException {
-      super(queue, numHits, fillFields);
-    }
-    
-    @Override
-    public void collect(int doc) throws IOException {
-      ++totalHits;
-      if (queueFull) {
-        // Fastmatch: return if this hit is not competitive
-        final int cmp = reverseMul * comparator.compareBottom(doc);
-        if (cmp < 0 || (cmp == 0 && doc + docBase > bottom.doc)) {
-          return;
-        }
-        
-        // This hit is competitive - replace bottom element in queue & adjustTop
-        comparator.copy(bottom.slot, doc);
-        updateBottom(doc);
-        comparator.setBottom(bottom.slot);
-      } else {
-        // Startup transient: queue hasn't gathered numHits yet
-        final int slot = totalHits - 1;
-        // Copy hit into queue
-        comparator.copy(slot, doc);
-        add(slot, doc, Float.NaN);
-        if (queueFull) {
-          comparator.setBottom(bottom.slot);
-        }
-      }
-    }
-    
-    @Override
-    public boolean acceptsDocsOutOfOrder() {
-      return true;
-    }
-
-  }
-
-  /*
-   * Implements a TopFieldCollector over one SortField criteria, while tracking
-   * document scores but no maxScore.
-   */
-  private static class OneComparatorScoringNoMaxScoreCollector extends
-      OneComparatorNonScoringCollector {
-
-    Scorer scorer;
-
-    public OneComparatorScoringNoMaxScoreCollector(FieldValueHitQueue<Entry> queue,
-        int numHits, boolean fillFields) throws IOException {
-      super(queue, numHits, fillFields);
-    }
-    
-    final void updateBottom(int doc, float score) {
-      bottom.doc = docBase + doc;
-      bottom.score = score;
-      bottom = pq.updateTop();
-    }
-
-    @Override
-    public void collect(int doc) throws IOException {
-      ++totalHits;
-      if (queueFull) {
-        if ((reverseMul * comparator.compareBottom(doc)) <= 0) {
-          // since docs are visited in doc Id order, if compare is 0, it means
-          // this document is largest than anything else in the queue, and
-          // therefore not competitive.
-          return;
-        }
-        
-        // Compute the score only if the hit is competitive.
-        final float score = scorer.score();
-
-        // This hit is competitive - replace bottom element in queue & adjustTop
-        comparator.copy(bottom.slot, doc);
-        updateBottom(doc, score);
-        comparator.setBottom(bottom.slot);
-      } else {
-        // Compute the score only if the hit is competitive.
-        final float score = scorer.score();
-
-        // Startup transient: queue hasn't gathered numHits yet
-        final int slot = totalHits - 1;
-        // Copy hit into queue
-        comparator.copy(slot, doc);
-        add(slot, doc, score);
-        if (queueFull) {
-          comparator.setBottom(bottom.slot);
-        }
-      }
-    }
-    
-    @Override
-    public void setScorer(Scorer scorer) throws IOException {
-      this.scorer = scorer;
-      comparator.setScorer(scorer);
-    }
-    
-  }
-
-  /*
-   * Implements a TopFieldCollector over one SortField criteria, while tracking
-   * document scores but no maxScore, and assumes out of orderness in doc Ids
-   * collection.
-   */
-  private static class OutOfOrderOneComparatorScoringNoMaxScoreCollector extends
-      OneComparatorScoringNoMaxScoreCollector {
-
-    public OutOfOrderOneComparatorScoringNoMaxScoreCollector(
-        FieldValueHitQueue<Entry> queue, int numHits, boolean fillFields)
-        throws IOException {
-      super(queue, numHits, fillFields);
-    }
-    
-    @Override
-    public void collect(int doc) throws IOException {
-      ++totalHits;
-      if (queueFull) {
-        // Fastmatch: return if this hit is not competitive
-        final int cmp = reverseMul * comparator.compareBottom(doc);
-        if (cmp < 0 || (cmp == 0 && doc + docBase > bottom.doc)) {
-          return;
-        }
-        
-        // Compute the score only if the hit is competitive.
-        final float score = scorer.score();
-
-        // This hit is competitive - replace bottom element in queue & adjustTop
-        comparator.copy(bottom.slot, doc);
-        updateBottom(doc, score);
-        comparator.setBottom(bottom.slot);
-      } else {
-        // Compute the score only if the hit is competitive.
-        final float score = scorer.score();
-
-        // Startup transient: queue hasn't gathered numHits yet
-        final int slot = totalHits - 1;
-        // Copy hit into queue
-        comparator.copy(slot, doc);
-        add(slot, doc, score);
-        if (queueFull) {
-          comparator.setBottom(bottom.slot);
-        }
-      }
-    }
-    
-    @Override
-    public boolean acceptsDocsOutOfOrder() {
-      return true;
-    }
-
-  }
-
-  /*
-   * Implements a TopFieldCollector over one SortField criteria, with tracking
-   * document scores and maxScore.
-   */
-  private static class OneComparatorScoringMaxScoreCollector extends
-      OneComparatorNonScoringCollector {
-
-    Scorer scorer;
-    
-    public OneComparatorScoringMaxScoreCollector(FieldValueHitQueue<Entry> queue,
-        int numHits, boolean fillFields) throws IOException {
-      super(queue, numHits, fillFields);
-      // Must set maxScore to NEG_INF, or otherwise Math.max always returns NaN.
-      maxScore = Float.NEGATIVE_INFINITY;
-    }
-    
-    final void updateBottom(int doc, float score) {
-      bottom.doc = docBase + doc;
-      bottom.score = score;
-      bottom =  pq.updateTop();
-    }
-
-    @Override
-    public void collect(int doc) throws IOException {
-      final float score = scorer.score();
-      if (score > maxScore) {
-        maxScore = score;
-      }
-      ++totalHits;
-      if (queueFull) {
-        if ((reverseMul * comparator.compareBottom(doc)) <= 0) {
-          // since docs are visited in doc Id order, if compare is 0, it means
-          // this document is largest than anything else in the queue, and
-          // therefore not competitive.
-          return;
-        }
-        
-        // This hit is competitive - replace bottom element in queue & adjustTop
-        comparator.copy(bottom.slot, doc);
-        updateBottom(doc, score);
-        comparator.setBottom(bottom.slot);
-      } else {
-        // Startup transient: queue hasn't gathered numHits yet
-        final int slot = totalHits - 1;
-        // Copy hit into queue
-        comparator.copy(slot, doc);
-        add(slot, doc, score);
-        if (queueFull) {
-          comparator.setBottom(bottom.slot);
-        }
-      }
-
-    }
-    
-    @Override
-    public void setScorer(Scorer scorer) throws IOException {
-      this.scorer = scorer;
-      super.setScorer(scorer);
-    }
-  }
-
-  /*
-   * Implements a TopFieldCollector over one SortField criteria, with tracking
-   * document scores and maxScore, and assumes out of orderness in doc Ids
-   * collection.
-   */
-  private static class OutOfOrderOneComparatorScoringMaxScoreCollector extends
-      OneComparatorScoringMaxScoreCollector {
-
-    public OutOfOrderOneComparatorScoringMaxScoreCollector(FieldValueHitQueue<Entry> queue,
-        int numHits, boolean fillFields) throws IOException {
-      super(queue, numHits, fillFields);
-    }
-    
-    @Override
-    public void collect(int doc) throws IOException {
-      final float score = scorer.score();
-      if (score > maxScore) {
-        maxScore = score;
-      }
-      ++totalHits;
-      if (queueFull) {
-        // Fastmatch: return if this hit is not competitive
-        final int cmp = reverseMul * comparator.compareBottom(doc);
-        if (cmp < 0 || (cmp == 0 && doc + docBase > bottom.doc)) {
-          return;
-        }
-        
-        // This hit is competitive - replace bottom element in queue & adjustTop
-        comparator.copy(bottom.slot, doc);
-        updateBottom(doc, score);
-        comparator.setBottom(bottom.slot);
-      } else {
-        // Startup transient: queue hasn't gathered numHits yet
-        final int slot = totalHits - 1;
-        // Copy hit into queue
-        comparator.copy(slot, doc);
-        add(slot, doc, score);
-        if (queueFull) {
-          comparator.setBottom(bottom.slot);
-        }
-      }
-    }
-    
-    @Override
-    public boolean acceptsDocsOutOfOrder() {
-      return true;
-    }
-
-  }
-
-  /*
-   * Implements a TopFieldCollector over multiple SortField criteria, without
-   * tracking document scores and maxScore.
-   */
-  private static class MultiComparatorNonScoringCollector extends TopFieldCollector {
-    
-    final FieldComparator[] comparators;
-    final int[] reverseMul;
-
-    public MultiComparatorNonScoringCollector(FieldValueHitQueue<Entry> queue,
-        int numHits, boolean fillFields) throws IOException {
-      super(queue, numHits, fillFields);
-      comparators = queue.getComparators();
-      reverseMul = queue.getReverseMul();
-    }
-    
-    final void updateBottom(int doc) {
-      // bottom.score is already set to Float.NaN in add().
-      bottom.doc = docBase + doc;
-      bottom = pq.updateTop();
-    }
-
-    @Override
-    public void collect(int doc) throws IOException {
-      ++totalHits;
-      if (queueFull) {
-        // Fastmatch: return if this hit is not competitive
-        for (int i = 0;; i++) {
-          final int c = reverseMul[i] * comparators[i].compareBottom(doc);
-          if (c < 0) {
-            // Definitely not competitive.
-            return;
-          } else if (c > 0) {
-            // Definitely competitive.
-            break;
-          } else if (i == comparators.length - 1) {
-            // Here c=0. If we're at the last comparator, this doc is not
-            // competitive, since docs are visited in doc Id order, which means
-            // this doc cannot compete with any other document in the queue.
-            return;
-          }
-        }
-
-        // This hit is competitive - replace bottom element in queue & adjustTop
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].copy(bottom.slot, doc);
-        }
-
-        updateBottom(doc);
-
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].setBottom(bottom.slot);
-        }
-      } else {
-        // Startup transient: queue hasn't gathered numHits yet
-        final int slot = totalHits - 1;
-        // Copy hit into queue
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].copy(slot, doc);
-        }
-        add(slot, doc, Float.NaN);
-        if (queueFull) {
-          for (int i = 0; i < comparators.length; i++) {
-            comparators[i].setBottom(bottom.slot);
-          }
-        }
-      }
-    }
-
-    @Override
-    public void setNextReader(IndexReader reader, int docBase) throws IOException {
-      this.docBase = docBase;
-      for (int i = 0; i < comparators.length; i++) {
-        comparators[i].setNextReader(reader, docBase);
-      }
-    }
-
-    @Override
-    public void setScorer(Scorer scorer) throws IOException {
-      // set the scorer on all comparators
-      for (int i = 0; i < comparators.length; i++) {
-        comparators[i].setScorer(scorer);
-      }
-    }
-  }
-  
-  /*
-   * Implements a TopFieldCollector over multiple SortField criteria, without
-   * tracking document scores and maxScore, and assumes out of orderness in doc
-   * Ids collection.
-   */
-  private static class OutOfOrderMultiComparatorNonScoringCollector extends
-      MultiComparatorNonScoringCollector {
-    
-    public OutOfOrderMultiComparatorNonScoringCollector(FieldValueHitQueue<Entry> queue,
-        int numHits, boolean fillFields) throws IOException {
-      super(queue, numHits, fillFields);
-    }
-    
-    @Override
-    public void collect(int doc) throws IOException {
-      ++totalHits;
-      if (queueFull) {
-        // Fastmatch: return if this hit is not competitive
-        for (int i = 0;; i++) {
-          final int c = reverseMul[i] * comparators[i].compareBottom(doc);
-          if (c < 0) {
-            // Definitely not competitive.
-            return;
-          } else if (c > 0) {
-            // Definitely competitive.
-            break;
-          } else if (i == comparators.length - 1) {
-            // This is the equals case.
-            if (doc + docBase > bottom.doc) {
-              // Definitely not competitive
-              return;
-            }
-            break;
-          }
-        }
-
-        // This hit is competitive - replace bottom element in queue & adjustTop
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].copy(bottom.slot, doc);
-        }
-
-        updateBottom(doc);
-
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].setBottom(bottom.slot);
-        }
-      } else {
-        // Startup transient: queue hasn't gathered numHits yet
-        final int slot = totalHits - 1;
-        // Copy hit into queue
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].copy(slot, doc);
-        }
-        add(slot, doc, Float.NaN);
-        if (queueFull) {
-          for (int i = 0; i < comparators.length; i++) {
-            comparators[i].setBottom(bottom.slot);
-          }
-        }
-      }
-    }
-    
-    @Override
-    public boolean acceptsDocsOutOfOrder() {
-      return true;
-    }
-
-  }
-
-  /*
-   * Implements a TopFieldCollector over multiple SortField criteria, with
-   * tracking document scores and maxScore.
-   */
-  private static class MultiComparatorScoringMaxScoreCollector extends MultiComparatorNonScoringCollector {
-    
-    Scorer scorer;
-    
-    public MultiComparatorScoringMaxScoreCollector(FieldValueHitQueue<Entry> queue,
-        int numHits, boolean fillFields) throws IOException {
-      super(queue, numHits, fillFields);
-      // Must set maxScore to NEG_INF, or otherwise Math.max always returns NaN.
-      maxScore = Float.NEGATIVE_INFINITY;
-    }
-    
-    final void updateBottom(int doc, float score) {
-      bottom.doc = docBase + doc;
-      bottom.score = score;
-      bottom =  pq.updateTop();
-    }
-
-    @Override
-    public void collect(int doc) throws IOException {
-      final float score = scorer.score();
-      if (score > maxScore) {
-        maxScore = score;
-      }
-      ++totalHits;
-      if (queueFull) {
-        // Fastmatch: return if this hit is not competitive
-        for (int i = 0;; i++) {
-          final int c = reverseMul[i] * comparators[i].compareBottom(doc);
-          if (c < 0) {
-            // Definitely not competitive.
-            return;
-          } else if (c > 0) {
-            // Definitely competitive.
-            break;
-          } else if (i == comparators.length - 1) {
-            // Here c=0. If we're at the last comparator, this doc is not
-            // competitive, since docs are visited in doc Id order, which means
-            // this doc cannot compete with any other document in the queue.
-            return;
-          }
-        }
-
-        // This hit is competitive - replace bottom element in queue & adjustTop
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].copy(bottom.slot, doc);
-        }
-
-        updateBottom(doc, score);
-
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].setBottom(bottom.slot);
-        }
-      } else {
-        // Startup transient: queue hasn't gathered numHits yet
-        final int slot = totalHits - 1;
-        // Copy hit into queue
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].copy(slot, doc);
-        }
-        add(slot, doc, score);
-        if (queueFull) {
-          for (int i = 0; i < comparators.length; i++) {
-            comparators[i].setBottom(bottom.slot);
-          }
-        }
-      }
-    }
-
-    @Override
-    public void setScorer(Scorer scorer) throws IOException {
-      this.scorer = scorer;
-      super.setScorer(scorer);
-    }
-  }
-
-  /*
-   * Implements a TopFieldCollector over multiple SortField criteria, with
-   * tracking document scores and maxScore, and assumes out of orderness in doc
-   * Ids collection.
-   */
-  private final static class OutOfOrderMultiComparatorScoringMaxScoreCollector
-      extends MultiComparatorScoringMaxScoreCollector {
-    
-    public OutOfOrderMultiComparatorScoringMaxScoreCollector(FieldValueHitQueue<Entry> queue,
-        int numHits, boolean fillFields) throws IOException {
-      super(queue, numHits, fillFields);
-    }
-    
-    @Override
-    public void collect(int doc) throws IOException {
-      final float score = scorer.score();
-      if (score > maxScore) {
-        maxScore = score;
-      }
-      ++totalHits;
-      if (queueFull) {
-        // Fastmatch: return if this hit is not competitive
-        for (int i = 0;; i++) {
-          final int c = reverseMul[i] * comparators[i].compareBottom(doc);
-          if (c < 0) {
-            // Definitely not competitive.
-            return;
-          } else if (c > 0) {
-            // Definitely competitive.
-            break;
-          } else if (i == comparators.length - 1) {
-            // This is the equals case.
-            if (doc + docBase > bottom.doc) {
-              // Definitely not competitive
-              return;
-            }
-            break;
-          }
-        }
-
-        // This hit is competitive - replace bottom element in queue & adjustTop
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].copy(bottom.slot, doc);
-        }
-
-        updateBottom(doc, score);
-
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].setBottom(bottom.slot);
-        }
-      } else {
-        // Startup transient: queue hasn't gathered numHits yet
-        final int slot = totalHits - 1;
-        // Copy hit into queue
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].copy(slot, doc);
-        }
-        add(slot, doc, score);
-        if (queueFull) {
-          for (int i = 0; i < comparators.length; i++) {
-            comparators[i].setBottom(bottom.slot);
-          }
-        }
-      }
-    }
-    
-    @Override
-    public boolean acceptsDocsOutOfOrder() {
-      return true;
-    }
-
-  }
-
-  /*
-   * Implements a TopFieldCollector over multiple SortField criteria, with
-   * tracking document scores and maxScore.
-   */
-  private static class MultiComparatorScoringNoMaxScoreCollector extends MultiComparatorNonScoringCollector {
-    
-    Scorer scorer;
-    
-    public MultiComparatorScoringNoMaxScoreCollector(FieldValueHitQueue<Entry> queue,
-        int numHits, boolean fillFields) throws IOException {
-      super(queue, numHits, fillFields);
-    }
-    
-    final void updateBottom(int doc, float score) {
-      bottom.doc = docBase + doc;
-      bottom.score = score;
-      bottom = pq.updateTop();
-    }
-
-    @Override
-    public void collect(int doc) throws IOException {
-      ++totalHits;
-      if (queueFull) {
-        // Fastmatch: return if this hit is not competitive
-        for (int i = 0;; i++) {
-          final int c = reverseMul[i] * comparators[i].compareBottom(doc);
-          if (c < 0) {
-            // Definitely not competitive.
-            return;
-          } else if (c > 0) {
-            // Definitely competitive.
-            break;
-          } else if (i == comparators.length - 1) {
-            // Here c=0. If we're at the last comparator, this doc is not
-            // competitive, since docs are visited in doc Id order, which means
-            // this doc cannot compete with any other document in the queue.
-            return;
-          }
-        }
-
-        // This hit is competitive - replace bottom element in queue & adjustTop
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].copy(bottom.slot, doc);
-        }
-
-        // Compute score only if it is competitive.
-        final float score = scorer.score();
-        updateBottom(doc, score);
-
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].setBottom(bottom.slot);
-        }
-      } else {
-        // Startup transient: queue hasn't gathered numHits yet
-        final int slot = totalHits - 1;
-        // Copy hit into queue
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].copy(slot, doc);
-        }
-
-        // Compute score only if it is competitive.
-        final float score = scorer.score();
-        add(slot, doc, score);
-        if (queueFull) {
-          for (int i = 0; i < comparators.length; i++) {
-            comparators[i].setBottom(bottom.slot);
-          }
-        }
-      }
-    }
-
-    @Override
-    public void setScorer(Scorer scorer) throws IOException {
-      this.scorer = scorer;
-      super.setScorer(scorer);
-    }
-  }
-
-  /*
-   * Implements a TopFieldCollector over multiple SortField criteria, with
-   * tracking document scores and maxScore, and assumes out of orderness in doc
-   * Ids collection.
-   */
-  private final static class OutOfOrderMultiComparatorScoringNoMaxScoreCollector
-      extends MultiComparatorScoringNoMaxScoreCollector {
-    
-    public OutOfOrderMultiComparatorScoringNoMaxScoreCollector(
-        FieldValueHitQueue<Entry> queue, int numHits, boolean fillFields)
-        throws IOException {
-      super(queue, numHits, fillFields);
-    }
-    
-    @Override
-    public void collect(int doc) throws IOException {
-      ++totalHits;
-      if (queueFull) {
-        // Fastmatch: return if this hit is not competitive
-        for (int i = 0;; i++) {
-          final int c = reverseMul[i] * comparators[i].compareBottom(doc);
-          if (c < 0) {
-            // Definitely not competitive.
-            return;
-          } else if (c > 0) {
-            // Definitely competitive.
-            break;
-          } else if (i == comparators.length - 1) {
-            // This is the equals case.
-            if (doc + docBase > bottom.doc) {
-              // Definitely not competitive
-              return;
-            }
-            break;
-          }
-        }
-
-        // This hit is competitive - replace bottom element in queue & adjustTop
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].copy(bottom.slot, doc);
-        }
-
-        // Compute score only if it is competitive.
-        final float score = scorer.score();
-        updateBottom(doc, score);
-
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].setBottom(bottom.slot);
-        }
-      } else {
-        // Startup transient: queue hasn't gathered numHits yet
-        final int slot = totalHits - 1;
-        // Copy hit into queue
-        for (int i = 0; i < comparators.length; i++) {
-          comparators[i].copy(slot, doc);
-        }
-
-        // Compute score only if it is competitive.
-        final float score = scorer.score();
-        add(slot, doc, score);
-        if (queueFull) {
-          for (int i = 0; i < comparators.length; i++) {
-            comparators[i].setBottom(bottom.slot);
-          }
-        }
-      }
-    }
-
-    @Override
-    public void setScorer(Scorer scorer) throws IOException {
-      this.scorer = scorer;
-      super.setScorer(scorer);
-    }
-    
-    @Override
-    public boolean acceptsDocsOutOfOrder() {
-      return true;
-    }
-
-  }
-
-  private static final ScoreDoc[] EMPTY_SCOREDOCS = new ScoreDoc[0];
-  
-  private final boolean fillFields;
-
-  /*
-   * Stores the maximum score value encountered, needed for normalizing. If
-   * document scores are not tracked, this value is initialized to NaN.
-   */
-  float maxScore = Float.NaN;
-
-  final int numHits;
-  FieldValueHitQueue.Entry bottom = null;
-  boolean queueFull;
-  int docBase;
-  
-  // Declaring the constructor private prevents extending this class by anyone
-  // else. Note that the class cannot be final since it's extended by the
-  // internal versions. If someone will define a constructor with any other
-  // visibility, then anyone will be able to extend the class, which is not what
-  // we want.
-  private TopFieldCollector(PriorityQueue<Entry> pq, int numHits, boolean fillFields) {
-    super(pq);
-    this.numHits = numHits;
-    this.fillFields = fillFields;
-  }
-
-  /**
-   * Creates a new {@link TopFieldCollector} from the given
-   * arguments.
-   *
-   * <p><b>NOTE</b>: The instances returned by this method
-   * pre-allocate a full array of length
-   * <code>numHits</code>.
-   * 
-   * @param sort
-   *          the sort criteria (SortFields).
-   * @param numHits
-   *          the number of results to collect.
-   * @param fillFields
-   *          specifies whether the actual field values should be returned on
-   *          the results (FieldDoc).
-   * @param trackDocScores
-   *          specifies whether document scores should be tracked and set on the
-   *          results. Note that if set to false, then the results' scores will
-   *          be set to Float.NaN. Setting this to true affects performance, as
-   *          it incurs the score computation on each competitive result.
-   *          Therefore if document scores are not required by the application,
-   *          it is recommended to set it to false.
-   * @param trackMaxScore
-   *          specifies whether the query's maxScore should be tracked and set
-   *          on the resulting {@link TopDocs}. Note that if set to false,
-   *          {@link TopDocs#getMaxScore()} returns Float.NaN. Setting this to
-   *          true affects performance as it incurs the score computation on
-   *          each result. Also, setting this true automatically sets
-   *          <code>trackDocScores</code> to true as well.
-   * @param docsScoredInOrder
-   *          specifies whether documents are scored in doc Id order or not by
-   *          the given {@link Scorer} in {@link #setScorer(Scorer)}.
-   * @return a {@link TopFieldCollector} instance which will sort the results by
-   *         the sort criteria.
-   * @throws IOException
-   */
-  public static TopFieldCollector create(Sort sort, int numHits,
-      boolean fillFields, boolean trackDocScores, boolean trackMaxScore,
-      boolean docsScoredInOrder)
-      throws IOException {
-    if (sort.fields.length == 0) {
-      throw new IllegalArgumentException("Sort must contain at least one field");
-    }
-    
-    if (numHits <= 0) {
-      throw new IllegalArgumentException("numHits must be > 0; please use TotalHitCountCollector if you just need the total hit count");
-    }
-
-    FieldValueHitQueue<Entry> queue = FieldValueHitQueue.create(sort.fields, numHits);
-    if (queue.getComparators().length == 1) {
-      if (docsScoredInOrder) {
-        if (trackMaxScore) {
-          return new OneComparatorScoringMaxScoreCollector(queue, numHits, fillFields);
-        } else if (trackDocScores) {
-          return new OneComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields);
-        } else {
-          return new OneComparatorNonScoringCollector(queue, numHits, fillFields);
-        }
-      } else {
-        if (trackMaxScore) {
-          return new OutOfOrderOneComparatorScoringMaxScoreCollector(queue, numHits, fillFields);
-        } else if (trackDocScores) {
-          return new OutOfOrderOneComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields);
-        } else {
-          return new OutOfOrderOneComparatorNonScoringCollector(queue, numHits, fillFields);
-        }
-      }
-    }
-
-    // multiple comparators.
-    if (docsScoredInOrder) {
-      if (trackMaxScore) {
-        return new MultiComparatorScoringMaxScoreCollector(queue, numHits, fillFields);
-      } else if (trackDocScores) {
-        return new MultiComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields);
-      } else {
-        return new MultiComparatorNonScoringCollector(queue, numHits, fillFields);
-      }
-    } else {
-      if (trackMaxScore) {
-        return new OutOfOrderMultiComparatorScoringMaxScoreCollector(queue, numHits, fillFields);
-      } else if (trackDocScores) {
-        return new OutOfOrderMultiComparatorScoringNoMaxScoreCollector(queue, numHits, fillFields);
-      } else {
-        return new OutOfOrderMultiComparatorNonScoringCollector(queue, numHits, fillFields);
-      }
-    }
-  }
-  
-  final void add(int slot, int doc, float score) {
-    bottom = pq.add(new Entry(slot, docBase + doc, score));
-    queueFull = totalHits == numHits;
-  }
-
-  /*
-   * Only the following callback methods need to be overridden since
-   * topDocs(int, int) calls them to return the results.
-   */
-
-  @Override
-  protected void populateResults(ScoreDoc[] results, int howMany) {
-    if (fillFields) {
-      // avoid casting if unnecessary.
-      FieldValueHitQueue<Entry> queue = (FieldValueHitQueue<Entry>) pq;
-      for (int i = howMany - 1; i >= 0; i--) {
-        results[i] = queue.fillFields(queue.pop());
-      }
-    } else {
-      for (int i = howMany - 1; i >= 0; i--) {
-        Entry entry = pq.pop();
-        results[i] = new FieldDoc(entry.doc, entry.score);
-      }
-    }
-  }
-  
-  @Override
-  protected TopDocs newTopDocs(ScoreDoc[] results, int start) {
-    if (results == null) {
-      results = EMPTY_SCOREDOCS;
-      // Set maxScore to NaN, in case this is a maxScore tracking collector.
-      maxScore = Float.NaN;
-    }
-
-    // If this is a maxScoring tracking collector and there were no results, 
-    return new TopFieldDocs(totalHits, results, ((FieldValueHitQueue<Entry>) pq).getFields(), maxScore);
-  }
-  
-  @Override
-  public boolean acceptsDocsOutOfOrder() {
-    return false;
-  }
-}