LUCENE-3191: simplify API; return TopFieldDocs from TopDocs.merge if sort != null; add some missing compareValue to FC impls

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1136467 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2011-06-16 14:52:56 +00:00
parent 240822d45a
commit fe7593efee
8 changed files with 79 additions and 95 deletions

View File

@ -954,6 +954,19 @@ public abstract class FieldComparator<T> {
public BytesRef value(int slot) {
return TermOrdValComparator.this.value(slot);
}
@Override
public int compareValues(BytesRef val1, BytesRef val2) {
if (val1 == null) {
if (val2 == null) {
return 0;
}
return -1;
} else if (val2 == null) {
return 1;
}
return val1.compareTo(val2);
}
}
// Used per-segment when bit width of doc->ord is 8:
@ -1332,6 +1345,19 @@ public abstract class FieldComparator<T> {
public BytesRef value(int slot) {
return values[slot];
}
@Override
public int compareValues(BytesRef val1, BytesRef val2) {
if (val1 == null) {
if (val2 == null) {
return 0;
}
return -1;
} else if (val2 == null) {
return 1;
}
return val1.compareTo(val2);
}
}
final protected static int binarySearch(BytesRef br, DocTermsIndex a, BytesRef key) {

View File

@ -59,6 +59,12 @@ public class FieldDoc extends ScoreDoc {
this.fields = fields;
}
/** Expert: Creates one of these objects with the given sort information. */
public FieldDoc(int doc, float score, Object[] fields, int shardIndex) {
super (doc, score, shardIndex);
this.fields = fields;
}
// A convenience method for debugging.
@Override
public String toString() {

View File

@ -17,21 +17,30 @@ package org.apache.lucene.search;
* limitations under the License.
*/
/** Expert: Returned by low-level search implementations.
* @see TopDocs */
/** Holds one hit in {@link TopDocs}. */
public class ScoreDoc {
/** Expert: The score of this document for the query. */
/** The score of this document for the query. */
public float score;
/** Expert: A hit document's number.
* @see IndexSearcher#doc(int)
*/
/** A hit document's number.
* @see IndexSearcher#doc(int) */
public int doc;
/** Expert: Constructs a ScoreDoc. */
/** Only set by {@link TopDocs#merge} */
public int shardIndex;
/** Constructs a ScoreDoc. */
public ScoreDoc(int doc, float score) {
this(doc, score, -1);
}
/** Constructs a ScoreDoc. */
public ScoreDoc(int doc, float score, int shardIndex) {
this.doc = doc;
this.score = score;
this.shardIndex = shardIndex;
}
// A convenience method for debugging.
@ -39,5 +48,4 @@ public class ScoreDoc {
public String toString() {
return "doc=" + doc + " score=" + score;
}
}

View File

@ -25,11 +25,13 @@ import org.apache.lucene.util.PriorityQueue;
* IndexSearcher#search(Query,Filter,int)} and {@link
* IndexSearcher#search(Query,int)}. */
public class TopDocs {
/** The total number of hits for the query.
*/
/** The total number of hits for the query. */
public int totalHits;
/** The top hits for the query. */
public ScoreDoc[] scoreDocs;
/** Stores the maximum score value encountered, needed for normalizing. */
private float maxScore;
@ -189,22 +191,6 @@ public class TopDocs {
}
}
/** Returned from {@link #merge}, to include the merged
* TopDocs as well as the reference to which original
* TopDocs shard each hit came from.
*
* @lucene.experimental */
public static class TopDocsAndShards extends TopDocs {
/** Parallel array matching <code>hits.scoreDocs</code> */
public final int[] shardIndex;
public TopDocsAndShards(int totalHits, ScoreDoc[] scoreDocs, float maxScore, int[] shardIndex) {
super(totalHits, scoreDocs, maxScore);
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
@ -216,7 +202,7 @@ public class TopDocs {
* <p>Pass sort=null to merge sort by score descending.
*
* @lucene.experimental */
public static TopDocsAndShards merge(Sort sort, int topN, TopDocs[] shardHits) throws IOException {
public static TopDocs merge(Sort sort, int topN, TopDocs[] shardHits) throws IOException {
final PriorityQueue<ShardRef> queue;
if (sort == null) {
@ -238,14 +224,17 @@ public class TopDocs {
}
final ScoreDoc[] hits = new ScoreDoc[Math.min(topN, totalHitCount)];
final int[] shardIndex = new int[hits.length];
int hitUpto = 0;
while(hitUpto < hits.length) {
assert queue.size() > 0;
ShardRef ref = queue.pop();
hits[hitUpto] = shardHits[ref.shardIndex].scoreDocs[ref.hitIndex++];
shardIndex[hitUpto] = ref.shardIndex;
final ScoreDoc hit = shardHits[ref.shardIndex].scoreDocs[ref.hitIndex++];
if (sort == null) {
hits[hitUpto] = new ScoreDoc(hit.doc, hit.score, ref.shardIndex);
} else {
hits[hitUpto] = new FieldDoc(hit.doc, hit.score, ((FieldDoc) hit).fields, ref.shardIndex);
}
//System.out.println(" hitUpto=" + hitUpto);
//System.out.println(" doc=" + hits[hitUpto].doc + " score=" + hits[hitUpto].score);
@ -258,6 +247,10 @@ public class TopDocs {
}
}
return new TopDocsAndShards(totalHitCount, hits, maxScore, shardIndex);
if (sort == null) {
return new TopDocs(totalHitCount, hits, maxScore);
} else {
return new TopFieldDocs(totalHitCount, hits, sort.getSort(), maxScore);
}
}
}

View File

@ -223,7 +223,7 @@ public class TestTopDocsMerge extends LuceneTestCase {
}
// Merge:
final TopDocs.TopDocsAndShards mergedHits = TopDocs.merge(sort, numHits, shardHits);
final TopDocs mergedHits = TopDocs.merge(sort, numHits, shardHits);
if (mergedHits.scoreDocs != null) {
// Make sure the returned shards are correct:
@ -231,7 +231,7 @@ public class TestTopDocsMerge extends LuceneTestCase {
final ScoreDoc sd = mergedHits.scoreDocs[hitIDX];
assertEquals("doc=" + sd.doc + " wrong shard",
ReaderUtil.subIndex(sd.doc, docStarts),
mergedHits.shardIndex[hitIDX]);
sd.shardIndex);
}
}

View File

@ -1,36 +0,0 @@
package org.apache.lucene.search.grouping;
/**
* 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 org.apache.lucene.search.ScoreDoc;
public class GroupDocsAndShards<GROUP_VALUE_TYPE> extends GroupDocs<GROUP_VALUE_TYPE> {
public final int[] shardIndex;
public GroupDocsAndShards(float maxScore,
int totalHits,
ScoreDoc[] scoreDocs,
GROUP_VALUE_TYPE groupValue,
Object[] groupSortValues,
int[] shardIndex) {
super(maxScore, totalHits, scoreDocs, groupValue, groupSortValues);
this.shardIndex = shardIndex;
}
}

View File

@ -18,7 +18,6 @@ package org.apache.lucene.search.grouping;
*/
import java.io.IOException;
import java.util.Arrays;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
@ -133,17 +132,14 @@ public class TopGroups<GROUP_VALUE_TYPE> {
totalHits += shardGroupDocs.totalHits;
}
final TopDocs.TopDocsAndShards mergedTopDocs = TopDocs.merge(docSort, docOffset + docTopN, shardTopDocs);
final TopDocs mergedTopDocs = TopDocs.merge(docSort, docOffset + docTopN, shardTopDocs);
// Slice;
final ScoreDoc[] mergedScoreDocs;
final int[] mergedShardIndex;
if (docOffset == 0) {
mergedScoreDocs = mergedTopDocs.scoreDocs;
mergedShardIndex = mergedTopDocs.shardIndex;
} else if (docOffset >= mergedTopDocs.scoreDocs.length) {
mergedScoreDocs = new ScoreDoc[0];
mergedShardIndex = new int[0];
} else {
mergedScoreDocs = new ScoreDoc[mergedTopDocs.scoreDocs.length - docOffset];
System.arraycopy(mergedTopDocs.scoreDocs,
@ -151,20 +147,13 @@ public class TopGroups<GROUP_VALUE_TYPE> {
mergedScoreDocs,
0,
mergedTopDocs.scoreDocs.length - docOffset);
mergedShardIndex = new int[mergedTopDocs.scoreDocs.length - docOffset];
System.arraycopy(mergedTopDocs.shardIndex,
docOffset,
mergedShardIndex,
0,
mergedTopDocs.scoreDocs.length - docOffset);
}
//System.out.println("SHARDS=" + Arrays.toString(mergedTopDocs.shardIndex));
mergedGroupDocs[groupIDX] = new GroupDocsAndShards<T>(maxScore,
mergedGroupDocs[groupIDX] = new GroupDocs<T>(maxScore,
totalHits,
mergedScoreDocs,
groupValue,
shardGroups[0].groups[groupIDX].groupSortValues,
mergedShardIndex);
shardGroups[0].groups[groupIDX].groupSortValues);
}
return new TopGroups<T>(groupSort.getSort(),

View File

@ -876,13 +876,11 @@ public class TestGrouping extends LuceneTestCase {
private void verifyShards(int[] docStarts, TopGroups<BytesRef> topGroups) {
for(GroupDocs group : topGroups.groups) {
assertTrue(group instanceof GroupDocsAndShards);
GroupDocsAndShards withShards = (GroupDocsAndShards) group;
for(int hitIDX=0;hitIDX<withShards.scoreDocs.length;hitIDX++) {
final ScoreDoc sd = withShards.scoreDocs[hitIDX];
for(int hitIDX=0;hitIDX<group.scoreDocs.length;hitIDX++) {
final ScoreDoc sd = group.scoreDocs[hitIDX];
assertEquals("doc=" + sd.doc + " wrong shard",
ReaderUtil.subIndex(sd.doc, docStarts),
withShards.shardIndex[hitIDX]);
sd.shardIndex);
}
}
}