Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/changelog/133397.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 133397
summary: Push down loading of singleton dense double based field types to the …
area: "Codec"
type: enhancement
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ protected void registerParameters(ParameterChecker checker) throws IOException {
checker.registerUpdateCheck(b -> b.field("coerce", false), m -> assertFalse(((ScaledFloatFieldMapper) m).coerce()));
}

@Override
protected boolean supportsBulkDoubleBlockReading() {
return true;
}

public void testExistsQueryDocValuesDisabled() throws IOException {
MapperService mapperService = createMapperService(fieldMapping(b -> {
minimalMapping(b);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.apache.lucene.util.packed.PackedInts;
import org.elasticsearch.core.IOUtils;
import org.elasticsearch.index.codec.tsdb.TSDBDocValuesEncoder;
import org.elasticsearch.index.mapper.BlockDocValuesReader;
import org.elasticsearch.index.mapper.BlockLoader;

import java.io.IOException;
Expand Down Expand Up @@ -383,7 +384,13 @@ public long cost() {
}

@Override
public BlockLoader.Block tryRead(BlockLoader.BlockFactory factory, BlockLoader.Docs docs, int offset) throws IOException {
public BlockLoader.Block tryRead(
BlockLoader.BlockFactory factory,
BlockLoader.Docs docs,
int offset,
BlockDocValuesReader.ToDouble toDouble
) throws IOException {
assert toDouble == null;
if (ords instanceof BaseDenseNumericValues denseOrds) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we assert toDouble is null here?

var block = tryReadAHead(factory, docs, offset);
if (block != null) {
Expand Down Expand Up @@ -457,7 +464,12 @@ public TermsEnum termsEnum() throws IOException {
}

@Override
public BlockLoader.Block tryRead(BlockLoader.BlockFactory factory, BlockLoader.Docs docs, int offset) throws IOException {
public BlockLoader.Block tryRead(
BlockLoader.BlockFactory factory,
BlockLoader.Docs docs,
int offset,
BlockDocValuesReader.ToDouble toDouble
) throws IOException {
return null;
}

Expand Down Expand Up @@ -504,7 +516,12 @@ public final long cost() {
}

@Override
public BlockLoader.Block tryRead(BlockLoader.BlockFactory factory, BlockLoader.Docs docs, int offset) throws IOException {
public BlockLoader.Block tryRead(
BlockLoader.BlockFactory factory,
BlockLoader.Docs docs,
int offset,
BlockDocValuesReader.ToDouble toDouble
) throws IOException {
return null;
}

Expand Down Expand Up @@ -1365,7 +1382,18 @@ public long longValue() throws IOException {
}

@Override
public BlockLoader.Block tryRead(BlockLoader.BlockFactory factory, BlockLoader.Docs docs, int offset) throws IOException {
public BlockLoader.Block tryRead(
BlockLoader.BlockFactory factory,
BlockLoader.Docs docs,
int offset,
BlockDocValuesReader.ToDouble toDouble
) throws IOException {
if (toDouble != null) {
try (BlockLoader.SingletonDoubleBuilder builder = factory.singletonDoubles(docs.count() - offset)) {
SingletonLongToDoubleDelegate delegate = new SingletonLongToDoubleDelegate(builder, toDouble);
return tryRead(delegate, docs, offset);
}
}
try (BlockLoader.SingletonLongBuilder builder = factory.singletonLongs(docs.count() - offset)) {
return tryRead(builder, docs, offset);
}
Expand Down Expand Up @@ -1774,4 +1802,55 @@ public BlockLoader.Builder endPositionEntry() {
public void close() {}
}

// Block builder that consumes long values and converts them to double using the provided converter function.
static final class SingletonLongToDoubleDelegate implements BlockLoader.SingletonLongBuilder {
private final BlockLoader.SingletonDoubleBuilder doubleBuilder;
private final BlockDocValuesReader.ToDouble toDouble;
private final double[] buffer = new double[ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE];

// The passed builder is used to store the converted double values and produce the final block containing them.
SingletonLongToDoubleDelegate(BlockLoader.SingletonDoubleBuilder doubleBuilder, BlockDocValuesReader.ToDouble toDouble) {
this.doubleBuilder = doubleBuilder;
this.toDouble = toDouble;
}

@Override
public BlockLoader.SingletonLongBuilder appendLong(long value) {
throw new UnsupportedOperationException();
}

@Override
public BlockLoader.SingletonLongBuilder appendLongs(long[] values, int from, int length) {
assert length <= buffer.length : "length " + length + " > " + buffer.length;
for (int i = 0; i < length; i++) {
buffer[i] = toDouble.convert(values[from + i]);
}
doubleBuilder.appendDoubles(buffer, 0, length);
return this;
}

@Override
public BlockLoader.Block build() {
return doubleBuilder.build();
}

@Override
public BlockLoader.Builder appendNull() {
throw new UnsupportedOperationException();
}

@Override
public BlockLoader.Builder beginPositionEntry() {
throw new UnsupportedOperationException();
}

@Override
public BlockLoader.Builder endPositionEntry() {
throw new UnsupportedOperationException();
}

@Override
public void close() {}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,12 @@ public AllReader reader(LeafReaderContext context) throws IOException {
}
}

static class SingletonLongs extends BlockDocValuesReader {
// Used for testing.
interface NumericDocValuesAccessor {
NumericDocValues numericDocValues();
}

static class SingletonLongs extends BlockDocValuesReader implements NumericDocValuesAccessor {
final NumericDocValues numericDocValues;

SingletonLongs(NumericDocValues numericDocValues) {
Expand All @@ -132,7 +137,7 @@ static class SingletonLongs extends BlockDocValuesReader {
@Override
public BlockLoader.Block read(BlockFactory factory, Docs docs, int offset, boolean nullsFiltered) throws IOException {
if (numericDocValues instanceof BlockLoader.OptionalColumnAtATimeReader direct) {
BlockLoader.Block result = direct.tryRead(factory, docs, offset);
BlockLoader.Block result = direct.tryRead(factory, docs, offset, null);
if (result != null) {
return result;
}
Expand Down Expand Up @@ -169,6 +174,11 @@ public int docId() {
public String toString() {
return "BlockDocValuesReader.SingletonLongs";
}

@Override
public NumericDocValues numericDocValues() {
return numericDocValues;
}
}

static class Longs extends BlockDocValuesReader {
Expand Down Expand Up @@ -387,7 +397,7 @@ public AllReader reader(LeafReaderContext context) throws IOException {
}
}

private static class SingletonDoubles extends BlockDocValuesReader {
static class SingletonDoubles extends BlockDocValuesReader implements NumericDocValuesAccessor {
private final NumericDocValues docValues;
private final ToDouble toDouble;

Expand All @@ -398,6 +408,12 @@ private static class SingletonDoubles extends BlockDocValuesReader {

@Override
public BlockLoader.Block read(BlockFactory factory, Docs docs, int offset, boolean nullsFiltered) throws IOException {
if (docValues instanceof BlockLoader.OptionalColumnAtATimeReader direct) {
BlockLoader.Block result = direct.tryRead(factory, docs, offset, toDouble);
if (result != null) {
return result;
}
}
try (BlockLoader.DoubleBuilder builder = factory.doublesFromDocValues(docs.count() - offset)) {
for (int i = offset; i < docs.count(); i++) {
int doc = docs.get(i);
Expand Down Expand Up @@ -430,9 +446,14 @@ public int docId() {
public String toString() {
return "BlockDocValuesReader.SingletonDoubles";
}

@Override
public NumericDocValues numericDocValues() {
return docValues;
}
}

private static class Doubles extends BlockDocValuesReader {
static class Doubles extends BlockDocValuesReader {
private final SortedNumericDocValues docValues;
private final ToDouble toDouble;

Expand Down Expand Up @@ -715,7 +736,7 @@ public BlockLoader.Block read(BlockFactory factory, Docs docs, int offset, boole
return readSingleDoc(factory, docs.get(offset));
}
if (ordinals instanceof BlockLoader.OptionalColumnAtATimeReader direct) {
BlockLoader.Block block = direct.tryRead(factory, docs, offset);
BlockLoader.Block block = direct.tryRead(factory, docs, offset, null);
if (block != null) {
return block;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,11 @@ interface OptionalColumnAtATimeReader {
/**
* Attempts to read the values of all documents in {@code docs}
* Returns {@code null} if unable to load the values.
*
* @param toDouble a function to convert long values to double, or null if no conversion is needed/supported
*/
@Nullable
BlockLoader.Block tryRead(BlockFactory factory, Docs docs, int offset) throws IOException;
BlockLoader.Block tryRead(BlockFactory factory, Docs docs, int offset, BlockDocValuesReader.ToDouble toDouble) throws IOException;
}

interface RowStrideReader extends Reader {
Expand Down Expand Up @@ -435,6 +437,17 @@ interface BlockFactory {
*/
SingletonLongBuilder singletonLongs(int expectedCount);

/**
* Build a specialized builder for singleton dense double based fields with the following constraints:
* <ul>
* <li>Only one value per document can be collected</li>
* <li>No more than expectedCount values can be collected</li>
* </ul>
*
* @param expectedCount The maximum number of values to be collected.
*/
SingletonDoubleBuilder singletonDoubles(int expectedCount);

/**
* Build a builder to load only {@code null}s.
*/
Expand Down Expand Up @@ -537,12 +550,20 @@ interface IntBuilder extends Builder {
* Specialized builder for collecting dense arrays of long values.
*/
interface SingletonLongBuilder extends Builder {

SingletonLongBuilder appendLong(long value);

SingletonLongBuilder appendLongs(long[] values, int from, int length);
}

/**
* Specialized builder for collecting dense arrays of double values.
*/
interface SingletonDoubleBuilder extends Builder {
SingletonDoubleBuilder appendDouble(double value);

SingletonDoubleBuilder appendDoubles(double[] values, int from, int length);
}

interface LongBuilder extends Builder {
/**
* Appends a long to the current entry.
Expand Down
Loading