Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.index.fielddata;
import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.SortedNumericSelector;
import org.apache.lucene.search.SortedNumericSortField;
import org.elasticsearch.common.time.DateUtils;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.index.fielddata.IndexFieldData.XFieldComparatorSource.Nested;
import org.elasticsearch.index.fielddata.fieldcomparator.DoubleValuesComparatorSource;
import org.elasticsearch.index.fielddata.fieldcomparator.FloatValuesComparatorSource;
import org.elasticsearch.index.fielddata.fieldcomparator.LongValuesComparatorSource;
import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.MultiValueMode;
import org.elasticsearch.search.aggregations.support.CoreValuesSourceType;
import org.elasticsearch.search.aggregations.support.ValuesSourceType;
import org.elasticsearch.search.sort.BucketedSort;
import org.elasticsearch.search.sort.SortOrder;
import java.io.IOException;
import java.util.function.LongUnaryOperator;
/**
* Base class for numeric field data.
*/
public abstract class IndexNumericFieldData implements IndexFieldData {
/**
* The type of number.
*/
public enum NumericType {
BOOLEAN(false, SortField.Type.LONG, CoreValuesSourceType.BOOLEAN),
BYTE(false, SortField.Type.LONG, CoreValuesSourceType.NUMERIC),
SHORT(false, SortField.Type.LONG, CoreValuesSourceType.NUMERIC),
INT(false, SortField.Type.LONG, CoreValuesSourceType.NUMERIC),
LONG(false, SortField.Type.LONG, CoreValuesSourceType.NUMERIC),
DATE(false, SortField.Type.LONG, CoreValuesSourceType.DATE),
DATE_NANOSECONDS(false, SortField.Type.LONG, CoreValuesSourceType.DATE),
HALF_FLOAT(true, SortField.Type.LONG, CoreValuesSourceType.NUMERIC),
FLOAT(true, SortField.Type.FLOAT, CoreValuesSourceType.NUMERIC),
DOUBLE(true, SortField.Type.DOUBLE, CoreValuesSourceType.NUMERIC);
private final boolean floatingPoint;
private final ValuesSourceType valuesSourceType;
private final SortField.Type sortFieldType;
NumericType(boolean floatingPoint, SortField.Type sortFieldType, ValuesSourceType valuesSourceType) {
this.floatingPoint = floatingPoint;
this.sortFieldType = sortFieldType;
this.valuesSourceType = valuesSourceType;
}
public final boolean isFloatingPoint() {
return floatingPoint;
}
public final ValuesSourceType getValuesSourceType() {
return valuesSourceType;
}
}
/**
* The numeric type of this number.
*/
public abstract NumericType getNumericType();
/**
* Returns the {@link SortField} to used for sorting.
* Values are casted to the provided targetNumericType type if it doesn't
* match the field's numericType.
*/
public final SortField sortField(
NumericType targetNumericType,
Object missingValue,
MultiValueMode sortMode,
Nested nested,
boolean reverse
) {
XFieldComparatorSource source = comparatorSource(targetNumericType, missingValue, sortMode, nested);
/*
* Use a SortField with the custom comparator logic if required because
* 1. The underlying data source needs it.
* 2. We need to read the value from a nested field.
* 3. We Aren't using max or min to resolve the duplicates.
* 4. We have to cast the results to another type.
*/
if (sortRequiresCustomComparator()
|| nested != null
|| (sortMode != MultiValueMode.MAX && sortMode != MultiValueMode.MIN)
|| targetNumericType != getNumericType()) {
return new SortField(getFieldName(), source, reverse);
}
SortedNumericSelector.Type selectorType = sortMode == MultiValueMode.MAX
? SortedNumericSelector.Type.MAX
: SortedNumericSelector.Type.MIN;
SortField sortField = new SortedNumericSortField(getFieldName(), getNumericType().sortFieldType, reverse, selectorType);
sortField.setMissingValue(source.missingObject(missingValue, reverse));
return sortField;
}
/**
* Does {@link #sortField} require a custom comparator because of the way
* the data is stored in doc values ({@code true}) or are the docs values
* stored such that they can be sorted without decoding ({@code false}).
*/
protected abstract boolean sortRequiresCustomComparator();
@Override
public final SortField sortField(Object missingValue, MultiValueMode sortMode, Nested nested, boolean reverse) {
return sortField(getNumericType(), missingValue, sortMode, nested, reverse);
}
/**
* Builds a {@linkplain BucketedSort} for the {@code targetNumericType},
* casting the values if their native type doesn't match.
*/
public final BucketedSort newBucketedSort(
NumericType targetNumericType,
BigArrays bigArrays,
@Nullable Object missingValue,
MultiValueMode sortMode,
Nested nested,
SortOrder sortOrder,
DocValueFormat format,
int bucketSize,
BucketedSort.ExtraData extra
) {
return comparatorSource(targetNumericType, missingValue, sortMode, nested).newBucketedSort(
bigArrays,
sortOrder,
format,
bucketSize,
extra
);
}
@Override
public final BucketedSort newBucketedSort(
BigArrays bigArrays,
@Nullable Object missingValue,
MultiValueMode sortMode,
Nested nested,
SortOrder sortOrder,
DocValueFormat format,
int bucketSize,
BucketedSort.ExtraData extra
) {
return newBucketedSort(getNumericType(), bigArrays, missingValue, sortMode, nested, sortOrder, format, bucketSize, extra);
}
/**
* Build a {@link XFieldComparatorSource} matching the parameters.
*/
private XFieldComparatorSource comparatorSource(
NumericType targetNumericType,
@Nullable Object missingValue,
MultiValueMode sortMode,
Nested nested
) {
switch (targetNumericType) {
case HALF_FLOAT:
case FLOAT:
return new FloatValuesComparatorSource(this, missingValue, sortMode, nested);
case DOUBLE:
return new DoubleValuesComparatorSource(this, missingValue, sortMode, nested);
case DATE:
return dateComparatorSource(missingValue, sortMode, nested);
case DATE_NANOSECONDS:
return dateNanosComparatorSource(missingValue, sortMode, nested);
default:
assert targetNumericType.isFloatingPoint() == false;
return new LongValuesComparatorSource(this, missingValue, sortMode, nested, targetNumericType);
}
}
protected XFieldComparatorSource dateComparatorSource(@Nullable Object missingValue, MultiValueMode sortMode, Nested nested) {
return new LongValuesComparatorSource(this, missingValue, sortMode, nested, NumericType.DATE);
}
protected XFieldComparatorSource dateNanosComparatorSource(@Nullable Object missingValue, MultiValueMode sortMode, Nested nested) {
return new LongValuesComparatorSource(
this,
missingValue,
sortMode,
nested,
dvs -> convertNumeric(dvs, DateUtils::toNanoSeconds),
NumericType.DATE_NANOSECONDS
);
}
/**
* Convert the values in dvs using the provided converter.
*/
protected static SortedNumericDocValues convertNumeric(SortedNumericDocValues values, LongUnaryOperator converter) {
return new AbstractSortedNumericDocValues() {
@Override
public boolean advanceExact(int target) throws IOException {
return values.advanceExact(target);
}
@Override
public long nextValue() throws IOException {
return converter.applyAsLong(values.nextValue());
}
@Override
public int docValueCount() {
return values.docValueCount();
}
@Override
public int nextDoc() throws IOException {
return values.nextDoc();
}
};
}
}