Skip to content

Commit

Permalink
Honor topvalue while determining isMissingvalueCompetitive in case bo…
Browse files Browse the repository at this point in the history
…ttom is not set (#12520)
  • Loading branch information
gashutos authored and jpountz committed Sep 12, 2023
1 parent 81d5367 commit 3f1952b
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 17 deletions.
2 changes: 2 additions & 0 deletions lucene/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ Bug Fixes
impact on the user, unless you explicitly invoke the convert function of UTF32ToUTF8, and in the extremely rare
scenario of searching a non-UTF-8 inverted field with Unicode search terms (Tang Donghai).

* LUCENE-12521: Sort After returning in-correct result when missing values are competitive. (Chaitanya Gohel)

Other
---------------------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,13 @@ public void copy(int slot, int doc) throws IOException {
}

@Override
protected boolean isMissingValueCompetitive() {
int result = Double.compare(missingValue, bottom);
return reverse ? (result >= 0) : (result <= 0);
protected int compareMissingValueWithBottomValue() {
return Double.compare(missingValue, bottom);
}

@Override
protected int compareMissingValueWithTopValue() {
return Double.compare(missingValue, topValue);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,13 @@ public void copy(int slot, int doc) throws IOException {
}

@Override
protected boolean isMissingValueCompetitive() {
int result = Float.compare(missingValue, bottom);
return reverse ? (result >= 0) : (result <= 0);
protected int compareMissingValueWithBottomValue() {
return Float.compare(missingValue, bottom);
}

@Override
protected int compareMissingValueWithTopValue() {
return Float.compare(missingValue, topValue);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,13 @@ public void copy(int slot, int doc) throws IOException {
}

@Override
protected boolean isMissingValueCompetitive() {
int result = Integer.compare(missingValue, bottom);
// in reverse (desc) sort missingValue is competitive when it's greater or equal to bottom,
// in asc sort missingValue is competitive when it's smaller or equal to bottom
return reverse ? (result >= 0) : (result <= 0);
protected int compareMissingValueWithBottomValue() {
return Integer.compare(missingValue, bottom);
}

@Override
protected int compareMissingValueWithTopValue() {
return Integer.compare(missingValue, topValue);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,13 @@ public void copy(int slot, int doc) throws IOException {
}

@Override
protected boolean isMissingValueCompetitive() {
int result = Long.compare(missingValue, bottom);
// in reverse (desc) sort missingValue is competitive when it's greater or equal to bottom,
// in asc sort missingValue is competitive when it's smaller or equal to bottom
return reverse ? (result >= 0) : (result <= 0);
protected int compareMissingValueWithBottomValue() {
return Long.compare(missingValue, bottom);
}

@Override
protected int compareMissingValueWithTopValue() {
return Long.compare(missingValue, topValue);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,26 @@ private void updateSkipInterval(boolean success) {
}
}

private boolean isMissingValueCompetitive() {
// if queue is full, always compare with bottom,
// if not, check if we can compare with topValue
if (queueFull) {
int result = compareMissingValueWithBottomValue();
// in reverse (desc) sort missingValue is competitive when it's greater or equal to bottom,
// in asc sort missingValue is competitive when it's smaller or equal to bottom
return reverse ? (result >= 0) : (result <= 0);
} else if (topValueSet) {
int result = compareMissingValueWithTopValue();
// in reverse (desc) sort missingValue is competitive when it's smaller or equal to
// topValue,
// in asc sort missingValue is competitive when it's greater or equal to topValue
return reverse ? (result <= 0) : (result >= 0);
} else {
// by default competitive
return true;
}
}

@Override
public DocIdSetIterator competitiveIterator() {
if (enableSkipping == false) return null;
Expand Down Expand Up @@ -337,7 +357,9 @@ public int advance(int target) throws IOException {
};
}

protected abstract boolean isMissingValueCompetitive();
protected abstract int compareMissingValueWithTopValue();

protected abstract int compareMissingValueWithBottomValue();

protected abstract void encodeBottom(byte[] packedValue);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,40 @@ public void testSortOptimizationWithMissingValues() throws IOException {
assertNonCompetitiveHitsAreSkipped(topDocs.totalHits.value, numDocs);
}

{ // test that optimization is not run when missing value setting of SortField is competitive
// with after on asc order
final long afterValue = Long.MAX_VALUE;
final int afterDocID = 10 + random().nextInt(1000);
FieldDoc after = new FieldDoc(afterDocID, Float.NaN, new Long[] {afterValue});
final SortField sortField = new SortField("my_field", SortField.Type.LONG);
sortField.setMissingValue(Long.MAX_VALUE); // set a competitive missing value
final Sort sort = new Sort(sortField);
CollectorManager<TopFieldCollector, TopFieldDocs> manager =
TopFieldCollector.createSharedManager(sort, numHits, after, totalHitsThreshold);
TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager);
assertEquals(topDocs.scoreDocs.length, numHits);
assertEquals(
topDocs.totalHits.value,
numDocs); // assert that all documents were collected => optimization was not run
}

{ // test that optimization is not run when missing value setting of SortField is competitive
// with after on desc order
final long afterValue = Long.MAX_VALUE;
final int afterDocID = 10 + random().nextInt(1000);
FieldDoc after = new FieldDoc(afterDocID, Float.NaN, new Long[] {afterValue});
final SortField sortField = new SortField("my_field", SortField.Type.LONG, true);
sortField.setMissingValue(Long.MAX_VALUE); // set a competitive missing value
final Sort sort = new Sort(sortField);
CollectorManager<TopFieldCollector, TopFieldDocs> manager =
TopFieldCollector.createSharedManager(sort, numHits, after, totalHitsThreshold);
TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager);
assertEquals(topDocs.scoreDocs.length, numHits);
assertEquals(
topDocs.totalHits.value,
numDocs); // assert that all documents were collected => optimization was not run
}

reader.close();
dir.close();
}
Expand Down

0 comments on commit 3f1952b

Please sign in to comment.