X-Git-Url: https://git.mdrn.pl/pylucene.git/blobdiff_plain/a2e61f0c04805cfcb8706176758d1283c7e3a55c..aaeed5504b982cf3545252ab528713250aa33eed:/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 index 76f9b71..0000000 --- a/lucene-java-3.4.0/lucene/src/java/org/apache/lucene/search/TopFieldCollector.java +++ /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. - *

- * 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 { - - // 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 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 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 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 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 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 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 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 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 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 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 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 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 pq, int numHits, boolean fillFields) { - super(pq); - this.numHits = numHits; - this.fillFields = fillFields; - } - - /** - * Creates a new {@link TopFieldCollector} from the given - * arguments. - * - *

NOTE: The instances returned by this method - * pre-allocate a full array of length - * numHits. - * - * @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 - * trackDocScores 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 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 queue = (FieldValueHitQueue) 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) pq).getFields(), maxScore); - } - - @Override - public boolean acceptsDocsOutOfOrder() { - return false; - } -}