Browse Source

Remove UnsortedNumericDoubleValues (#26817)

Closes #24086
kel 8 years ago
parent
commit
100e3c9a8a

+ 32 - 29
core/src/main/java/org/elasticsearch/index/query/functionscore/DecayFunctionBuilder.java

@@ -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));
                 }
             };
         }

+ 0 - 77
core/src/main/java/org/elasticsearch/search/MultiValueMode.java

@@ -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);

+ 1 - 122
core/src/test/java/org/elasticsearch/search/MultiValueModeTests.java

@@ -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));