Skip to content

Commit

Permalink
LUCENE-10089: Disable numeric sort optimization early (#2576)
Browse files Browse the repository at this point in the history
This commit moves the responsibility to disable
the numeric sort optimization on comparators to the SortField.
This way we don't need to apply the logic on every top field collectors.

Co-authored-by: Jim Ferenczi <[email protected]>
  • Loading branch information
2 people authored and dnhatn committed Sep 16, 2021
1 parent b7b9dfb commit bf2fcb5
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,6 @@ private FieldValueHitQueue(SortField[] fields, int size) {
reverseMul[i] = field.reverse ? -1 : 1;
comparators[i] = field.getComparator(size, i);
}
if (numComparators > 0 && fields[0].getCanUsePoints() == false) {
// disable skipping functionality of a numeric comparator if we can't use points
comparators[0].disableSkipping();
}
if (numComparators == 1) {
// inform a comparator that sort is based on this single field
// to enable some optimizations for skipping over non-competitive documents
Expand Down
69 changes: 44 additions & 25 deletions lucene/core/src/java/org/apache/lucene/search/SortField.java
Original file line number Diff line number Diff line change
Expand Up @@ -472,42 +472,61 @@ public Comparator<BytesRef> getBytesComparator() {
* @return {@link FieldComparator} to use when sorting
*/
public FieldComparator<?> getComparator(final int numHits, final int sortPos) {

final FieldComparator<?> fieldComparator;
switch (type) {
case SCORE:
return new FieldComparator.RelevanceComparator(numHits);
case SCORE:
fieldComparator = new FieldComparator.RelevanceComparator(numHits);
break;

case DOC:
return new DocComparator(numHits, reverse, sortPos);
case DOC:
fieldComparator = new DocComparator(numHits, reverse, sortPos);
break;

case INT:
return new IntComparator(numHits, field, (Integer) missingValue, reverse, sortPos);
case INT:
fieldComparator =
new IntComparator(numHits, field, (Integer) missingValue, reverse, sortPos);
break;

case FLOAT:
return new FloatComparator(numHits, field, (Float) missingValue, reverse, sortPos);
case FLOAT:
fieldComparator =
new FloatComparator(numHits, field, (Float) missingValue, reverse, sortPos);
break;

case LONG:
fieldComparator = new LongComparator(numHits, field, (Long) missingValue, reverse, sortPos);
break;

case LONG:
return new LongComparator(numHits, field, (Long) missingValue, reverse, sortPos);
case DOUBLE:
fieldComparator =
new DoubleComparator(numHits, field, (Double) missingValue, reverse, sortPos);
break;

case DOUBLE:
return new DoubleComparator(numHits, field, (Double) missingValue, reverse, sortPos);
case CUSTOM:
assert comparatorSource != null;
fieldComparator = comparatorSource.newComparator(field, numHits, sortPos, reverse);
break;

case CUSTOM:
assert comparatorSource != null;
return comparatorSource.newComparator(field, numHits, sortPos, reverse);
case STRING:
return new FieldComparator.TermOrdValComparator(
numHits, field, missingValue == STRING_LAST);

case STRING:
return new FieldComparator.TermOrdValComparator(numHits, field, missingValue == STRING_LAST);
case STRING_VAL:
fieldComparator =
new FieldComparator.TermValComparator(numHits, field, missingValue == STRING_LAST);
break;

case STRING_VAL:
return new FieldComparator.TermValComparator(numHits, field, missingValue == STRING_LAST);
case REWRITEABLE:
throw new IllegalStateException(
"SortField needs to be rewritten through Sort.rewrite(..) and SortField.rewrite(..)");

case REWRITEABLE:
throw new IllegalStateException("SortField needs to be rewritten through Sort.rewrite(..) and SortField.rewrite(..)");

default:
throw new IllegalStateException("Illegal sort type: " + type);
default:
throw new IllegalStateException("Illegal sort type: " + type);
}
if (getCanUsePoints() == false) {
// disable skipping functionality of a numeric comparator if we can't use points
fieldComparator.disableSkipping();
}
return fieldComparator;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,58 +227,89 @@ public void setMissingValue(Object missingValue) {

@Override
public FieldComparator<?> getComparator(int numHits, int sortPos) {
switch(type) {
final FieldComparator<?> fieldComparator;
switch (type) {
case INT:
return new IntComparator(numHits, getField(), (Integer) missingValue, reverse, sortPos) {
@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
return new IntLeafComparator(context) {
fieldComparator =
new IntComparator(numHits, getField(), (Integer) missingValue, reverse, sortPos) {
@Override
protected NumericDocValues getNumericDocValues(LeafReaderContext context, String field) throws IOException {
return SortedNumericSelector.wrap(DocValues.getSortedNumeric(context.reader(), field), selector, type);
public LeafFieldComparator getLeafComparator(LeafReaderContext context)
throws IOException {
return new IntLeafComparator(context) {
@Override
protected NumericDocValues getNumericDocValues(
LeafReaderContext context, String field) throws IOException {
return SortedNumericSelector.wrap(
DocValues.getSortedNumeric(context.reader(), field), selector, type);
}
};
}
};
}
};
break;
case FLOAT:
return new FloatComparator(numHits, getField(), (Float) missingValue, reverse, sortPos) {
@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
return new FloatLeafComparator(context) {
fieldComparator =
new FloatComparator(numHits, getField(), (Float) missingValue, reverse, sortPos) {
@Override
protected NumericDocValues getNumericDocValues(LeafReaderContext context, String field) throws IOException {
return SortedNumericSelector.wrap(DocValues.getSortedNumeric(context.reader(), field), selector, type);
public LeafFieldComparator getLeafComparator(LeafReaderContext context)
throws IOException {
return new FloatLeafComparator(context) {
@Override
protected NumericDocValues getNumericDocValues(
LeafReaderContext context, String field) throws IOException {
return SortedNumericSelector.wrap(
DocValues.getSortedNumeric(context.reader(), field), selector, type);
}
};
}
};
}
};
break;
case LONG:
return new LongComparator(numHits, getField(), (Long) missingValue, reverse, sortPos) {
@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
return new LongLeafComparator(context) {
fieldComparator =
new LongComparator(numHits, getField(), (Long) missingValue, reverse, sortPos) {
@Override
protected NumericDocValues getNumericDocValues(LeafReaderContext context, String field) throws IOException {
return SortedNumericSelector.wrap(DocValues.getSortedNumeric(context.reader(), field), selector, type);
public LeafFieldComparator getLeafComparator(LeafReaderContext context)
throws IOException {
return new LongLeafComparator(context) {
@Override
protected NumericDocValues getNumericDocValues(
LeafReaderContext context, String field) throws IOException {
return SortedNumericSelector.wrap(
DocValues.getSortedNumeric(context.reader(), field), selector, type);
}
};
}
};
}
};
break;
case DOUBLE:
return new DoubleComparator(numHits, getField(), (Double) missingValue, reverse, sortPos) {
@Override
public LeafFieldComparator getLeafComparator(LeafReaderContext context) throws IOException {
return new DoubleLeafComparator(context) {
fieldComparator =
new DoubleComparator(numHits, getField(), (Double) missingValue, reverse, sortPos) {
@Override
protected NumericDocValues getNumericDocValues(LeafReaderContext context, String field) throws IOException {
return SortedNumericSelector.wrap(DocValues.getSortedNumeric(context.reader(), field), selector, type);
public LeafFieldComparator getLeafComparator(LeafReaderContext context)
throws IOException {
return new DoubleLeafComparator(context) {
@Override
protected NumericDocValues getNumericDocValues(
LeafReaderContext context, String field) throws IOException {
return SortedNumericSelector.wrap(
DocValues.getSortedNumeric(context.reader(), field), selector, type);
}
};
}
};
}
};
break;
case CUSTOM:
case DOC:
case REWRITEABLE:
case STRING_VAL:
case SCORE:
case STRING:
default:
throw new AssertionError();
}
if (getCanUsePoints() == false) {
fieldComparator.disableSkipping();
}
return fieldComparator;
}

private NumericDocValues getValue(LeafReader reader) throws IOException {
Expand Down

0 comments on commit bf2fcb5

Please sign in to comment.