Don't use the fixed bitset filter cache for child nested level filters, but the regular filter cache instead.

Random access based bitsets are not required for the child level nested level filters.

Closes #8810
This commit is contained in:
Martijn van Groningen 2015-01-08 16:05:44 +01:00
parent b2b7506ace
commit 16446440e4
10 changed files with 222 additions and 123 deletions

View File

@ -129,9 +129,11 @@ public interface IndexFieldData<FD extends AtomicFieldData> extends IndexCompone
* parent + 1, or 0 if there is no previous parent, and R (excluded).
*/
public static class Nested {
private final BitDocIdSetFilter rootFilter, innerFilter;
public Nested(BitDocIdSetFilter rootFilter, BitDocIdSetFilter innerFilter) {
private final BitDocIdSetFilter rootFilter;
private final Filter innerFilter;
public Nested(BitDocIdSetFilter rootFilter, Filter innerFilter) {
this.rootFilter = rootFilter;
this.innerFilter = innerFilter;
}
@ -144,10 +146,10 @@ public interface IndexFieldData<FD extends AtomicFieldData> extends IndexCompone
}
/**
* Get a {@link BitDocIdSet} that matches the inner documents.
* Get a {@link DocIdSet} that matches the inner documents.
*/
public BitDocIdSet innerDocs(LeafReaderContext ctx) throws IOException {
return innerFilter.getDocIdSet(ctx);
public DocIdSet innerDocs(LeafReaderContext ctx) throws IOException {
return innerFilter.getDocIdSet(ctx, null);
}
}

View File

@ -23,6 +23,7 @@ import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.BinaryDocValues;
import org.apache.lucene.index.RandomAccessOrds;
import org.apache.lucene.index.SortedDocValues;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.SortField;
@ -81,7 +82,7 @@ public class BytesRefFieldComparatorSource extends IndexFieldData.XFieldComparat
selectedValues = sortMode.select(values);
} else {
final BitSet rootDocs = nested.rootDocs(context).bits();
final BitSet innerDocs = nested.innerDocs(context).bits();
final DocIdSet innerDocs = nested.innerDocs(context);
selectedValues = sortMode.select(values, rootDocs, innerDocs);
}
if (sortMissingFirst(missingValue) || sortMissingLast(missingValue)) {
@ -132,7 +133,7 @@ public class BytesRefFieldComparatorSource extends IndexFieldData.XFieldComparat
selectedValues = sortMode.select(values, nonNullMissingBytes);
} else {
final BitSet rootDocs = nested.rootDocs(context).bits();
final BitSet innerDocs = nested.innerDocs(context).bits();
final DocIdSet innerDocs = nested.innerDocs(context);
selectedValues = sortMode.select(values, nonNullMissingBytes, rootDocs, innerDocs, context.reader().maxDoc());
}
return selectedValues;

View File

@ -21,6 +21,7 @@ package org.elasticsearch.index.fielddata.fieldcomparator;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.SortField;
@ -78,7 +79,7 @@ public class DoubleValuesComparatorSource extends IndexFieldData.XFieldComparato
selectedValues = sortMode.select(values, dMissingValue);
} else {
final BitSet rootDocs = nested.rootDocs(context).bits();
final BitSet innerDocs = nested.innerDocs(context).bits();
final DocIdSet innerDocs = nested.innerDocs(context);
selectedValues = sortMode.select(values, dMissingValue, rootDocs, innerDocs, context.reader().maxDoc());
}
return selectedValues.getRawDoubleValues();

View File

@ -20,6 +20,7 @@ package org.elasticsearch.index.fielddata.fieldcomparator;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.SortField;
import org.apache.lucene.util.BitSet;
@ -70,7 +71,7 @@ public class FloatValuesComparatorSource extends IndexFieldData.XFieldComparator
selectedValues = sortMode.select(values, dMissingValue);
} else {
final BitSet rootDocs = nested.rootDocs(context).bits();
final BitSet innerDocs = nested.innerDocs(context).bits();
final DocIdSet innerDocs = nested.innerDocs(context);
selectedValues = sortMode.select(values, dMissingValue, rootDocs, innerDocs, context.reader().maxDoc());
}
return selectedValues.getRawFloatValues();

View File

