mirror of https://github.com/apache/lucene.git
refactor updateMinCompetitiveScore and ensures that the recorded min competitive score is resetted on setScorer
This commit is contained in:
parent
ee50a3812c
commit
7eab6ebb27
|
@ -124,7 +124,9 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
@Override
|
@Override
|
||||||
public void setScorer(Scorable scorer) throws IOException {
|
public void setScorer(Scorable scorer) throws IOException {
|
||||||
super.setScorer(scorer);
|
super.setScorer(scorer);
|
||||||
updateMinCompetitiveScore(scorer);
|
// reset the minimum competitive score
|
||||||
|
minCompetitiveScore = 0f;
|
||||||
|
updateMinCompetitiveScore(scorer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -143,10 +145,8 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
} else {
|
} else {
|
||||||
collectedAllCompetitiveHits = true;
|
collectedAllCompetitiveHits = true;
|
||||||
}
|
}
|
||||||
} else if (totalHitsRelation == Relation.EQUAL_TO || shouldUpdateMinScore()) {
|
} else {
|
||||||
// we just reached totalHitsThreshold, we can start setting the min
|
updateMinCompetitiveScore(scorer, totalHitsRelation == Relation.EQUAL_TO);
|
||||||
// competitive score now
|
|
||||||
updateMinCompetitiveScore(scorer);
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
comparator.copy(bottom.slot, doc);
|
comparator.copy(bottom.slot, doc);
|
||||||
updateBottom(doc);
|
updateBottom(doc);
|
||||||
comparator.setBottom(bottom.slot);
|
comparator.setBottom(bottom.slot);
|
||||||
updateMinCompetitiveScore(scorer);
|
updateMinCompetitiveScore(scorer, true);
|
||||||
} else {
|
} else {
|
||||||
// Startup transient: queue hasn't gathered numHits yet
|
// Startup transient: queue hasn't gathered numHits yet
|
||||||
final int slot = totalHits - 1;
|
final int slot = totalHits - 1;
|
||||||
|
@ -165,7 +165,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
add(slot, doc);
|
add(slot, doc);
|
||||||
if (queueFull) {
|
if (queueFull) {
|
||||||
comparator.setBottom(bottom.slot);
|
comparator.setBottom(bottom.slot);
|
||||||
updateMinCompetitiveScore(scorer);
|
updateMinCompetitiveScore(scorer, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,8 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
@Override
|
@Override
|
||||||
public void setScorer(Scorable scorer) throws IOException {
|
public void setScorer(Scorable scorer) throws IOException {
|
||||||
super.setScorer(scorer);
|
super.setScorer(scorer);
|
||||||
updateMinCompetitiveScore(scorer);
|
minCompetitiveScore = 0f;
|
||||||
|
updateMinCompetitiveScore(scorer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -238,10 +239,10 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
} else {
|
} else {
|
||||||
collectedAllCompetitiveHits = true;
|
collectedAllCompetitiveHits = true;
|
||||||
}
|
}
|
||||||
} else if (totalHitsRelation == Relation.EQUAL_TO || shouldUpdateMinScore()) {
|
} else {
|
||||||
// we just reached totalHitsThreshold, we can start setting the min
|
// we just reached totalHitsThreshold, we can start setting the min
|
||||||
// competitive score now
|
// competitive score now
|
||||||
updateMinCompetitiveScore(scorer);
|
updateMinCompetitiveScore(scorer, totalHitsRelation == Relation.EQUAL_TO);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -260,7 +261,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
updateBottom(doc);
|
updateBottom(doc);
|
||||||
|
|
||||||
comparator.setBottom(bottom.slot);
|
comparator.setBottom(bottom.slot);
|
||||||
updateMinCompetitiveScore(scorer);
|
updateMinCompetitiveScore(scorer, true);
|
||||||
} else {
|
} else {
|
||||||
collectedHits++;
|
collectedHits++;
|
||||||
|
|
||||||
|
@ -274,7 +275,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
queueFull = collectedHits == numHits;
|
queueFull = collectedHits == numHits;
|
||||||
if (queueFull) {
|
if (queueFull) {
|
||||||
comparator.setBottom(bottom.slot);
|
comparator.setBottom(bottom.slot);
|
||||||
updateMinCompetitiveScore(scorer);
|
updateMinCompetitiveScore(scorer, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,10 +291,9 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
final BottomValueChecker bottomValueChecker;
|
final BottomValueChecker bottomValueChecker;
|
||||||
final FieldComparator.RelevanceComparator firstComparator;
|
final FieldComparator.RelevanceComparator firstComparator;
|
||||||
final boolean canSetMinScore;
|
final boolean canSetMinScore;
|
||||||
// the minimum score (if canSetMinScore is true) that is currently used by the scorer,
|
// the minimum competitive score (if canSetMinScore is true) that is currently
|
||||||
// can be different than pqTop.score if the provided bottomValueChecker reports a minimum
|
// used by the underlying scorer (see setScorer)
|
||||||
// score that is greater than the local one.
|
float minCompetitiveScore;
|
||||||
float minScore;
|
|
||||||
final int numComparators;
|
final int numComparators;
|
||||||
FieldValueHitQueue.Entry bottom = null;
|
FieldValueHitQueue.Entry bottom = null;
|
||||||
boolean queueFull;
|
boolean queueFull;
|
||||||
|
@ -335,28 +335,31 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
return scoreMode;
|
return scoreMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean shouldUpdateMinScore() {
|
protected void updateMinCompetitiveScore(Scorable scorer, boolean checkQueue) throws IOException {
|
||||||
return bottomValueChecker != null ? bottomValueChecker.getBottomValue() > minScore : false;
|
if (canSetMinScore && hitsThresholdChecker.isThresholdReached()) {
|
||||||
}
|
boolean hasChanged = false;
|
||||||
|
if (checkQueue && queueFull) {
|
||||||
protected void updateMinCompetitiveScore(Scorable scorer) throws IOException {
|
|
||||||
if (canSetMinScore && hitsThresholdChecker.isThresholdReached()
|
|
||||||
&& (queueFull || (bottomValueChecker != null && bottomValueChecker.getBottomValue() > 0f))) {
|
|
||||||
float maxMinScore = Float.NEGATIVE_INFINITY;
|
|
||||||
if (queueFull) {
|
|
||||||
assert bottom != null && firstComparator != null;
|
assert bottom != null && firstComparator != null;
|
||||||
maxMinScore = firstComparator.value(bottom.slot);
|
float localMinScore = firstComparator.value(bottom.slot);
|
||||||
if (bottomValueChecker != null) {
|
if (localMinScore > minCompetitiveScore) {
|
||||||
bottomValueChecker.updateThreadLocalBottomValue(maxMinScore);
|
hasChanged = true;
|
||||||
|
minCompetitiveScore = localMinScore;
|
||||||
|
if (bottomValueChecker != null) {
|
||||||
|
bottomValueChecker.updateThreadLocalBottomValue(minCompetitiveScore);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bottomValueChecker != null) {
|
if (bottomValueChecker != null) {
|
||||||
maxMinScore = Math.max(maxMinScore, bottomValueChecker.getBottomValue());
|
float globalMinScore = bottomValueChecker.getBottomValue();
|
||||||
|
if (globalMinScore > minCompetitiveScore) {
|
||||||
|
hasChanged = true;
|
||||||
|
minCompetitiveScore = globalMinScore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasChanged) {
|
||||||
|
scorer.setMinCompetitiveScore(minCompetitiveScore);
|
||||||
|
totalHitsRelation = TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO;
|
||||||
}
|
}
|
||||||
assert maxMinScore > 0f;
|
|
||||||
scorer.setMinCompetitiveScore(maxMinScore);
|
|
||||||
minScore = maxMinScore;
|
|
||||||
totalHitsRelation = TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,9 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
|
||||||
@Override
|
@Override
|
||||||
public void setScorer(Scorable scorer) throws IOException {
|
public void setScorer(Scorable scorer) throws IOException {
|
||||||
super.setScorer(scorer);
|
super.setScorer(scorer);
|
||||||
updateMinCompetitiveScore(scorer);
|
// reset the minimum competitive score
|
||||||
|
minCompetitiveScore = 0f;
|
||||||
|
updateMinCompetitiveScore(scorer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -76,12 +78,10 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
|
||||||
hitsThresholdChecker.incrementHitCount();
|
hitsThresholdChecker.incrementHitCount();
|
||||||
|
|
||||||
if (score <= pqTop.score) {
|
if (score <= pqTop.score) {
|
||||||
if ((totalHitsRelation == TotalHits.Relation.EQUAL_TO || shouldUpdateMinScore())
|
// the document is not competitive but we need to update the minimum competitive score
|
||||||
&& hitsThresholdChecker.isThresholdReached()) {
|
// if we just reached the total hits threshold or if the global minimum score (bottomValueChecker)
|
||||||
// we just reached totalHitsThreshold, we can start setting the min
|
// has been updated
|
||||||
// competitive score now
|
updateMinCompetitiveScore(scorer, totalHitsRelation == TotalHits.Relation.EQUAL_TO);
|
||||||
updateMinCompetitiveScore(scorer);
|
|
||||||
}
|
|
||||||
// Since docs are returned in-order (i.e., increasing doc Id), a document
|
// Since docs are returned in-order (i.e., increasing doc Id), a document
|
||||||
// with equal score to pqTop.score cannot compete since HitQueue favors
|
// with equal score to pqTop.score cannot compete since HitQueue favors
|
||||||
// documents with lower doc Ids. Therefore reject those docs too.
|
// documents with lower doc Ids. Therefore reject those docs too.
|
||||||
|
@ -90,7 +90,7 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
|
||||||
pqTop.doc = doc + docBase;
|
pqTop.doc = doc + docBase;
|
||||||
pqTop.score = score;
|
pqTop.score = score;
|
||||||
pqTop = pq.updateTop();
|
pqTop = pq.updateTop();
|
||||||
updateMinCompetitiveScore(scorer);
|
updateMinCompetitiveScore(scorer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -140,12 +140,7 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
|
||||||
|
|
||||||
if (score > after.score || (score == after.score && doc <= afterDoc)) {
|
if (score > after.score || (score == after.score && doc <= afterDoc)) {
|
||||||
// hit was collected on a previous page
|
// hit was collected on a previous page
|
||||||
if ((totalHitsRelation == TotalHits.Relation.EQUAL_TO || shouldUpdateMinScore())
|
updateMinCompetitiveScore(scorer, totalHitsRelation == TotalHits.Relation.EQUAL_TO);
|
||||||
&& hitsThresholdChecker.isThresholdReached()) {
|
|
||||||
// we just reached totalHitsThreshold, we can start setting the min
|
|
||||||
// competitive score now
|
|
||||||
updateMinCompetitiveScore(scorer);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +154,7 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
|
||||||
pqTop.doc = doc + docBase;
|
pqTop.doc = doc + docBase;
|
||||||
pqTop.score = score;
|
pqTop.score = score;
|
||||||
pqTop = pq.updateTop();
|
pqTop = pq.updateTop();
|
||||||
updateMinCompetitiveScore(scorer);
|
updateMinCompetitiveScore(scorer, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -249,10 +244,9 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ScoreDoc pqTop;
|
ScoreDoc pqTop;
|
||||||
// the minimum score that is currently used by the scorer, can be different than pqTop.score
|
// the minimum competitive score that is currently
|
||||||
// if the provided bottomValueChecker reports a minimum score that is greater than the local
|
// used by the underlying scorer (see setScorer)
|
||||||
// one.
|
float minCompetitiveScore;
|
||||||
float minScore;
|
|
||||||
final HitsThresholdChecker hitsThresholdChecker;
|
final HitsThresholdChecker hitsThresholdChecker;
|
||||||
final BottomValueChecker bottomValueChecker;
|
final BottomValueChecker bottomValueChecker;
|
||||||
|
|
||||||
|
@ -283,36 +277,44 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
|
||||||
return hitsThresholdChecker.scoreMode();
|
return hitsThresholdChecker.scoreMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean shouldUpdateMinScore() {
|
public boolean isQueueFull() {
|
||||||
return bottomValueChecker != null ? bottomValueChecker.getBottomValue() > minScore : false;
|
return pqTop != null && pqTop.score != Float.NEGATIVE_INFINITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateMinCompetitiveScore(Scorable scorer) throws IOException {
|
protected void updateMinCompetitiveScore(Scorable scorer, boolean checkQueue) throws IOException {
|
||||||
if (hitsThresholdChecker.isThresholdReached()
|
if (hitsThresholdChecker.isThresholdReached()) {
|
||||||
&& ((bottomValueChecker != null && bottomValueChecker.getBottomValue() > 0)
|
boolean hasChanged = false;
|
||||||
|| (pqTop != null && pqTop.score != Float.NEGATIVE_INFINITY))) { // -Infinity is the score of sentinels
|
if (checkQueue && isQueueFull()) {
|
||||||
// since we tie-break on doc id and collect in doc id order, we can require
|
// since we tie-break on doc id and collect in doc id order, we can require
|
||||||
// the next float
|
// the next float
|
||||||
float bottomScore = Float.NEGATIVE_INFINITY;
|
float localMinScore = Math.nextUp(pqTop.score);
|
||||||
|
if (localMinScore > minCompetitiveScore) {
|
||||||
if (pqTop != null && pqTop.score != Float.NEGATIVE_INFINITY) {
|
hasChanged = true;
|
||||||
bottomScore = Math.nextUp(pqTop.score);
|
minCompetitiveScore = localMinScore;
|
||||||
|
if (bottomValueChecker != null) {
|
||||||
if (bottomValueChecker != null) {
|
// we don't use the next float here since we register a minimum value
|
||||||
bottomValueChecker.updateThreadLocalBottomValue(pqTop.score);
|
// for other segments that might have smaller doc ids
|
||||||
|
bottomValueChecker.updateThreadLocalBottomValue(pqTop.score);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Global bottom can only be greater than or equal to the local bottom score
|
// Global bottom can only be greater than or equal to the local bottom score
|
||||||
// The updating of global bottom score for this hit before getting here should
|
// The updating of global bottom score for this hit before getting here should
|
||||||
// ensure that
|
// ensure that
|
||||||
if (bottomValueChecker != null && bottomValueChecker.getBottomValue() > bottomScore) {
|
if (bottomValueChecker != null) {
|
||||||
bottomScore = bottomValueChecker.getBottomValue();
|
float globalMinScore = bottomValueChecker.getBottomValue();
|
||||||
|
if (globalMinScore > minCompetitiveScore) {
|
||||||
|
assert isQueueFull() == false || bottomValueChecker.getBottomValue() > Math.nextUp(pqTop.score);
|
||||||
|
hasChanged = true;
|
||||||
|
minCompetitiveScore = bottomValueChecker.getBottomValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scorer.setMinCompetitiveScore(bottomScore);
|
if (hasChanged) {
|
||||||
minScore = bottomScore;
|
scorer.setMinCompetitiveScore(minCompetitiveScore);
|
||||||
totalHitsRelation = TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO;
|
totalHitsRelation = TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -476,7 +476,7 @@ public class TestTopDocsCollector extends LuceneTestCase {
|
||||||
dir.close();
|
dir.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testConcurrentMinScoreTopScoreDocs() throws Exception {
|
public void testConcurrentMinScore() throws Exception {
|
||||||
Directory dir = newDirectory();
|
Directory dir = newDirectory();
|
||||||
IndexWriter w = new IndexWriter(dir, newIndexWriterConfig().setMergePolicy(NoMergePolicy.INSTANCE));
|
IndexWriter w = new IndexWriter(dir, newIndexWriterConfig().setMergePolicy(NoMergePolicy.INSTANCE));
|
||||||
Document doc = new Document();
|
Document doc = new Document();
|
||||||
|
@ -591,121 +591,4 @@ public class TestTopDocsCollector extends LuceneTestCase {
|
||||||
reader.close();
|
reader.close();
|
||||||
dir.close();
|
dir.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testConcurrentMinScoreTopFieldDocs() throws Exception {
|
|
||||||
Directory dir = newDirectory();
|
|
||||||
IndexWriter w = new IndexWriter(dir, newIndexWriterConfig().setMergePolicy(NoMergePolicy.INSTANCE));
|
|
||||||
Document doc = new Document();
|
|
||||||
w.addDocuments(Arrays.asList(doc, doc, doc, doc, doc));
|
|
||||||
w.flush();
|
|
||||||
w.addDocuments(Arrays.asList(doc, doc, doc, doc, doc, doc));
|
|
||||||
w.flush();
|
|
||||||
w.addDocuments(Arrays.asList(doc, doc));
|
|
||||||
w.flush();
|
|
||||||
IndexReader reader = DirectoryReader.open(w);
|
|
||||||
assertEquals(3, reader.leaves().size());
|
|
||||||
w.close();
|
|
||||||
|
|
||||||
Sort sort = new Sort(SortField.FIELD_SCORE, SortField.FIELD_DOC);
|
|
||||||
CollectorManager<TopFieldCollector, TopFieldDocs> manager =
|
|
||||||
TopFieldCollector.createSharedManager(sort, 2, null, 0);
|
|
||||||
TopFieldCollector collector = manager.newCollector();
|
|
||||||
TopFieldCollector collector2 = manager.newCollector();
|
|
||||||
assertTrue(collector.bottomValueChecker == collector2.bottomValueChecker);
|
|
||||||
BottomValueChecker minValueChecker = collector.bottomValueChecker;
|
|
||||||
|
|
||||||
ScoreAndDoc scorer = new ScoreAndDoc();
|
|
||||||
ScoreAndDoc scorer2 = new ScoreAndDoc();
|
|
||||||
|
|
||||||
LeafCollector leafCollector = collector.getLeafCollector(reader.leaves().get(0));
|
|
||||||
leafCollector.setScorer(scorer);
|
|
||||||
LeafCollector leafCollector2 = collector2.getLeafCollector(reader.leaves().get(1));
|
|
||||||
leafCollector2.setScorer(scorer2);
|
|
||||||
|
|
||||||
scorer.doc = 0;
|
|
||||||
scorer.score = 3;
|
|
||||||
leafCollector.collect(0);
|
|
||||||
|
|
||||||
scorer2.doc = 0;
|
|
||||||
scorer2.score = 6;
|
|
||||||
leafCollector2.collect(0);
|
|
||||||
|
|
||||||
scorer.doc = 1;
|
|
||||||
scorer.score = 2;
|
|
||||||
leafCollector.collect(1);
|
|
||||||
assertEquals(minValueChecker.getBottomValue(), 2f, 0f);
|
|
||||||
assertEquals(scorer.minCompetitiveScore, 2f, 0f);
|
|
||||||
assertNull(scorer2.minCompetitiveScore);
|
|
||||||
|
|
||||||
scorer2.doc = 1;
|
|
||||||
scorer2.score = 9;
|
|
||||||
leafCollector2.collect(1);
|
|
||||||
assertEquals(minValueChecker.getBottomValue(), 6f, 0f);
|
|
||||||
assertEquals(scorer.minCompetitiveScore, 2f, 0f);
|
|
||||||
assertEquals(scorer2.minCompetitiveScore, 6f, 0f);
|
|
||||||
|
|
||||||
scorer2.doc = 2;
|
|
||||||
scorer2.score = 7;
|
|
||||||
leafCollector2.collect(2);
|
|
||||||
assertEquals(minValueChecker.getBottomValue(), 7f, 0f);
|
|
||||||
assertEquals(scorer.minCompetitiveScore, 2f, 0f);
|
|
||||||
assertEquals(scorer2.minCompetitiveScore, 7f, 0f);
|
|
||||||
|
|
||||||
scorer2.doc = 3;
|
|
||||||
scorer2.score = 1;
|
|
||||||
leafCollector2.collect(3);
|
|
||||||
assertEquals(minValueChecker.getBottomValue(), 7f, 0f);
|
|
||||||
assertEquals(scorer.minCompetitiveScore, 2f, 0f);
|
|
||||||
assertEquals(scorer2.minCompetitiveScore, 7f, 0f);
|
|
||||||
|
|
||||||
scorer.doc = 2;
|
|
||||||
scorer.score = 10;
|
|
||||||
leafCollector.collect(2);
|
|
||||||
assertEquals(minValueChecker.getBottomValue(), 7f, 0f);
|
|
||||||
assertEquals(scorer.minCompetitiveScore, 7f, 0f);
|
|
||||||
assertEquals(scorer2.minCompetitiveScore, 7f, 0f);
|
|
||||||
|
|
||||||
scorer.doc = 3;
|
|
||||||
scorer.score = 11;
|
|
||||||
leafCollector.collect(3);
|
|
||||||
assertEquals(minValueChecker.getBottomValue(), 10, 0f);
|
|
||||||
assertEquals(scorer.minCompetitiveScore, 10f, 0f);
|
|
||||||
assertEquals(scorer2.minCompetitiveScore, 7f, 0f);
|
|
||||||
|
|
||||||
TopFieldCollector collector3 = manager.newCollector();
|
|
||||||
LeafCollector leafCollector3 = collector3.getLeafCollector(reader.leaves().get(2));
|
|
||||||
ScoreAndDoc scorer3 = new ScoreAndDoc();
|
|
||||||
leafCollector3.setScorer(scorer3);
|
|
||||||
assertEquals(scorer3.minCompetitiveScore, 10f, 0f);
|
|
||||||
|
|
||||||
scorer3.doc = 0;
|
|
||||||
scorer3.score = 1f;
|
|
||||||
leafCollector3.collect(0);
|
|
||||||
assertEquals(minValueChecker.getBottomValue(), 10f, 0f);
|
|
||||||
assertEquals(scorer3.minCompetitiveScore, 10f, 0f);
|
|
||||||
|
|
||||||
scorer.doc = 4;
|
|
||||||
scorer.score = 11;
|
|
||||||
leafCollector.collect(4);
|
|
||||||
assertEquals(minValueChecker.getBottomValue(), 11f, 0f);
|
|
||||||
assertEquals(scorer.minCompetitiveScore, 11f, 0f);
|
|
||||||
assertEquals(scorer2.minCompetitiveScore, 7f, 0f);
|
|
||||||
assertEquals(scorer3.minCompetitiveScore, 10f, 0f);
|
|
||||||
|
|
||||||
scorer3.doc = 1;
|
|
||||||
scorer3.score = 2f;
|
|
||||||
leafCollector3.collect(1);
|
|
||||||
assertEquals(minValueChecker.getBottomValue(), 11f, 0f);
|
|
||||||
assertEquals(scorer.minCompetitiveScore, 11f, 0f);
|
|
||||||
assertEquals(scorer2.minCompetitiveScore, 7f, 0f);
|
|
||||||
assertEquals(scorer3.minCompetitiveScore, 11f, 0f);
|
|
||||||
|
|
||||||
|
|
||||||
TopFieldDocs topDocs = manager.reduce(Arrays.asList(collector, collector2, collector3));
|
|
||||||
assertEquals(11, topDocs.totalHits.value);
|
|
||||||
assertEquals(new TotalHits(11, TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO), topDocs.totalHits);
|
|
||||||
|
|
||||||
reader.close();
|
|
||||||
dir.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -495,4 +495,121 @@ public class TestTopFieldCollector extends LuceneTestCase {
|
||||||
dir.close();
|
dir.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testConcurrentMinScore() throws Exception {
|
||||||
|
Directory dir = newDirectory();
|
||||||
|
IndexWriter w = new IndexWriter(dir, newIndexWriterConfig().setMergePolicy(NoMergePolicy.INSTANCE));
|
||||||
|
Document doc = new Document();
|
||||||
|
w.addDocuments(Arrays.asList(doc, doc, doc, doc, doc));
|
||||||
|
w.flush();
|
||||||
|
w.addDocuments(Arrays.asList(doc, doc, doc, doc, doc, doc));
|
||||||
|
w.flush();
|
||||||
|
w.addDocuments(Arrays.asList(doc, doc));
|
||||||
|
w.flush();
|
||||||
|
IndexReader reader = DirectoryReader.open(w);
|
||||||
|
assertEquals(3, reader.leaves().size());
|
||||||
|
w.close();
|
||||||
|
|
||||||
|
Sort sort = new Sort(SortField.FIELD_SCORE, SortField.FIELD_DOC);
|
||||||
|
CollectorManager<TopFieldCollector, TopFieldDocs> manager =
|
||||||
|
TopFieldCollector.createSharedManager(sort, 2, null, 0);
|
||||||
|
TopFieldCollector collector = manager.newCollector();
|
||||||
|
TopFieldCollector collector2 = manager.newCollector();
|
||||||
|
assertTrue(collector.bottomValueChecker == collector2.bottomValueChecker);
|
||||||
|
BottomValueChecker minValueChecker = collector.bottomValueChecker;
|
||||||
|
|
||||||
|
ScoreAndDoc scorer = new ScoreAndDoc();
|
||||||
|
ScoreAndDoc scorer2 = new ScoreAndDoc();
|
||||||
|
|
||||||
|
LeafCollector leafCollector = collector.getLeafCollector(reader.leaves().get(0));
|
||||||
|
leafCollector.setScorer(scorer);
|
||||||
|
LeafCollector leafCollector2 = collector2.getLeafCollector(reader.leaves().get(1));
|
||||||
|
leafCollector2.setScorer(scorer2);
|
||||||
|
|
||||||
|
scorer.doc = 0;
|
||||||
|
scorer.score = 3;
|
||||||
|
leafCollector.collect(0);
|
||||||
|
|
||||||
|
scorer2.doc = 0;
|
||||||
|
scorer2.score = 6;
|
||||||
|
leafCollector2.collect(0);
|
||||||
|
|
||||||
|
scorer.doc = 1;
|
||||||
|
scorer.score = 2;
|
||||||
|
leafCollector.collect(1);
|
||||||
|
assertEquals(minValueChecker.getBottomValue(), 2f, 0f);
|
||||||
|
assertEquals(scorer.minCompetitiveScore, 2f, 0f);
|
||||||
|
assertNull(scorer2.minCompetitiveScore);
|
||||||
|
|
||||||
|
scorer2.doc = 1;
|
||||||
|
scorer2.score = 9;
|
||||||
|
leafCollector2.collect(1);
|
||||||
|
assertEquals(minValueChecker.getBottomValue(), 6f, 0f);
|
||||||
|
assertEquals(scorer.minCompetitiveScore, 2f, 0f);
|
||||||
|
assertEquals(scorer2.minCompetitiveScore, 6f, 0f);
|
||||||
|
|
||||||
|
scorer2.doc = 2;
|
||||||
|
scorer2.score = 7;
|
||||||
|
leafCollector2.collect(2);
|
||||||
|
assertEquals(minValueChecker.getBottomValue(), 7f, 0f);
|
||||||
|
assertEquals(scorer.minCompetitiveScore, 2f, 0f);
|
||||||
|
assertEquals(scorer2.minCompetitiveScore, 7f, 0f);
|
||||||
|
|
||||||
|
scorer2.doc = 3;
|
||||||
|
scorer2.score = 1;
|
||||||
|
leafCollector2.collect(3);
|
||||||
|
assertEquals(minValueChecker.getBottomValue(), 7f, 0f);
|
||||||
|
assertEquals(scorer.minCompetitiveScore, 2f, 0f);
|
||||||
|
assertEquals(scorer2.minCompetitiveScore, 7f, 0f);
|
||||||
|
|
||||||
|
scorer.doc = 2;
|
||||||
|
scorer.score = 10;
|
||||||
|
leafCollector.collect(2);
|
||||||
|
assertEquals(minValueChecker.getBottomValue(), 7f, 0f);
|
||||||
|
assertEquals(scorer.minCompetitiveScore, 7f, 0f);
|
||||||
|
assertEquals(scorer2.minCompetitiveScore, 7f, 0f);
|
||||||
|
|
||||||
|
scorer.doc = 3;
|
||||||
|
scorer.score = 11;
|
||||||
|
leafCollector.collect(3);
|
||||||
|
assertEquals(minValueChecker.getBottomValue(), 10, 0f);
|
||||||
|
assertEquals(scorer.minCompetitiveScore, 10f, 0f);
|
||||||
|
assertEquals(scorer2.minCompetitiveScore, 7f, 0f);
|
||||||
|
|
||||||
|
TopFieldCollector collector3 = manager.newCollector();
|
||||||
|
LeafCollector leafCollector3 = collector3.getLeafCollector(reader.leaves().get(2));
|
||||||
|
ScoreAndDoc scorer3 = new ScoreAndDoc();
|
||||||
|
leafCollector3.setScorer(scorer3);
|
||||||
|
assertEquals(scorer3.minCompetitiveScore, 10f, 0f);
|
||||||
|
|
||||||
|
scorer3.doc = 0;
|
||||||
|
scorer3.score = 1f;
|
||||||
|
leafCollector3.collect(0);
|
||||||
|
assertEquals(minValueChecker.getBottomValue(), 10f, 0f);
|
||||||
|
assertEquals(scorer3.minCompetitiveScore, 10f, 0f);
|
||||||
|
|
||||||
|
scorer.doc = 4;
|
||||||
|
scorer.score = 11;
|
||||||
|
leafCollector.collect(4);
|
||||||
|
assertEquals(minValueChecker.getBottomValue(), 11f, 0f);
|
||||||
|
assertEquals(scorer.minCompetitiveScore, 11f, 0f);
|
||||||
|
assertEquals(scorer2.minCompetitiveScore, 7f, 0f);
|
||||||
|
assertEquals(scorer3.minCompetitiveScore, 10f, 0f);
|
||||||
|
|
||||||
|
scorer3.doc = 1;
|
||||||
|
scorer3.score = 2f;
|
||||||
|
leafCollector3.collect(1);
|
||||||
|
assertEquals(minValueChecker.getBottomValue(), 11f, 0f);
|
||||||
|
assertEquals(scorer.minCompetitiveScore, 11f, 0f);
|
||||||
|
assertEquals(scorer2.minCompetitiveScore, 7f, 0f);
|
||||||
|
assertEquals(scorer3.minCompetitiveScore, 11f, 0f);
|
||||||
|
|
||||||
|
|
||||||
|
TopFieldDocs topDocs = manager.reduce(Arrays.asList(collector, collector2, collector3));
|
||||||
|
assertEquals(11, topDocs.totalHits.value);
|
||||||
|
assertEquals(new TotalHits(11, TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO), topDocs.totalHits);
|
||||||
|
|
||||||
|
reader.close();
|
||||||
|
dir.close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue