Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc cleanups to TopScoreDocCollector #13935

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 11 additions & 13 deletions lucene/core/src/java/org/apache/lucene/search/HitQueue.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,22 @@ public final class HitQueue extends PriorityQueue<ScoreDoc> {
public HitQueue(int size, boolean prePopulate) {
super(
size,
() -> {
if (prePopulate) {
// Always set the doc Id to MAX_VALUE so that it won't be favored by
// lessThan. This generally should not happen since if score is not NEG_INF,
// TopScoreDocCollector will always add the object to the queue.
return new ScoreDoc(Integer.MAX_VALUE, Float.NEGATIVE_INFINITY);
} else {
return null;
}
});
prePopulate
? () -> {
// Always set the doc Id to MAX_VALUE so that it won't be favored by
// lessThan. This generally should not happen since if score is not NEG_INF,
// TopScoreDocCollector will always add the object to the queue.
return new ScoreDoc(Integer.MAX_VALUE, Float.NEGATIVE_INFINITY);
}
: () -> null);
}

@Override
protected final boolean lessThan(ScoreDoc hitA, ScoreDoc hitB) {
if (hitA.score == hitB.score) {
int cmp = Float.compare(hitA.score, hitB.score);
if (cmp == 0) {
return hitA.doc > hitB.doc;
} else {
return hitA.score < hitB.score;
}
return cmp < 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ protected int topDocsSize() {
// In case pq was populated with sentinel values, there might be less
// results than pq.size(). Therefore return all results until either
// pq.size() or totalHits.
return totalHits < pq.size() ? totalHits : pq.size();
return Math.min(totalHits, pq.size());
}

/** Returns the top docs that were collected by this collector. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ static class PagingTopScoreDocCollector extends TopScoreDocCollector {

@Override
protected int topDocsSize() {
return collectedHits < pq.size() ? collectedHits : pq.size();
return Math.min(collectedHits, pq.size());
}

@Override
Expand Down Expand Up @@ -158,26 +158,18 @@ public void collect(int doc) throws IOException {
updateGlobalMinCompetitiveScore(scorer);
}

if (score > after.score || (score == after.score && doc <= afterDoc)) {
// hit was collected on a previous page
if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
// we just reached totalHitsThreshold, we can start setting the min
// competitive score now
updateMinCompetitiveScore(scorer);
}
return;
}

if (score <= pqTop.score) {
if (score > after.score
|| (score == after.score && doc <= afterDoc)
|| score <= pqTop.score) {
// Either hit was collected on a previous page or
// 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.
if (totalHitsRelation == TotalHits.Relation.EQUAL_TO) {
// we just reached totalHitsThreshold, we can start setting the min
// competitive score now
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++;
Expand Down