@ -21,6 +21,7 @@ package org.elasticsearch.index.fielddata.fieldcomparator;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.index.SortedNumericDocValues;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.SortField;
import org.apache.lucene.util.BitSet;
@ -69,7 +70,7 @@ public class LongValuesComparatorSource extends IndexFieldData.XFieldComparatorS
selectedValues = sortMode.select(values, dMissingValue);
} else {
final BitSet rootDocs = nested.rootDocs(context).bits();
final BitSet innerDocs = nested.innerDocs(context).bits();
final DocIdSet innerDocs = nested.innerDocs(context);
selectedValues = sortMode.select(values, dMissingValue, rootDocs, innerDocs, context.reader().maxDoc());
}
return selectedValues;

View File

@ -21,6 +21,8 @@
package org.elasticsearch.search;
import org.apache.lucene.index.*;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BitSet;
import org.apache.lucene.util.BytesRef;
@ -31,6 +33,7 @@ import org.elasticsearch.index.fielddata.NumericDoubleValues;
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
import java.io.IOException;
import java.util.Locale;
/**
@ -438,39 +441,61 @@ public enum MultiValueMode {
*
* NOTE: Calling the returned instance on docs that are not root docs is illegal
*/
// TODO: technically innerDocs need not be BitSet: only needs advance() ?
public NumericDocValues select(final SortedNumericDocValues values, final long missingValue, final BitSet rootDocs, final BitSet innerDocs, int maxDoc) {
if (rootDocs == null || innerDocs == null) {
public NumericDocValues select(final SortedNumericDocValues values, final long missingValue, final BitSet rootDocs, final DocIdSet innerDocSet, int maxDoc) throws IOException {
if (rootDocs == null || innerDocSet == null) {
return select(DocValues.emptySortedNumeric(maxDoc), missingValue);
}
final DocIdSetIterator innerDocs = innerDocSet.iterator();
if (innerDocs == null) {
return select(DocValues.emptySortedNumeric(maxDoc), missingValue);
}
return new NumericDocValues() {
int lastSeenRootDoc = 0;
long lastEmittedValue = missingValue;
@Override
public long get(int rootDoc) {
assert rootDocs.get(rootDoc) : "can only sort root documents";
if (rootDoc == 0) {
return missingValue;
assert rootDoc >= lastSeenRootDoc : "can only evaluate current and upcoming root docs";
// If via compareBottom this method has previously invoked for the same rootDoc then we need to use the
// last seen value, because innerDocs can't re-iterate over nested child docs it has already emitted,
// because DocIdSetIterator can only advance forwards.
if (rootDoc == lastSeenRootDoc) {
return lastEmittedValue;
}
final int prevRootDoc = rootDocs.prevSetBit(rootDoc - 1);
final int firstNestedDoc = innerDocs.nextSetBit(prevRootDoc + 1);
long accumulated = startLong();
int numValues = 0;
for (int doc = firstNestedDoc; doc != -1 && doc < rootDoc; doc = innerDocs.nextSetBit(doc + 1)) {
values.setDocument(doc);
final int count = values.count();
for (int i = 0; i < count; ++i) {
final long value = values.valueAt(i);
accumulated = apply(accumulated, value);
try {
final int prevRootDoc = rootDocs.prevSetBit(rootDoc - 1);
final int firstNestedDoc;
if (innerDocs.docID() > prevRootDoc) {
firstNestedDoc = innerDocs.docID();
} else {
firstNestedDoc = innerDocs.advance(prevRootDoc + 1);
}
numValues += count;
}
return numValues == 0
? missingValue
: reduce(accumulated, numValues);
long accumulated = startLong();
int numValues = 0;
for (int doc = firstNestedDoc; doc < rootDoc; doc = innerDocs.nextDoc()) {
values.setDocument(doc);
final int count = values.count();
for (int i = 0; i < count; ++i) {
final long value = values.valueAt(i);
accumulated = apply(accumulated, value);
}
numValues += count;
}
lastSeenRootDoc = rootDoc;
if (numValues == 0) {
lastEmittedValue = missingValue;
} else {
lastEmittedValue = reduce(accumulated, numValues);
}
return lastEmittedValue;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
}
@ -531,39 +556,60 @@ public enum MultiValueMode {
*
* NOTE: Calling the returned instance on docs that are not root docs is illegal
*/
// TODO: technically innerDocs need not be BitSet: only needs advance() ?
public NumericDoubleValues select(final SortedNumericDoubleValues values, final double missingValue, final BitSet rootDocs, final BitSet innerDocs, int maxDoc) {
if (rootDocs == null || innerDocs == null) {
public NumericDoubleValues select(final SortedNumericDoubleValues values, final double missingValue, final BitSet rootDocs, final DocIdSet innerDocSet, int maxDoc) throws IOException {
if (rootDocs == null || innerDocSet == null) {
return select(FieldData.emptySortedNumericDoubles(maxDoc), missingValue);
}
final DocIdSetIterator innerDocs = innerDocSet.iterator();
if (innerDocs == null) {
return select(FieldData.emptySortedNumericDoubles(maxDoc), missingValue);
}
return new NumericDoubleValues() {
int lastSeenRootDoc = 0;
double lastEmittedValue = missingValue;
@Override
public double get(int rootDoc) {
assert rootDocs.get(rootDoc) : "can only sort root documents";
if (rootDoc == 0) {
return missingValue;
assert rootDoc >= lastSeenRootDoc : "can only evaluate current and upcoming root docs";
if (rootDoc == lastSeenRootDoc) {
return lastEmittedValue;
}
final int prevRootDoc = rootDocs.prevSetBit(rootDoc - 1);
final int firstNestedDoc = innerDocs.nextSetBit(prevRootDoc + 1);
double accumulated = startDouble();
int numValues = 0;
for (int doc = firstNestedDoc; doc != -1 && doc < rootDoc; doc = innerDocs.nextSetBit(doc + 1)) {
values.setDocument(doc);
final int count = values.count();
for (int i = 0; i < count; ++i) {
final double value = values.valueAt(i);
accumulated = apply(accumulated, value);
try {
final int prevRootDoc = rootDocs.prevSetBit(rootDoc - 1);
final int firstNestedDoc;
if (innerDocs.docID() > prevRootDoc) {
firstNestedDoc = innerDocs.docID();
} else {
firstNestedDoc = innerDocs.advance(prevRootDoc + 1);
}
numValues += count;
}
return numValues == 0
? missingValue
: reduce(accumulated, numValues);
double accumulated = startDouble();
int numValues = 0;
for (int doc = firstNestedDoc; doc > prevRootDoc && doc < rootDoc; doc = innerDocs.nextDoc()) {
values.setDocument(doc);
final int count = values.count();
for (int i = 0; i < count; ++i) {
final double value = values.valueAt(i);
accumulated = apply(accumulated, value);
}
numValues += count;
}
lastSeenRootDoc = rootDoc;
if (numValues == 0) {
lastEmittedValue = missingValue;
} else {
lastEmittedValue = reduce(accumulated, numValues);
}
return lastEmittedValue;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
}
@ -615,11 +661,16 @@ public enum MultiValueMode {
*
* NOTE: Calling the returned instance on docs that are not root docs is illegal
*/
// TODO: technically innerDocs need not be BitSet: only needs advance() ?
public BinaryDocValues select(final SortedBinaryDocValues values, final BytesRef missingValue, final BitSet rootDocs, final BitSet innerDocs, int maxDoc) {
if (rootDocs == null || innerDocs == null) {
public BinaryDocValues select(final SortedBinaryDocValues values, final BytesRef missingValue, final BitSet rootDocs, final DocIdSet innerDocSet, int maxDoc) throws IOException {
if (rootDocs == null || innerDocSet == null) {
return select(FieldData.emptySortedBinary(maxDoc), missingValue);
}
final DocIdSetIterator innerDocs = innerDocSet.iterator();
if (innerDocs == null) {
return select(FieldData.emptySortedBinary(maxDoc), missingValue);
}
final BinaryDocValues selectedValues = select(values, new BytesRef());
final Bits docsWithValue;
if (FieldData.unwrapSingleton(values) != null) {
@ -631,35 +682,54 @@ public enum MultiValueMode {
final BytesRefBuilder spare = new BytesRefBuilder();
int lastSeenRootDoc = 0;
BytesRef lastEmittedValue = missingValue;
@Override
public BytesRef get(int rootDoc) {
assert rootDocs.get(rootDoc) : "can only sort root documents";
if (rootDoc == 0) {
return missingValue;
assert rootDoc >= lastSeenRootDoc : "can only evaluate current and upcoming root docs";
if (rootDoc == lastSeenRootDoc) {
return lastEmittedValue;
}
final int prevRootDoc = rootDocs.prevSetBit(rootDoc - 1);
final int firstNestedDoc = innerDocs.nextSetBit(prevRootDoc + 1);
try {
final int prevRootDoc = rootDocs.prevSetBit(rootDoc - 1);
final int firstNestedDoc;
if (innerDocs.docID() > prevRootDoc) {
firstNestedDoc = innerDocs.docID();
} else {
firstNestedDoc = innerDocs.advance(prevRootDoc + 1);
}
BytesRefBuilder accumulated = null;
BytesRefBuilder accumulated = null;
for (int doc = firstNestedDoc; doc != -1 && doc < rootDoc; doc = innerDocs.nextSetBit(doc + 1)) {
values.setDocument(doc);
final BytesRef innerValue = selectedValues.get(doc);
if (innerValue.length > 0 || docsWithValue == null || docsWithValue.get(doc)) {
if (accumulated == null) {
spare.copyBytes(innerValue);
accumulated = spare;
} else {
final BytesRef applied = apply(accumulated.get(), innerValue);
if (applied == innerValue) {
accumulated.copyBytes(innerValue);
for (int doc = firstNestedDoc; doc > prevRootDoc && doc < rootDoc; doc = innerDocs.nextDoc()) {
values.setDocument(doc);
final BytesRef innerValue = selectedValues.get(doc);
if (innerValue.length > 0 || docsWithValue == null || docsWithValue.get(doc)) {
if (accumulated == null) {
spare.copyBytes(innerValue);
accumulated = spare;
} else {
final BytesRef applied = apply(accumulated.get(), innerValue);
if (applied == innerValue) {
accumulated.copyBytes(innerValue);
}
}
}
}
}
return accumulated == null ? missingValue : accumulated.get();
lastSeenRootDoc = rootDoc;
if (accumulated == null) {
lastEmittedValue = missingValue;
} else {
lastEmittedValue = accumulated.get();
}
return lastEmittedValue;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
}
@ -709,14 +779,22 @@ public enum MultiValueMode {
*
* NOTE: Calling the returned instance on docs that are not root docs is illegal
*/
// TODO: technically innerDocs need not be BitSet: only needs advance() ?
public SortedDocValues select(final RandomAccessOrds values, final BitSet rootDocs, final BitSet innerDocs) {
if (rootDocs == null || innerDocs == null) {
return select((RandomAccessOrds) DocValues.emptySortedSet());
public SortedDocValues select(final RandomAccessOrds values, final BitSet rootDocs, final DocIdSet innerDocSet) throws IOException {
if (rootDocs == null || innerDocSet == null) {
return select(DocValues.emptySortedSet());
}
final DocIdSetIterator innerDocs = innerDocSet.iterator();
if (innerDocs == null) {
return select(DocValues.emptySortedSet());
}
final SortedDocValues selectedValues = select(values);
return new SortedDocValues() {
int lastSeenRootDoc = 0;
int lastEmittedOrd = -1;
@Override
public BytesRef lookupOrd(int ord) {
return selectedValues.lookupOrd(ord);
@ -730,26 +808,37 @@ public enum MultiValueMode {
@Override
public int getOrd(int rootDoc) {
assert rootDocs.get(rootDoc) : "can only sort root documents";
if (rootDoc == 0) {
return -1;
assert rootDoc >= lastSeenRootDoc : "can only evaluate current and upcoming root docs";
if (rootDoc == lastSeenRootDoc) {
return lastEmittedOrd;
}
final int prevRootDoc = rootDocs.prevSetBit(rootDoc - 1);
final int firstNestedDoc = innerDocs.nextSetBit(prevRootDoc + 1);
int ord = -1;
try {
final int prevRootDoc = rootDocs.prevSetBit(rootDoc - 1);
final int firstNestedDoc;
if (innerDocs.docID() > prevRootDoc) {
firstNestedDoc = innerDocs.docID();
} else {
firstNestedDoc = innerDocs.advance(prevRootDoc + 1);
}
int ord = -1;
for (int doc = firstNestedDoc; doc != -1 && doc < rootDoc; doc = innerDocs.nextSetBit(doc + 1)) {
final int innerOrd = selectedValues.getOrd(doc);
if (innerOrd != -1) {
if (ord == -1) {
ord = innerOrd;
} else {
ord = applyOrd(ord, innerOrd);
for (int doc = firstNestedDoc; doc > prevRootDoc && doc < rootDoc; doc = innerDocs.nextDoc()) {
final int innerOrd = selectedValues.getOrd(doc);
if (innerOrd != -1) {
if (ord == -1) {
ord = innerOrd;
} else {
ord = applyOrd(ord, innerOrd);
}
}
}
}
return ord;
lastSeenRootDoc = rootDoc;
return lastEmittedOrd = ord;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
};
}

View File

@ -21,8 +21,7 @@ package org.elasticsearch.search.sort;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.*;
import org.apache.lucene.search.join.BitDocIdSetFilter;
import org.apache.lucene.util.BitSet;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
@ -157,12 +156,13 @@ public class GeoDistanceSortParser implements SortParser {
final Nested nested;
if (nestedHelper != null && nestedHelper.getPath() != null) {
BitDocIdSetFilter rootDocumentsFilter = context.bitsetFilterCache().getBitDocIdSetFilter(NonNestedDocsFilter.INSTANCE);
BitDocIdSetFilter innerDocumentsFilter;
Filter innerDocumentsFilter;
if (nestedHelper.filterFound()) {
innerDocumentsFilter = context.bitsetFilterCache().getBitDocIdSetFilter(nestedHelper.getInnerFilter());
innerDocumentsFilter = context.filterCache().cache(nestedHelper.getInnerFilter(), null, context.queryParserService().autoFilterCachePolicy());
} else {
innerDocumentsFilter = context.bitsetFilterCache().getBitDocIdSetFilter(nestedHelper.getNestedObjectMapper().nestedTypeFilter());
innerDocumentsFilter = context.filterCache().cache(nestedHelper.getNestedObjectMapper().nestedTypeFilter(), null, context.queryParserService().autoFilterCachePolicy());
}
nested = new Nested(rootDocumentsFilter, innerDocumentsFilter);
} else {
@ -188,7 +188,7 @@ public class GeoDistanceSortParser implements SortParser {
selectedValues = finalSortMode.select(distanceValues, Double.MAX_VALUE);
} else {
final BitSet rootDocs = nested.rootDocs(context).bits();
final BitSet innerDocs = nested.innerDocs(context).bits();
final DocIdSet innerDocs = nested.innerDocs(context);
selectedValues = finalSortMode.select(distanceValues, Double.MAX_VALUE, rootDocs, innerDocs, context.reader().maxDoc());
}
return selectedValues.getRawDoubleValues();

View File

@ -21,6 +21,7 @@ package org.elasticsearch.search.sort;
import org.apache.lucene.index.BinaryDocValues;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.join.BitDocIdSetFilter;
@ -131,11 +132,11 @@ public class ScriptSortParser implements SortParser {
final Nested nested;
if (nestedHelper != null && nestedHelper.getPath() != null) {
BitDocIdSetFilter rootDocumentsFilter = context.bitsetFilterCache().getBitDocIdSetFilter(NonNestedDocsFilter.INSTANCE);
BitDocIdSetFilter innerDocumentsFilter;
Filter innerDocumentsFilter;
if (nestedHelper.filterFound()) {
innerDocumentsFilter = context.bitsetFilterCache().getBitDocIdSetFilter(nestedHelper.getInnerFilter());
innerDocumentsFilter = context.filterCache().cache(nestedHelper.getInnerFilter(), null, context.queryParserService().autoFilterCachePolicy());
} else {
innerDocumentsFilter = context.bitsetFilterCache().getBitDocIdSetFilter(nestedHelper.getNestedObjectMapper().nestedTypeFilter());
innerDocumentsFilter = context.filterCache().cache(nestedHelper.getNestedObjectMapper().nestedTypeFilter(), null, context.queryParserService().autoFilterCachePolicy());
}
nested = new Nested(rootDocumentsFilter, innerDocumentsFilter);
} else {

View File

@ -21,6 +21,7 @@ package org.elasticsearch.search.sort;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.join.BitDocIdSetFilter;
@ -252,11 +253,11 @@ public class SortParseElement implements SearchParseElement {
final Nested nested;
if (nestedHelper != null && nestedHelper.getPath() != null) {
BitDocIdSetFilter rootDocumentsFilter = context.bitsetFilterCache().getBitDocIdSetFilter(NonNestedDocsFilter.INSTANCE);
BitDocIdSetFilter innerDocumentsFilter;
Filter innerDocumentsFilter;
if (nestedHelper.filterFound()) {
innerDocumentsFilter = context.bitsetFilterCache().getBitDocIdSetFilter(nestedHelper.getInnerFilter());
innerDocumentsFilter = context.filterCache().cache(nestedHelper.getInnerFilter(), null, context.queryParserService().autoFilterCachePolicy());
} else {
innerDocumentsFilter = context.bitsetFilterCache().getBitDocIdSetFilter(nestedHelper.getNestedObjectMapper().nestedTypeFilter());
innerDocumentsFilter = context.filterCache().cache(nestedHelper.getNestedObjectMapper().nestedTypeFilter(), null, context.queryParserService().autoFilterCachePolicy());
}
nested = new Nested(rootDocumentsFilter, innerDocumentsFilter);
} else {

View File

@ -21,6 +21,7 @@ package org.elasticsearch.search;
import com.carrotsearch.randomizedtesting.generators.RandomStrings;
import org.apache.lucene.index.*;
import org.apache.lucene.util.BitDocIdSet;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.FixedBitSet;
import org.elasticsearch.index.fielddata.FieldData;
@ -29,6 +30,7 @@ import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
import org.elasticsearch.test.ElasticsearchTestCase;
import java.io.IOException;
import java.util.Arrays;
public class MultiValueModeTests extends ElasticsearchTestCase {
@ -55,7 +57,7 @@ public class MultiValueModeTests extends ElasticsearchTestCase {
return innerDocs;
}
public void testSingleValuedLongs() {
public void testSingleValuedLongs() throws Exception {
final int numDocs = scaledRandomIntBetween(1, 100);
final long[] array = new long[numDocs];
final FixedBitSet docsWithValue = randomBoolean() ? null : new FixedBitSet(numDocs);
@ -82,7 +84,7 @@ public class MultiValueModeTests extends ElasticsearchTestCase {
verify(multiValues, numDocs, rootDocs, innerDocs);
}
public void testMultiValuedLongs() {
public void testMultiValuedLongs() throws Exception {
final int numDocs = scaledRandomIntBetween(1, 100);
final long[][] array = new long[numDocs][];
for (int i = 0; i < numDocs; ++i) {
@ -142,10 +144,10 @@ public class MultiValueModeTests extends ElasticsearchTestCase {
}
}
private void verify(SortedNumericDocValues values, int maxDoc, FixedBitSet rootDocs, FixedBitSet innerDocs) {
private void verify(SortedNumericDocValues values, int maxDoc, FixedBitSet rootDocs, FixedBitSet innerDocs) throws IOException {
for (long missingValue : new long[] { 0, randomLong() }) {
for (MultiValueMode mode : MultiValueMode.values()) {
final NumericDocValues selected = mode.select(values, missingValue, rootDocs, innerDocs, maxDoc);
final NumericDocValues selected = mode.select(values, missingValue, rootDocs, new BitDocIdSet(innerDocs), maxDoc);
int prevRoot = -1;
for (int root = rootDocs.nextSetBit(0); root != -1; root = root + 1 < maxDoc ? rootDocs.nextSetBit(root + 1) : -1) {
final long actual = selected.get(root);
@ -172,7 +174,7 @@ public class MultiValueModeTests extends ElasticsearchTestCase {
}
}
public void testSingleValuedDoubles() {
public void testSingleValuedDoubles() throws Exception {
final int numDocs = scaledRandomIntBetween(1, 100);
final double[] array = new double[numDocs];
final FixedBitSet docsWithValue = randomBoolean() ? null : new FixedBitSet(numDocs);
@ -199,7 +201,7 @@ public class MultiValueModeTests extends ElasticsearchTestCase {
verify(multiValues, numDocs, rootDocs, innerDocs);
}
public void testMultiValuedDoubles() {
public void testMultiValuedDoubles() throws Exception {
final int numDocs = scaledRandomIntBetween(1, 100);
final double[][] array = new double[numDocs][];
for (int i = 0; i < numDocs; ++i) {
@ -259,10 +261,10 @@ public class MultiValueModeTests extends ElasticsearchTestCase {
}
}
private void verify(SortedNumericDoubleValues values, int maxDoc, FixedBitSet rootDocs, FixedBitSet innerDocs) {
private void verify(SortedNumericDoubleValues values, int maxDoc, FixedBitSet rootDocs, FixedBitSet innerDocs) throws IOException {
for (long missingValue : new long[] { 0, randomLong() }) {
for (MultiValueMode mode : MultiValueMode.values()) {
final NumericDoubleValues selected = mode.select(values, missingValue, rootDocs, innerDocs, maxDoc);
final NumericDoubleValues selected = mode.select(values, missingValue, rootDocs, new BitDocIdSet(innerDocs), maxDoc);
int prevRoot = -1;
for (int root = rootDocs.nextSetBit(0); root != -1; root = root + 1 < maxDoc ? rootDocs.nextSetBit(root + 1) : -1) {
final double actual = selected.get(root);
@ -289,7 +291,7 @@ public class MultiValueModeTests extends ElasticsearchTestCase {
}
}
public void testSingleValuedStrings() {
public void testSingleValuedStrings() throws Exception {
final int numDocs = scaledRandomIntBetween(1, 100);
final BytesRef[] array = new BytesRef[numDocs];
final FixedBitSet docsWithValue = randomBoolean() ? null : new FixedBitSet(numDocs);
@ -319,7 +321,7 @@ public class MultiValueModeTests extends ElasticsearchTestCase {
verify(multiValues, numDocs, rootDocs, innerDocs);
}
public void testMultiValuedStrings() {
public void testMultiValuedStrings() throws Exception {
final int numDocs = scaledRandomIntBetween(1, 100);
final BytesRef[][] array = new BytesRef[numDocs][];
for (int i = 0; i < numDocs; ++i) {
@ -384,10 +386,10 @@ public class MultiValueModeTests extends ElasticsearchTestCase {
}
}
private void verify(SortedBinaryDocValues values, int maxDoc, FixedBitSet rootDocs, FixedBitSet innerDocs) {
private void verify(SortedBinaryDocValues values, int maxDoc, FixedBitSet rootDocs, FixedBitSet innerDocs) throws IOException {
for (BytesRef missingValue : new BytesRef[] { new BytesRef(), new BytesRef(RandomStrings.randomAsciiOfLength(getRandom(), 8)) }) {
for (MultiValueMode mode : new MultiValueMode[] {MultiValueMode.MIN, MultiValueMode.MAX}) {
final BinaryDocValues selected = mode.select(values, missingValue, rootDocs, innerDocs, maxDoc);
final BinaryDocValues selected = mode.select(values, missingValue, rootDocs, new BitDocIdSet(innerDocs), maxDoc);
int prevRoot = -1;
for (int root = rootDocs.nextSetBit(0); root != -1; root = root + 1 < maxDoc ? rootDocs.nextSetBit(root + 1) : -1) {
final BytesRef actual = selected.get(root);
@ -416,7 +418,7 @@ public class MultiValueModeTests extends ElasticsearchTestCase {
}
public void testSingleValuedOrds() {
public void testSingleValuedOrds() throws Exception {
final int numDocs = scaledRandomIntBetween(1, 100);
final int[] array = new int[numDocs];
for (int i = 0; i < array.length; ++i) {
@ -449,7 +451,7 @@ public class MultiValueModeTests extends ElasticsearchTestCase {
verify(multiValues, numDocs, rootDocs, innerDocs);
}
public void testMultiValuedOrds() {
public void testMultiValuedOrds() throws Exception {
final int numDocs = scaledRandomIntBetween(1, 100);
final long[][] array = new long[numDocs][];
for (int i = 0; i < numDocs; ++i) {
@ -518,9 +520,9 @@ public class MultiValueModeTests extends ElasticsearchTestCase {
}
}
private void verify(RandomAccessOrds values, int maxDoc, FixedBitSet rootDocs, FixedBitSet innerDocs) {
private void verify(RandomAccessOrds values, int maxDoc, FixedBitSet rootDocs, FixedBitSet innerDocs) throws IOException {
for (MultiValueMode mode : new MultiValueMode[] {MultiValueMode.MIN, MultiValueMode.MAX}) {
final SortedDocValues selected = mode.select(values, rootDocs, innerDocs);
final SortedDocValues selected = mode.select(values, rootDocs, new BitDocIdSet(innerDocs));
int prevRoot = -1;
for (int root = rootDocs.nextSetBit(0); root != -1; root = root + 1 < maxDoc ? rootDocs.nextSetBit(root + 1) : -1) {
final int actual = selected.getOrd(root);