Index: lucene/contrib/queries/src/java/org/apache/lucene/search/SlowCollatedStringComparator.java
--- lucene/contrib/queries/src/java/org/apache/lucene/search/SlowCollatedStringComparator.java Thu Jun 09 13:10:14 2011 -0400
+++ lucene/contrib/queries/src/java/org/apache/lucene/search/SlowCollatedStringComparator.java Fri Jun 10 15:48:44 2011 -0400
@@ -103,4 +103,18 @@
final String s = values[slot];
return s == null ? null : new BytesRef(values[slot]);
}
+
+ @Override
+ public int compare(Comparable first, Comparable second) {
+ if (first == null) {
+ if (second == null) {
+ return 0;
+ }
+ return -1;
+ } else if (second == null) {
+ return 1;
+ } else {
+ return collator.compare((BytesRef) first, (BytesRef) second);
+ }
+ }
}
Index: lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceFieldComparatorSource.java
--- lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceFieldComparatorSource.java Thu Jun 09 13:10:14 2011 -0400
+++ lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceFieldComparatorSource.java Fri Jun 10 15:48:44 2011 -0400
@@ -31,94 +31,104 @@
*/
public class DistanceFieldComparatorSource extends FieldComparatorSource {
- private DistanceFilter distanceFilter;
- private DistanceScoreDocLookupComparator dsdlc;
+ private DistanceFilter distanceFilter;
+ private DistanceScoreDocLookupComparator dsdlc;
- public DistanceFieldComparatorSource(Filter distanceFilter) {
+ public DistanceFieldComparatorSource(Filter distanceFilter) {
+ this.distanceFilter = (DistanceFilter) distanceFilter;
+ }
- this.distanceFilter = (DistanceFilter) distanceFilter;
+ public void cleanUp() {
+ distanceFilter = null;
- }
+ if (dsdlc != null) {
+ dsdlc.cleanUp();
+ }
- public void cleanUp() {
- distanceFilter = null;
+ dsdlc = null;
+ }
- if (dsdlc != null)
- dsdlc.cleanUp();
+ @Override
+ public FieldComparator newComparator(String fieldname, int numHits,
+ int sortPos, boolean reversed) throws IOException {
+ dsdlc = new DistanceScoreDocLookupComparator(numHits);
+ return dsdlc;
+ }
- dsdlc = null;
- }
+ private class DistanceScoreDocLookupComparator extends FieldComparator {
- @Override
- public FieldComparator newComparator(String fieldname, int numHits,
- int sortPos, boolean reversed) throws IOException {
- dsdlc = new DistanceScoreDocLookupComparator(numHits);
- return dsdlc;
- }
+ private double[] values;
+ private double bottom;
+ private int offset =0;
+
+ public DistanceScoreDocLookupComparator(int numHits) {
+ values = new double[numHits];
+ return;
+ }
- private class DistanceScoreDocLookupComparator extends FieldComparator {
+ @Override
+ public int compare(int slot1, int slot2) {
+ double a = values[slot1];
+ double b = values[slot2];
+ if (a > b)
+ return 1;
+ if (a < b)
+ return -1;
- private double[] values;
- private double bottom;
- private int offset =0;
-
- public DistanceScoreDocLookupComparator(int numHits) {
- values = new double[numHits];
- return;
- }
+ return 0;
+ }
- @Override
- public int compare(int slot1, int slot2) {
- double a = values[slot1];
- double b = values[slot2];
- if (a > b)
- return 1;
- if (a < b)
- return -1;
+ public void cleanUp() {
+ distanceFilter = null;
+ }
- return 0;
- }
+ @Override
+ public int compareBottom(int doc) {
+ double v2 = distanceFilter.getDistance(doc+ offset);
+
+ if (bottom > v2) {
+ return 1;
+ } else if (bottom < v2) {
+ return -1;
+ }
+ return 0;
+ }
- public void cleanUp() {
- distanceFilter = null;
- }
+ @Override
+ public void copy(int slot, int doc) {
+ values[slot] = distanceFilter.getDistance(doc + offset);
+ }
- @Override
- public int compareBottom(int doc) {
- double v2 = distanceFilter.getDistance(doc+ offset);
-
- if (bottom > v2) {
- return 1;
- } else if (bottom < v2) {
- return -1;
- }
- return 0;
- }
-
- @Override
- public void copy(int slot, int doc) {
- values[slot] = distanceFilter.getDistance(doc + offset);
- }
-
- @Override
- public void setBottom(int slot) {
- this.bottom = values[slot];
-
- }
+ @Override
+ public void setBottom(int slot) {
+ this.bottom = values[slot];
+ }
@Override
public FieldComparator setNextReader(AtomicReaderContext context)
- throws IOException {
+ throws IOException {
// each reader in a segmented base
// has an offset based on the maxDocs of previous readers
offset = context.docBase;
return this;
}
- @Override
- public Comparable
type is SCORE or DOC.
* @param type Type of values in the terms.
*/
- public SortField (String field, int type) {
+ public SortField(String field, int type) {
initFieldType(field, type);
}
@@ -113,7 +113,7 @@
* @param type Type of values in the terms.
* @param reverse True if natural order should be reversed.
*/
- public SortField (String field, int type, boolean reverse) {
+ public SortField(String field, int type, boolean reverse) {
initFieldType(field, type);
this.reverse = reverse;
}
@@ -131,7 +131,7 @@
* @deprecated (4.0) use EntryCreator version
*/
@Deprecated
- public SortField (String field, FieldCache.Parser parser) {
+ public SortField(String field, FieldCache.Parser parser) {
this(field, parser, false);
}
@@ -149,7 +149,7 @@
* @deprecated (4.0) use EntryCreator version
*/
@Deprecated
- public SortField (String field, FieldCache.Parser parser, boolean reverse) {
+ public SortField(String field, FieldCache.Parser parser, boolean reverse) {
if (field == null) {
throw new IllegalArgumentException("field can only be null when type is SCORE or DOC");
}
@@ -216,7 +216,7 @@
* @param field Name of field to sort by; cannot be null.
* @param comparator Returns a comparator for sorting hits.
*/
- public SortField (String field, FieldComparatorSource comparator) {
+ public SortField(String field, FieldComparatorSource comparator) {
initFieldType(field, CUSTOM);
this.comparatorSource = comparator;
}
@@ -226,7 +226,7 @@
* @param comparator Returns a comparator for sorting hits.
* @param reverse True if natural order should be reversed.
*/
- public SortField (String field, FieldComparatorSource comparator, boolean reverse) {
+ public SortField(String field, FieldComparatorSource comparator, boolean reverse) {
initFieldType(field, CUSTOM);
this.reverse = reverse;
this.comparatorSource = comparator;
Index: lucene/src/java/org/apache/lucene/search/TopDocs.java
--- lucene/src/java/org/apache/lucene/search/TopDocs.java Thu Jun 09 13:10:14 2011 -0400
+++ lucene/src/java/org/apache/lucene/search/TopDocs.java Fri Jun 10 15:48:44 2011 -0400
@@ -17,6 +17,10 @@
* limitations under the License.
*/
+import java.io.IOException;
+
+import org.apache.lucene.util.PriorityQueue;
+
/** Represents hits returned by {@link
* IndexSearcher#search(Query,Filter,int)} and {@link
* IndexSearcher#search(Query,int)}. */
@@ -52,4 +56,211 @@
this.scoreDocs = scoreDocs;
this.maxScore = maxScore;
}
+
+ // Refers to one hit:
+ private static class ShardRef {
+ // Which shard (index into shardHits[]):
+ final int shardIndex;
+
+ // Which hit within the shard:
+ int hitIndex;
+
+ public ShardRef(int shardIndex) {
+ this.shardIndex = shardIndex;
+ }
+
+ @Override
+ public String toString() {
+ return "ShardRef(shardIndex=" + shardIndex + " hitIndex=" + hitIndex + ")";
+ }
+ };
+
+ // Specialized MergeSortQueue that just merges by
+ // relevance score, descending:
+ private static class ScoreMergeSortQueue extends PriorityQueuehits.scoreDocs */
+ public final int[] shardIndex;
+
+ public TopDocsAndShards(TopDocs hits, int[] shardIndex) {
+ this.hits = hits;
+ this.shardIndex = shardIndex;
+ }
+ }
+
+ /** Returns a new TopDocs, containing topN results across
+ * the provided TopDocs, sorting by the specified {@link
+ * Sort}. Each of the TopDocs must have been sorted by
+ * the same Sort, and sort field values must have been
+ * filled (ie, fillFields=true must be
+ * passed to {@link
+ * TopFieldCollector#create}.
+ *
+ * Pass sort=null to merge sort by score descending.
+ *
+ * @lucene.experimental */
+ public static TopDocsAndShards merge(Sort sort, int topN, TopDocs[] shardHits) throws IOException {
+
+ final PriorityQueue