Calculate and cache result when advanceExact is called (#26920)

Cache final result instead of result of advanceExact.
Fix SortedNumericDoubleValues does not test MEDIAN mode
Replace deprecated random string generation method
This commit is contained in:
kel 2017-10-09 07:02:38 -05:00 committed by Adrien Grand
parent 19dc629e6d
commit 1d4f70210f
2 changed files with 66 additions and 29 deletions

View File

@ -416,11 +416,11 @@ public enum MultiValueMode implements Writeable {
if (singleton != null) {
return new AbstractNumericDocValues() {
private boolean hasValue;
private long value;
@Override
public boolean advanceExact(int target) throws IOException {
hasValue = singleton.advanceExact(target);
this.value = singleton.advanceExact(target) ? singleton.longValue() : missingValue;
return true;
}
@ -431,17 +431,17 @@ public enum MultiValueMode implements Writeable {
@Override
public long longValue() throws IOException {
return hasValue ? singleton.longValue() : missingValue;
return this.value;
}
};
} else {
return new AbstractNumericDocValues() {
private boolean hasValue;
private long value;
@Override
public boolean advanceExact(int target) throws IOException {
hasValue = values.advanceExact(target);
this.value = values.advanceExact(target) ? pick(values) : missingValue;
return true;
}
@ -452,7 +452,7 @@ public enum MultiValueMode implements Writeable {
@Override
public long longValue() throws IOException {
return hasValue ? pick(values) : missingValue;
return value;
}
};
}
@ -533,35 +533,33 @@ public enum MultiValueMode implements Writeable {
final NumericDoubleValues singleton = FieldData.unwrapSingleton(values);
if (singleton != null) {
return new NumericDoubleValues() {
private boolean hasValue;
private double value;
@Override
public boolean advanceExact(int doc) throws IOException {
hasValue = singleton.advanceExact(doc);
this.value = singleton.advanceExact(doc) ? singleton.doubleValue() : missingValue;
return true;
}
@Override
public double doubleValue() throws IOException {
return hasValue ? singleton.doubleValue() : missingValue;
return this.value;
}
};
} else {
return new NumericDoubleValues() {
private boolean hasValue;
private double value;
@Override
public boolean advanceExact(int target) throws IOException {
hasValue = values.advanceExact(target);
value = values.advanceExact(target) ? pick(values) : missingValue;
return true;
}
@Override
public double doubleValue() throws IOException {
return hasValue ? pick(values) : missingValue;
return this.value;
}
};
}
@ -638,17 +636,17 @@ public enum MultiValueMode implements Writeable {
}
return new AbstractBinaryDocValues() {
private boolean hasValue;
private BytesRef value;
@Override
public boolean advanceExact(int target) throws IOException {
hasValue = singleton.advanceExact(target);
this.value = singleton.advanceExact(target) ? singleton.binaryValue() : missingValue;
return true;
}
@Override
public BytesRef binaryValue() throws IOException {
return hasValue ? singleton.binaryValue() : missingValue;
return this.value;
}
};
} else {

View File

@ -19,8 +19,6 @@
package org.elasticsearch.search;
import com.carrotsearch.randomizedtesting.generators.RandomStrings;
import org.apache.lucene.index.BinaryDocValues;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.NumericDocValues;
@ -160,6 +158,8 @@ public class MultiValueModeTests extends ESTestCase {
for (int i = 0; i < maxDoc; ++i) {
assertTrue(selected.advanceExact(i));
final long actual = selected.longValue();
verifyLongValueCanCalledMoreThanOnce(selected, actual);
long expected = 0;
if (values.advanceExact(i) == false) {
expected = missingValue;
@ -203,6 +203,12 @@ public class MultiValueModeTests extends ESTestCase {
}
}
private void verifyLongValueCanCalledMoreThanOnce(NumericDocValues values, long expected) throws IOException {
for (int j = 0, numCall = randomIntBetween(1, 10); j < numCall; j++) {
assertEquals(expected, values.longValue());
}
}
private void verifySortedNumeric(Supplier<SortedNumericDocValues> supplier, int maxDoc, FixedBitSet rootDocs, FixedBitSet innerDocs) throws IOException {
for (long missingValue : new long[] { 0, randomLong() }) {
for (MultiValueMode mode : new MultiValueMode[] {MultiValueMode.MIN, MultiValueMode.MAX, MultiValueMode.SUM, MultiValueMode.AVG}) {
@ -212,6 +218,8 @@ public class MultiValueModeTests extends ESTestCase {
for (int root = rootDocs.nextSetBit(0); root != -1; root = root + 1 < maxDoc ? rootDocs.nextSetBit(root + 1) : -1) {
assertTrue(selected.advanceExact(root));
final long actual = selected.longValue();
verifyLongValueCanCalledMoreThanOnce(selected, actual);
long expected = 0;
if (mode == MultiValueMode.MAX) {
expected = Long.MIN_VALUE;
@ -320,14 +328,13 @@ public class MultiValueModeTests extends ESTestCase {
private void verifySortedNumericDouble(Supplier<SortedNumericDoubleValues> supplier, int maxDoc) throws IOException {
for (long missingValue : new long[] { 0, randomLong() }) {
for (MultiValueMode mode : MultiValueMode.values()) {
if (MultiValueMode.MEDIAN.equals(mode)) {
continue;
}
SortedNumericDoubleValues 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();
verifyDoubleValueCanCalledMoreThanOnce(selected, actual);
double expected = 0.0;
if (values.advanceExact(i) == false) {
expected = missingValue;
@ -371,6 +378,12 @@ public class MultiValueModeTests extends ESTestCase {
}
}
private void verifyDoubleValueCanCalledMoreThanOnce(NumericDoubleValues values, double expected) throws IOException {
for (int j = 0, numCall = randomIntBetween(1, 10); j < numCall; j++) {
assertTrue(Double.compare(values.doubleValue(), expected) == 0);
}
}
private void verifySortedNumericDouble(Supplier<SortedNumericDoubleValues> supplier, int maxDoc, FixedBitSet rootDocs, FixedBitSet innerDocs) throws IOException {
for (long missingValue : new long[] { 0, randomLong() }) {
for (MultiValueMode mode : new MultiValueMode[] {MultiValueMode.MIN, MultiValueMode.MAX, MultiValueMode.SUM, MultiValueMode.AVG}) {
@ -379,7 +392,9 @@ public class MultiValueModeTests extends ESTestCase {
int prevRoot = -1;
for (int root = rootDocs.nextSetBit(0); root != -1; root = root + 1 < maxDoc ? rootDocs.nextSetBit(root + 1) : -1) {
assertTrue(selected.advanceExact(root));
final double actual = selected.doubleValue();;
final double actual = selected.doubleValue();
verifyDoubleValueCanCalledMoreThanOnce(selected, actual);
double expected = 0.0;
if (mode == MultiValueMode.MAX) {
expected = Long.MIN_VALUE;
@ -421,7 +436,7 @@ public class MultiValueModeTests extends ESTestCase {
final FixedBitSet docsWithValue = randomBoolean() ? null : new FixedBitSet(numDocs);
for (int i = 0; i < array.length; ++i) {
if (randomBoolean()) {
array[i] = new BytesRef(RandomStrings.randomAsciiOfLength(random(), 8));
array[i] = new BytesRef(randomAlphaOfLengthBetween(8, 8));
if (docsWithValue != null) {
docsWithValue.set(i);
}
@ -456,7 +471,7 @@ public class MultiValueModeTests extends ESTestCase {
for (int i = 0; i < numDocs; ++i) {
final BytesRef[] values = new BytesRef[randomInt(4)];
for (int j = 0; j < values.length; ++j) {
values[j] = new BytesRef(RandomStrings.randomAsciiOfLength(random(), 8));
values[j] = new BytesRef(randomAlphaOfLengthBetween(8, 8));
}
Arrays.sort(values);
array[i] = values;
@ -489,13 +504,15 @@ public class MultiValueModeTests extends ESTestCase {
}
private void verifySortedBinary(Supplier<SortedBinaryDocValues> supplier, int maxDoc) throws IOException {
for (BytesRef missingValue : new BytesRef[] { new BytesRef(), new BytesRef(RandomStrings.randomAsciiOfLength(random(), 8)) }) {
for (BytesRef missingValue : new BytesRef[] { new BytesRef(), new BytesRef(randomAlphaOfLengthBetween(8, 8)) }) {
for (MultiValueMode mode : new MultiValueMode[] {MultiValueMode.MIN, MultiValueMode.MAX}) {
SortedBinaryDocValues values = supplier.get();
final BinaryDocValues selected = mode.select(values, missingValue);
for (int i = 0; i < maxDoc; ++i) {
assertTrue(selected.advanceExact(i));
final BytesRef actual = selected.binaryValue();
verifyBinaryValueCanCalledMoreThanOnce(selected, actual);
BytesRef expected = null;
if (values.advanceExact(i) == false) {
expected = missingValue;
@ -524,8 +541,14 @@ public class MultiValueModeTests extends ESTestCase {
}
}
private void verifyBinaryValueCanCalledMoreThanOnce(BinaryDocValues values, BytesRef expected) throws IOException {
for (int j = 0, numCall = randomIntBetween(1, 10); j < numCall; j++) {
assertEquals(values.binaryValue(), expected);
}
}
private void verifySortedBinary(Supplier<SortedBinaryDocValues> supplier, int maxDoc, FixedBitSet rootDocs, FixedBitSet innerDocs) throws IOException {
for (BytesRef missingValue : new BytesRef[] { new BytesRef(), new BytesRef(RandomStrings.randomAsciiOfLength(random(), 8)) }) {
for (BytesRef missingValue : new BytesRef[] { new BytesRef(), new BytesRef(randomAlphaOfLengthBetween(8, 8)) }) {
for (MultiValueMode mode : new MultiValueMode[] {MultiValueMode.MIN, MultiValueMode.MAX}) {
SortedBinaryDocValues values = supplier.get();
final BinaryDocValues selected = mode.select(values, missingValue, rootDocs, new BitSetIterator(innerDocs, 0L), maxDoc);
@ -533,6 +556,8 @@ public class MultiValueModeTests extends ESTestCase {
for (int root = rootDocs.nextSetBit(0); root != -1; root = root + 1 < maxDoc ? rootDocs.nextSetBit(root + 1) : -1) {
assertTrue(selected.advanceExact(root));
final BytesRef actual = selected.binaryValue();
verifyBinaryValueCanCalledMoreThanOnce(selected, actual);
BytesRef expected = null;
for (int child = innerDocs.nextSetBit(prevRoot + 1); child != -1 && child < root; child = innerDocs.nextSetBit(child + 1)) {
if (values.advanceExact(child)) {
@ -658,7 +683,11 @@ public class MultiValueModeTests extends ESTestCase {
SortedSetDocValues values = supplier.get();
final SortedDocValues selected = mode.select(values);
for (int i = 0; i < maxDoc; ++i) {
final long actual = selected.advanceExact(i) ? selected.ordValue() : -1;
long actual = -1;
if (selected.advanceExact(i)) {
actual = selected.ordValue();
verifyOrdValueCanCalledMoreThanOnce(selected, selected.ordValue());
}
int expected = -1;
if (values.advanceExact(i)) {
for (long ord = values.nextOrd(); ord != SortedSetDocValues.NO_MORE_ORDS; ord = values.nextOrd()) {
@ -679,13 +708,23 @@ public class MultiValueModeTests extends ESTestCase {
}
}
private void verifyOrdValueCanCalledMoreThanOnce(SortedDocValues values, long expected) throws IOException {
for (int j = 0, numCall = randomIntBetween(1, 10); j < numCall; j++) {
assertEquals(values.ordValue(), expected);
}
}
private void verifySortedSet(Supplier<SortedSetDocValues> supplier, int maxDoc, FixedBitSet rootDocs, FixedBitSet innerDocs) throws IOException {
for (MultiValueMode mode : new MultiValueMode[] {MultiValueMode.MIN, MultiValueMode.MAX}) {
SortedSetDocValues values = supplier.get();
final SortedDocValues selected = mode.select(values, rootDocs, new BitSetIterator(innerDocs, 0L));
int prevRoot = -1;
for (int root = rootDocs.nextSetBit(0); root != -1; root = root + 1 < maxDoc ? rootDocs.nextSetBit(root + 1) : -1) {
final int actual = selected.advanceExact(root) ? selected.ordValue() : -1;
int actual = -1;
if (selected.advanceExact(root)) {
actual = selected.ordValue();
verifyOrdValueCanCalledMoreThanOnce(selected, actual);
}
int expected = -1;
for (int child = innerDocs.nextSetBit(prevRoot + 1); child != -1 && child < root; child = innerDocs.nextSetBit(child + 1)) {
if (values.advanceExact(child)) {