do not check global minimum score on non-competitive hits since it hurts constant score queries

This commit is contained in:
jimczi 2019-10-02 10:34:03 +02:00
parent 1770f15bb5
commit 93d135e79d
2 changed files with 42 additions and 29 deletions

View File

@ -126,7 +126,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
super.setScorer(scorer);
// reset the minimum competitive score
minCompetitiveScore = 0f;
updateMinCompetitiveScore(scorer, true);
updateMinCompetitiveScore(scorer);
}
@Override
@ -145,8 +145,10 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
} else {
collectedAllCompetitiveHits = true;
}
} else {
updateMinCompetitiveScore(scorer, totalHitsRelation == Relation.EQUAL_TO);
} else if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
// we can start setting the min competitive score if we just
// reached totalHitsThreshold
updateMinCompetitiveScore(scorer);
}
return;
}
@ -155,7 +157,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
comparator.copy(bottom.slot, doc);
updateBottom(doc);
comparator.setBottom(bottom.slot);
updateMinCompetitiveScore(scorer, true);
updateMinCompetitiveScore(scorer);
} else {
// Startup transient: queue hasn't gathered numHits yet
final int slot = totalHits - 1;
@ -166,7 +168,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
if (queueFull) {
comparator.setBottom(bottom.slot);
}
updateMinCompetitiveScore(scorer, true);
updateMinCompetitiveScore(scorer);
}
}
@ -215,7 +217,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
public void setScorer(Scorable scorer) throws IOException {
super.setScorer(scorer);
minCompetitiveScore = 0f;
updateMinCompetitiveScore(scorer, true);
updateMinCompetitiveScore(scorer);
}
@Override
@ -239,10 +241,10 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
} else {
collectedAllCompetitiveHits = true;
}
} else {
// we just reached totalHitsThreshold, we can start setting the min
// competitive score now
updateMinCompetitiveScore(scorer, totalHitsRelation == Relation.EQUAL_TO);
} else if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
// we can start setting the min competitive score if we just
// reached totalHitsThreshold
updateMinCompetitiveScore(scorer);
}
return;
}
@ -251,7 +253,11 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
final int topCmp = reverseMul * comparator.compareTop(doc);
if (topCmp > 0 || (topCmp == 0 && doc <= afterDoc)) {
// Already collected on a previous page
updateMinCompetitiveScore(scorer, totalHitsRelation == Relation.EQUAL_TO);
if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
// we can start setting the min competitive score if we just
// reached totalHitsThreshold
updateMinCompetitiveScore(scorer);
}
return;
}
@ -262,7 +268,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
updateBottom(doc);
comparator.setBottom(bottom.slot);
updateMinCompetitiveScore(scorer, true);
updateMinCompetitiveScore(scorer);
} else {
collectedHits++;
@ -277,7 +283,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
if (queueFull) {
comparator.setBottom(bottom.slot);
}
updateMinCompetitiveScore(scorer, true);
updateMinCompetitiveScore(scorer);
}
}
};
@ -336,10 +342,10 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
return scoreMode;
}
protected void updateMinCompetitiveScore(Scorable scorer, boolean checkQueue) throws IOException {
protected void updateMinCompetitiveScore(Scorable scorer) throws IOException {
if (canSetMinScore && hitsThresholdChecker.isThresholdReached()) {
boolean hasChanged = false;
if (checkQueue && queueFull) {
if (queueFull) {
assert bottom != null && firstComparator != null;
float localMinScore = firstComparator.value(bottom.slot);
if (localMinScore > minCompetitiveScore) {

View File

@ -64,7 +64,7 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
super.setScorer(scorer);
// reset the minimum competitive score
minCompetitiveScore = 0f;
updateMinCompetitiveScore(scorer, true);
updateMinCompetitiveScore(scorer);
}
@Override
@ -78,10 +78,11 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
hitsThresholdChecker.incrementHitCount();
if (score <= pqTop.score) {
// the document is not competitive but we need to update the minimum competitive score
// if we just reached the total hits threshold or if the global minimum score (bottomValueChecker)
// has been updated
updateMinCompetitiveScore(scorer, totalHitsRelation == TotalHits.Relation.EQUAL_TO);
if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
// we can start setting the min competitive score if we just
// reached totalHitsThreshold
updateMinCompetitiveScore(scorer);
}
// Since docs are returned in-order (i.e., increasing doc Id), a document
// with equal score to pqTop.score cannot compete since HitQueue favors
// documents with lower doc Ids. Therefore reject those docs too.
@ -90,7 +91,7 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
pqTop.doc = doc + docBase;
pqTop.score = score;
pqTop = pq.updateTop();
updateMinCompetitiveScore(scorer, true);
updateMinCompetitiveScore(scorer);
}
};
@ -140,25 +141,31 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
if (score > after.score || (score == after.score && doc <= afterDoc)) {
// hit was collected on a previous page
updateMinCompetitiveScore(scorer, totalHitsRelation == TotalHits.Relation.EQUAL_TO);
if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
// we can start setting the min competitive score if we just
// reached totalHitsThreshold
updateMinCompetitiveScore(scorer);
}
return;
}
if (score <= pqTop.score) {
// the document is not competitive but we need to update the minimum competitive score
// if we just reached the total hits threshold or if the global minimum score (bottomValueChecker)
// has been updated
updateMinCompetitiveScore(scorer, totalHitsRelation == TotalHits.Relation.EQUAL_TO);
if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
// we can start setting the min competitive score if we just
// reached totalHitsThreshold
updateMinCompetitiveScore(scorer);
}
// Since docs are returned in-order (i.e., increasing doc Id), a document
// with equal score to pqTop.score cannot compete since HitQueue favors
// documents with lower doc Ids. Therefore reject those docs too.
return;
}
collectedHits++;
pqTop.doc = doc + docBase;
pqTop.score = score;
pqTop = pq.updateTop();
updateMinCompetitiveScore(scorer, true);
updateMinCompetitiveScore(scorer);
}
};
}
@ -285,10 +292,10 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
return pqTop != null && pqTop.score != Float.NEGATIVE_INFINITY;
}
protected void updateMinCompetitiveScore(Scorable scorer, boolean checkQueue) throws IOException {
protected void updateMinCompetitiveScore(Scorable scorer) throws IOException {
if (hitsThresholdChecker.isThresholdReached()) {
boolean hasChanged = false;
if (checkQueue && isQueueFull()) {
if (isQueueFull()) {
// since we tie-break on doc id and collect in doc id order, we can require
// the next float
float localMinScore = Math.nextUp(pqTop.score);