Remove UnsortedNumericDoubleValues (#26817)

Closes #24086
This commit is contained in:
kel 2017-10-06 09:31:50 -05:00 committed by Adrien Grand
parent 16431a6601
commit 100e3c9a8a
3 changed files with 33 additions and 228 deletions

View File

@ -43,8 +43,9 @@ import org.elasticsearch.index.fielddata.IndexNumericFieldData;
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
import org.elasticsearch.index.fielddata.NumericDoubleValues;
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
import org.elasticsearch.index.mapper.GeoPointFieldMapper.GeoPointFieldType;
import org.elasticsearch.index.fielddata.SortingNumericDoubleValues;
import org.elasticsearch.index.mapper.DateFieldMapper;
import org.elasticsearch.index.mapper.GeoPointFieldMapper.GeoPointFieldType;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.NumberFieldMapper;
import org.elasticsearch.index.query.QueryShardContext;
@ -346,22 +347,23 @@ public abstract class DecayFunctionBuilder<DFB extends DecayFunctionBuilder<DFB>
@Override
protected NumericDoubleValues distance(LeafReaderContext context) {
final MultiGeoPointValues geoPointValues = fieldData.load(context).getGeoPointValues();
return mode.select(new MultiValueMode.UnsortedNumericDoubleValues() {
@Override
public int docValueCount() {
return geoPointValues.docValueCount();
}
return mode.select(new SortingNumericDoubleValues() {
@Override
public boolean advanceExact(int docId) throws IOException {
return geoPointValues.advanceExact(docId);
}
@Override
public double nextValue() throws IOException {
GeoPoint other = geoPointValues.nextValue();
return Math.max(0.0d,
distFunction.calculate(origin.lat(), origin.lon(), other.lat(), other.lon(), DistanceUnit.METERS) - offset);
if (geoPointValues.advanceExact(docId)) {
int n = geoPointValues.docValueCount();
resize(n);
for (int i = 0; i < n; i++) {
GeoPoint other = geoPointValues.nextValue();
double distance = distFunction.calculate(
origin.lat(), origin.lon(), other.lat(), other.lon(), DistanceUnit.METERS);
values[i] = Math.max(0.0d, distance - offset);
}
sort();
return true;
} else {
return false;
}
}
}, 0.0);
}
@ -427,20 +429,20 @@ public abstract class DecayFunctionBuilder<DFB extends DecayFunctionBuilder<DFB>
@Override
protected NumericDoubleValues distance(LeafReaderContext context) {
final SortedNumericDoubleValues doubleValues = fieldData.load(context).getDoubleValues();
return mode.select(new MultiValueMode.UnsortedNumericDoubleValues() {
return mode.select(new SortingNumericDoubleValues() {
@Override
public int docValueCount() {
return doubleValues.docValueCount();
}
@Override
public boolean advanceExact(int doc) throws IOException {
return doubleValues.advanceExact(doc);
}
@Override
public double nextValue() throws IOException {
return Math.max(0.0d, Math.abs(doubleValues.nextValue() - origin) - offset);
public boolean advanceExact(int docId) throws IOException {
if (doubleValues.advanceExact(docId)) {
int n = doubleValues.docValueCount();
resize(n);
for (int i = 0; i < n; i++) {
values[i] = Math.max(0.0d, Math.abs(doubleValues.nextValue() - origin) - offset);
}
sort();
return true;
} else {
return false;
}
}
}, 0.0);
}
@ -542,10 +544,11 @@ public abstract class DecayFunctionBuilder<DFB extends DecayFunctionBuilder<DFB>
if (distance.advanceExact(docId) == false) {
return Explanation.noMatch("No value for the distance");
}
double value = distance.doubleValue();
return Explanation.match(
(float) score(docId, subQueryScore.getValue()),
"Function for field " + getFieldName() + ":",
func.explainFunction(getDistanceString(ctx, docId), distance.doubleValue(), scale));
func.explainFunction(getDistanceString(ctx, docId), value, scale));
}
};
}

View File

@ -104,16 +104,6 @@ public enum MultiValueMode implements Writeable {
}
return totalCount > 0 ? totalValue : missingValue;
}
@Override
protected double pick(UnsortedNumericDoubleValues values) throws IOException {
final int count = values.docValueCount();
double total = 0;
for (int index = 0; index < count; ++index) {
total += values.nextValue();
}
return total;
}
},
/**
@ -177,16 +167,6 @@ public enum MultiValueMode implements Writeable {
}
return totalValue/totalCount;
}
@Override
protected double pick(UnsortedNumericDoubleValues values) throws IOException {
final int count = values.docValueCount();
double total = 0;
for (int index = 0; index < count; ++index) {
total += values.nextValue();
}
return total/count;
}
},
/**
@ -303,16 +283,6 @@ public enum MultiValueMode implements Writeable {
}
return hasValue ? ord : -1;
}
@Override
protected double pick(UnsortedNumericDoubleValues values) throws IOException {
int count = values.docValueCount();
double min = Double.POSITIVE_INFINITY;
for (int index = 0; index < count; ++index) {
min = Math.min(values.nextValue(), min);
}
return min;
}
},
/**
@ -419,16 +389,6 @@ public enum MultiValueMode implements Writeable {
}
return ord;
}
@Override
protected double pick(UnsortedNumericDoubleValues values) throws IOException {
int count = values.docValueCount();
double max = Double.NEGATIVE_INFINITY;
for (int index = 0; index < count; ++index) {
max = Math.max(values.nextValue(), max);
}
return max;
}
};
/**
@ -905,43 +865,6 @@ public enum MultiValueMode implements Writeable {
throw new IllegalArgumentException("Unsupported sort mode: " + this);
}
/**
* Return a {@link NumericDoubleValues} instance that can be used to sort documents
* with this mode and the provided values. When a document has no value,
* <code>missingValue</code> is returned.
*
* Allowed Modes: SUM, AVG, MIN, MAX
*/
public NumericDoubleValues select(final UnsortedNumericDoubleValues values, final double missingValue) {
return new NumericDoubleValues() {
private boolean hasValue;
@Override
public boolean advanceExact(int doc) throws IOException {
hasValue = values.advanceExact(doc);
return true;
}
@Override
public double doubleValue() throws IOException {
return hasValue ? pick(values) : missingValue;
}
};
}
protected double pick(UnsortedNumericDoubleValues values) throws IOException {
throw new IllegalArgumentException("Unsupported sort mode: " + this);
}
/**
* Interface allowing custom value generators to be used in MultiValueMode.
*/
// TODO: why do we need it???
public interface UnsortedNumericDoubleValues {
boolean advanceExact(int doc) throws IOException;
int docValueCount() throws IOException;
double nextValue() throws IOException;
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeEnum(this);

View File

@ -41,7 +41,6 @@ import org.elasticsearch.index.fielddata.FieldData;
import org.elasticsearch.index.fielddata.NumericDoubleValues;
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
import org.elasticsearch.search.MultiValueMode.UnsortedNumericDoubleValues;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
@ -92,7 +91,7 @@ public class MultiValueModeTests extends ESTestCase {
docsWithValue.set(i);
}
}
final Supplier<SortedNumericDocValues> multiValues = () -> DocValues.singleton(new AbstractNumericDocValues() {
int docId = -1;
@Override
@ -711,126 +710,6 @@ public class MultiValueModeTests extends ESTestCase {
}
}
public void testUnsortedSingleValuedDoubles() throws Exception {
final int numDocs = scaledRandomIntBetween(1, 100);
final double[] array = new double[numDocs];
final FixedBitSet docsWithValue = randomBoolean() ? null : new FixedBitSet(numDocs);
for (int i = 0; i < array.length; ++i) {
if (randomBoolean()) {
array[i] = randomDouble();
if (docsWithValue != null) {
docsWithValue.set(i);
}
} else if (docsWithValue != null && randomBoolean()) {
docsWithValue.set(i);
}
}
final NumericDoubleValues singleValues = new NumericDoubleValues() {
private int docID;
@Override
public boolean advanceExact(int doc) throws IOException {
docID = doc;
return docsWithValue == null || docsWithValue.get(docID);
}
@Override
public double doubleValue() {
return array[docID];
}
};
final SortedNumericDoubleValues singletonValues = FieldData.singleton(singleValues);
final MultiValueMode.UnsortedNumericDoubleValues multiValues = new MultiValueMode.UnsortedNumericDoubleValues() {
@Override
public int docValueCount() {
return singletonValues.docValueCount();
}
@Override
public boolean advanceExact(int doc) throws IOException {
return singletonValues.advanceExact(doc);
}
@Override
public double nextValue() throws IOException {
return Math.cos(singletonValues.nextValue());
}
};
verifyUnsortedNumeric(() -> multiValues, numDocs);
}
public void testUnsortedMultiValuedDoubles() throws Exception {
final int numDocs = scaledRandomIntBetween(1, 100);
final double[][] array = new double[numDocs][];
for (int i = 0; i < numDocs; ++i) {
final double[] values = new double[randomInt(4)];
for (int j = 0; j < values.length; ++j) {
values[j] = randomDouble();
}
Arrays.sort(values);
array[i] = values;
}
final MultiValueMode.UnsortedNumericDoubleValues multiValues = new MultiValueMode.UnsortedNumericDoubleValues() {
int doc;
int i;
@Override
public int docValueCount() {
return array[doc].length;
}
@Override
public boolean advanceExact(int doc) {
this.doc = doc;
i = 0;
return array[doc].length > 0;
}
@Override
public double nextValue() {
return Math.sin(array[doc][i++]);
}
};
verifyUnsortedNumeric(() -> multiValues, numDocs);
}
private void verifyUnsortedNumeric(Supplier<MultiValueMode.UnsortedNumericDoubleValues> supplier, int maxDoc) throws IOException {
for (double missingValue : new double[] { 0, randomDouble() }) {
for (MultiValueMode mode : new MultiValueMode[] {MultiValueMode.MIN, MultiValueMode.MAX, MultiValueMode.SUM, MultiValueMode.AVG}) {
UnsortedNumericDoubleValues values = supplier.get();
final NumericDoubleValues selected = mode.select(values, missingValue);
for (int i = 0; i < maxDoc; ++i) {
assertTrue(selected.advanceExact(i));
final double actual = selected.doubleValue();
double expected = 0.0;
if (values.advanceExact(i) == false) {
expected = missingValue;
} else {
int numValues = values.docValueCount();
if (mode == MultiValueMode.MAX) {
expected = Long.MIN_VALUE;
} else if (mode == MultiValueMode.MIN) {
expected = Long.MAX_VALUE;
}
for (int j = 0; j < numValues; ++j) {
if (mode == MultiValueMode.SUM || mode == MultiValueMode.AVG) {
expected += values.nextValue();
} else if (mode == MultiValueMode.MIN) {
expected = Math.min(expected, values.nextValue());
} else if (mode == MultiValueMode.MAX) {
expected = Math.max(expected, values.nextValue());
}
}
if (mode == MultiValueMode.AVG) {
expected = expected/numValues;
}
}
assertEquals(mode.toString() + " docId=" + i, expected, actual, 0.1);
}
}
}
}
public void testValidOrdinals() {
assertThat(MultiValueMode.SUM.ordinal(), equalTo(0));
assertThat(MultiValueMode.AVG.ordinal(), equalTo(1));