mirror of https://github.com/apache/lucene.git
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:
parent
240822d45a
commit
fe7593efee
|
@ -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) {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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(),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue