Skip to content

Commit

Permalink
Address MinAndMax generics warnings
Browse files Browse the repository at this point in the history
The MinAndMax encapsulates min and max values for a shard. It uses generics to make sure that the values are of the same type and are also comparable. Though there are warnings whenever this class is currently used, which are addressed with this commit.

Relates to elastic#49092
  • Loading branch information
javanna committed Feb 21, 2020
1 parent cb9be14 commit 409f760
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ private static List<SearchShardIterator> sortShards(GroupShardsIterator<SearchSh
return IntStream.range(0, shardsIts.size())
.boxed()
.sorted(shardComparator(shardsIts, minAndMaxes, order))
.map(ord -> shardsIts.get(ord))
.map(shardsIts::get)
.collect(Collectors.toList());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ public static FieldSortBuilder getPrimaryFieldSortOrNull(SearchSourceBuilder sou
* {@link SortField}. This is needed for {@link SortField} that converts values from one type to another using
* {@link FieldSortBuilder#setNumericType(String)} )} (e.g.: long to double).
*/
private static Function<byte[], Comparable> numericPointConverter(SortField sortField, NumberFieldType numberFieldType) {
private static Function<byte[], Comparable<?>> numericPointConverter(SortField sortField, NumberFieldType numberFieldType) {
switch (IndexSortConfig.getSortFieldType(sortField)) {
case LONG:
return v -> numberFieldType.parsePoint(v).longValue();
Expand All @@ -457,7 +457,7 @@ private static Function<byte[], Comparable> numericPointConverter(SortField sort
* Return a {@link Function} that converts a serialized date point into a {@link Long} according to the provided
* {@link NumericType}.
*/
private static Function<byte[], Comparable> datePointConverter(DateFieldType dateFieldType, String numericTypeStr) {
private static Function<byte[], Comparable<?>> datePointConverter(DateFieldType dateFieldType, String numericTypeStr) {
if (numericTypeStr != null) {
NumericType numericType = resolveNumericType(numericTypeStr);
if (dateFieldType.resolution() == MILLISECONDS && numericType == NumericType.DATE_NANOSECONDS) {
Expand Down Expand Up @@ -491,7 +491,7 @@ public static MinAndMax<?> getMinMaxOrNull(QueryShardContext context, FieldSortB
case INT:
case DOUBLE:
case FLOAT:
final Function<byte[], Comparable> converter;
final Function<byte[], Comparable<?>> converter;
if (fieldType instanceof NumberFieldType) {
converter = numericPointConverter(sortField, (NumberFieldType) fieldType);
} else if (fieldType instanceof DateFieldType) {
Expand All @@ -502,9 +502,7 @@ public static MinAndMax<?> getMinMaxOrNull(QueryShardContext context, FieldSortB
if (PointValues.size(reader, fieldName) == 0) {
return null;
}
final Comparable min = converter.apply(PointValues.getMinPackedValue(reader, fieldName));
final Comparable max = converter.apply(PointValues.getMaxPackedValue(reader, fieldName));
return MinAndMax.newMinMax(min, max);
return extractMinAndMax(reader, fieldName, converter);

case STRING:
case STRING_VAL:
Expand All @@ -520,6 +518,14 @@ public static MinAndMax<?> getMinMaxOrNull(QueryShardContext context, FieldSortB
return null;
}

@SuppressWarnings("unchecked")
private static <T extends Comparable<T>> MinAndMax<T> extractMinAndMax(IndexReader reader, String fieldName,
Function<byte[], Comparable<?>> converter) throws IOException {
final T min = (T)converter.apply(PointValues.getMinPackedValue(reader, fieldName));
final T max = (T)converter.apply(PointValues.getMaxPackedValue(reader, fieldName));
return MinAndMax.newMinMax(min, max);
}

/**
* Throws an exception if max children is not located at top level nested sort.
*/
Expand Down Expand Up @@ -601,12 +607,12 @@ public static FieldSortBuilder fromXContent(XContentParser parser, String fieldN
private static final ObjectParser<FieldSortBuilder, Void> PARSER = new ObjectParser<>(NAME);

static {
PARSER.declareField(FieldSortBuilder::missing, p -> p.objectText(), MISSING, ValueType.VALUE);
PARSER.declareField(FieldSortBuilder::missing, XContentParser::objectText, MISSING, ValueType.VALUE);
PARSER.declareString(FieldSortBuilder::unmappedType , UNMAPPED_TYPE);
PARSER.declareString((b, v) -> b.order(SortOrder.fromString(v)) , ORDER_FIELD);
PARSER.declareString((b, v) -> b.sortMode(SortMode.fromString(v)), SORT_MODE);
PARSER.declareObject(FieldSortBuilder::setNestedSort, (p, c) -> NestedSortBuilder.fromXContent(p), NESTED_FIELD);
PARSER.declareString((b, v) -> b.setNumericType(v), NUMERIC_TYPE);
PARSER.declareString(FieldSortBuilder::setNumericType, NUMERIC_TYPE);
}

@Override
Expand Down
20 changes: 11 additions & 9 deletions server/src/main/java/org/elasticsearch/search/sort/MinAndMax.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
import java.util.Objects;

/**
* A class that encapsulates a minimum and a maximum {@link Comparable}.
* A class that encapsulates a minimum and a maximum, that are of the same type and {@link Comparable}.
*/
public class MinAndMax<T extends Comparable<? super T>> implements Writeable {
public class MinAndMax<T extends Comparable<T>> implements Writeable {
private final T minValue;
private final T maxValue;

Expand All @@ -40,9 +40,10 @@ private MinAndMax(T minValue, T maxValue) {
this.maxValue = Objects.requireNonNull(maxValue);
}

@SuppressWarnings("unchecked")
public MinAndMax(StreamInput in) throws IOException {
this.minValue = (T) Lucene.readSortValue(in);
this.maxValue = (T) Lucene.readSortValue(in);
this.minValue = (T)Lucene.readSortValue(in);
this.maxValue = (T)Lucene.readSortValue(in);
}

@Override
Expand All @@ -54,27 +55,28 @@ public void writeTo(StreamOutput out) throws IOException {
/**
* Return the minimum value.
*/
public T getMin() {
T getMin() {
return minValue;
}

/**
* Return the maximum value.
*/
public T getMax() {
T getMax() {
return maxValue;
}

public static <T extends Comparable<? super T>> MinAndMax<T> newMinMax(T min, T max) {
public static <T extends Comparable<T>> MinAndMax<T> newMinMax(T min, T max) {
return new MinAndMax<>(min, max);
}

/**
* Return a {@link Comparator} for {@link MinAndMax} values according to the provided {@link SortOrder}.
*/
public static Comparator<MinAndMax<?>> getComparator(SortOrder order) {
Comparator<MinAndMax> cmp = order == SortOrder.ASC ?
Comparator.comparing(v -> (Comparable) v.getMin()) : Comparator.comparing(v -> (Comparable) v.getMax());
Comparator<MinAndMax<?>> cmp = order == SortOrder.ASC ?
Comparator.comparing(MinAndMax::getMin) : Comparator.comparing(MinAndMax::getMax);

if (order == SortOrder.DESC) {
cmp = cmp.reversed();
}
Expand Down

0 comments on commit 409f760

Please sign in to comment.