Skip to content

Commit 96a83e9

Browse files
committed
use SingletonDoubleBuilder
1 parent b15bf8a commit 96a83e9

File tree

12 files changed

+255
-196
lines changed

12 files changed

+255
-196
lines changed

server/src/main/java/org/elasticsearch/index/codec/tsdb/es819/ES819TSDBDocValuesProducer.java

Lines changed: 72 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,12 @@ public long cost() {
384384
}
385385

386386
@Override
387-
public BlockLoader.Block tryRead(BlockLoader.BlockFactory factory, BlockLoader.Docs docs, int offset) throws IOException {
387+
public BlockLoader.Block tryRead(
388+
BlockLoader.BlockFactory factory,
389+
BlockLoader.Docs docs,
390+
int offset,
391+
BlockDocValuesReader.ToDouble toDouble
392+
) throws IOException {
388393
if (ords instanceof BaseDenseNumericValues denseOrds) {
389394
var block = tryReadAHead(factory, docs, offset);
390395
if (block != null) {
@@ -458,7 +463,12 @@ public TermsEnum termsEnum() throws IOException {
458463
}
459464

460465
@Override
461-
public BlockLoader.Block tryRead(BlockLoader.BlockFactory factory, BlockLoader.Docs docs, int offset) throws IOException {
466+
public BlockLoader.Block tryRead(
467+
BlockLoader.BlockFactory factory,
468+
BlockLoader.Docs docs,
469+
int offset,
470+
BlockDocValuesReader.ToDouble toDouble
471+
) throws IOException {
462472
return null;
463473
}
464474

@@ -505,7 +515,12 @@ public final long cost() {
505515
}
506516

507517
@Override
508-
public BlockLoader.Block tryRead(BlockLoader.BlockFactory factory, BlockLoader.Docs docs, int offset) throws IOException {
518+
public BlockLoader.Block tryRead(
519+
BlockLoader.BlockFactory factory,
520+
BlockLoader.Docs docs,
521+
int offset,
522+
BlockDocValuesReader.ToDouble toDouble
523+
) throws IOException {
509524
return null;
510525
}
511526

@@ -1366,21 +1381,19 @@ public long longValue() throws IOException {
13661381
}
13671382

13681383
@Override
1369-
public BlockLoader.Block tryRead(BlockLoader.BlockFactory factory, BlockLoader.Docs docs, int offset) throws IOException {
1370-
try (BlockLoader.SingletonLongBuilder builder = factory.singletonLongs(docs.count() - offset)) {
1371-
return tryRead(builder, docs, offset);
1372-
}
1373-
}
1374-
1375-
@Override
1376-
public BlockLoader.Block tryReadDoubles(
1384+
public BlockLoader.Block tryRead(
13771385
BlockLoader.BlockFactory factory,
13781386
BlockLoader.Docs docs,
13791387
int offset,
13801388
BlockDocValuesReader.ToDouble toDouble
13811389
) throws IOException {
1390+
if (toDouble != null) {
1391+
try (BlockLoader.SingletonDoubleBuilder builder = factory.singletonDoubles(docs.count() - offset)) {
1392+
SingletonLongToDoubleDelegate delegate = new SingletonLongToDoubleDelegate(builder, toDouble);
1393+
return tryRead(delegate, docs, offset);
1394+
}
1395+
}
13821396
try (BlockLoader.SingletonLongBuilder builder = factory.singletonLongs(docs.count() - offset)) {
1383-
builder.setToDouble(toDouble);
13841397
return tryRead(builder, docs, offset);
13851398
}
13861399
}
@@ -1783,7 +1796,53 @@ public BlockLoader.Builder endPositionEntry() {
17831796
}
17841797

17851798
@Override
1786-
public void setToDouble(BlockDocValuesReader.ToDouble toDouble) {
1799+
public void close() {}
1800+
}
1801+
1802+
// Block builder that consumes long values and converts them to double using the provided converter function.
1803+
static final class SingletonLongToDoubleDelegate implements BlockLoader.SingletonLongBuilder {
1804+
private final BlockLoader.SingletonDoubleBuilder doubleBuilder;
1805+
private final BlockDocValuesReader.ToDouble toDouble;
1806+
private final double[] buffer = new double[ES819TSDBDocValuesFormat.NUMERIC_BLOCK_SIZE];
1807+
1808+
// The passed builder is used to store the converted double values and produce the final block containing them.
1809+
SingletonLongToDoubleDelegate(BlockLoader.SingletonDoubleBuilder doubleBuilder, BlockDocValuesReader.ToDouble toDouble) {
1810+
this.doubleBuilder = doubleBuilder;
1811+
this.toDouble = toDouble;
1812+
}
1813+
1814+
@Override
1815+
public BlockLoader.SingletonLongBuilder appendLong(long value) {
1816+
throw new UnsupportedOperationException();
1817+
}
1818+
1819+
@Override
1820+
public BlockLoader.SingletonLongBuilder appendLongs(long[] values, int from, int length) {
1821+
assert length <= buffer.length : "length " + length + " > " + buffer.length;
1822+
for (int i = 0; i < length; i++) {
1823+
buffer[i] = toDouble.convert(values[from + i]);
1824+
}
1825+
doubleBuilder.appendDoubles(buffer, 0, length);
1826+
return this;
1827+
}
1828+
1829+
@Override
1830+
public BlockLoader.Block build() {
1831+
return doubleBuilder.build();
1832+
}
1833+
1834+
@Override
1835+
public BlockLoader.Builder appendNull() {
1836+
throw new UnsupportedOperationException();
1837+
}
1838+
1839+
@Override
1840+
public BlockLoader.Builder beginPositionEntry() {
1841+
throw new UnsupportedOperationException();
1842+
}
1843+
1844+
@Override
1845+
public BlockLoader.Builder endPositionEntry() {
17871846
throw new UnsupportedOperationException();
17881847
}
17891848

server/src/main/java/org/elasticsearch/index/mapper/BlockDocValuesReader.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ static class SingletonLongs extends BlockDocValuesReader {
132132
@Override
133133
public BlockLoader.Block read(BlockFactory factory, Docs docs, int offset, boolean nullsFiltered) throws IOException {
134134
if (numericDocValues instanceof BlockLoader.OptionalColumnAtATimeReader direct) {
135-
BlockLoader.Block result = direct.tryRead(factory, docs, offset);
135+
BlockLoader.Block result = direct.tryRead(factory, docs, offset, null);
136136
if (result != null) {
137137
return result;
138138
}
@@ -399,7 +399,7 @@ private static class SingletonDoubles extends BlockDocValuesReader {
399399
@Override
400400
public BlockLoader.Block read(BlockFactory factory, Docs docs, int offset, boolean nullsFiltered) throws IOException {
401401
if (docValues instanceof BlockLoader.OptionalColumnAtATimeReader direct) {
402-
BlockLoader.Block result = direct.tryReadDoubles(factory, docs, offset, toDouble);
402+
BlockLoader.Block result = direct.tryRead(factory, docs, offset, toDouble);
403403
if (result != null) {
404404
return result;
405405
}
@@ -721,7 +721,7 @@ public BlockLoader.Block read(BlockFactory factory, Docs docs, int offset, boole
721721
return readSingleDoc(factory, docs.get(offset));
722722
}
723723
if (ordinals instanceof BlockLoader.OptionalColumnAtATimeReader direct) {
724-
BlockLoader.Block block = direct.tryRead(factory, docs, offset);
724+
BlockLoader.Block block = direct.tryRead(factory, docs, offset, null);
725725
if (block != null) {
726726
return block;
727727
}

server/src/main/java/org/elasticsearch/index/mapper/BlockLoader.java

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,11 @@ interface OptionalColumnAtATimeReader {
6565
/**
6666
* Attempts to read the values of all documents in {@code docs}
6767
* Returns {@code null} if unable to load the values.
68+
*
69+
* @param toDouble a function to convert long values to double, or null if no conversion is needed/supported
6870
*/
6971
@Nullable
70-
BlockLoader.Block tryRead(BlockFactory factory, Docs docs, int offset) throws IOException;
71-
72-
/**
73-
* Specialization for doubles.
74-
* Returns {@code null} if unable to load values as doubles.
75-
*/
76-
@Nullable
77-
default BlockLoader.Block tryReadDoubles(BlockFactory factory, Docs docs, int offset, BlockDocValuesReader.ToDouble toDouble)
78-
throws IOException {
79-
return null;
80-
}
72+
BlockLoader.Block tryRead(BlockFactory factory, Docs docs, int offset, BlockDocValuesReader.ToDouble toDouble) throws IOException;
8173
}
8274

8375
interface RowStrideReader extends Reader {
@@ -445,6 +437,17 @@ interface BlockFactory {
445437
*/
446438
SingletonLongBuilder singletonLongs(int expectedCount);
447439

440+
/**
441+
* Build a specialized builder for singleton dense double based fields with the following constraints:
442+
* <ul>
443+
* <li>Only one value per document can be collected</li>
444+
* <li>No more than expectedCount values can be collected</li>
445+
* </ul>
446+
*
447+
* @param expectedCount The maximum number of values to be collected.
448+
*/
449+
SingletonDoubleBuilder singletonDoubles(int expectedCount);
450+
448451
/**
449452
* Build a builder to load only {@code null}s.
450453
*/
@@ -547,13 +550,20 @@ interface IntBuilder extends Builder {
547550
* Specialized builder for collecting dense arrays of long values.
548551
*/
549552
interface SingletonLongBuilder extends Builder {
550-
void setToDouble(BlockDocValuesReader.ToDouble toDouble);
551-
552553
SingletonLongBuilder appendLong(long value);
553554

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

558+
/**
559+
* Specialized builder for collecting dense arrays of double values.
560+
*/
561+
interface SingletonDoubleBuilder extends Builder {
562+
SingletonDoubleBuilder appendDouble(double value);
563+
564+
SingletonDoubleBuilder appendDoubles(double[] values, int from, int length);
565+
}
566+
557567
interface LongBuilder extends Builder {
558568
/**
559569
* Appends a long to the current entry.

server/src/test/java/org/elasticsearch/index/codec/tsdb/es819/ES819TSDBDocValuesFormatTests.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ public void testOptionalColumnAtATimeReader() throws Exception {
773773

774774
{
775775
// bulk loading timestamp:
776-
var block = (TestBlock) timestampDV.tryRead(factory, docs, 0);
776+
var block = (TestBlock) timestampDV.tryRead(factory, docs, 0, null);
777777
assertNotNull(block);
778778
assertEquals(size, block.size());
779779
for (int j = 0; j < block.size(); j++) {
@@ -785,10 +785,10 @@ public void testOptionalColumnAtATimeReader() throws Exception {
785785
}
786786
{
787787
// bulk loading counter field:
788-
var block = (TestBlock) counterDV.tryRead(factory, docs, 0);
788+
var block = (TestBlock) counterDV.tryRead(factory, docs, 0, null);
789789
assertNotNull(block);
790790
assertEquals(size, block.size());
791-
var stringBlock = (TestBlock) stringCounterDV.tryRead(factory, docs, 0);
791+
var stringBlock = (TestBlock) stringCounterDV.tryRead(factory, docs, 0, null);
792792
assertNotNull(stringBlock);
793793
assertEquals(size, stringBlock.size());
794794
for (int j = 0; j < block.size(); j++) {
@@ -805,7 +805,7 @@ public void testOptionalColumnAtATimeReader() throws Exception {
805805
}
806806
{
807807
// bulk loading gauge field:
808-
var block = (TestBlock) gaugeDV.tryRead(factory, docs, 0);
808+
var block = (TestBlock) gaugeDV.tryRead(factory, docs, 0, null);
809809
assertNotNull(block);
810810
assertEquals(size, block.size());
811811
for (int j = 0; j < block.size(); j++) {
@@ -843,7 +843,7 @@ public void testOptionalColumnAtATimeReader() throws Exception {
843843

844844
{
845845
// bulk loading timestamp:
846-
var block = (TestBlock) timestampDV.tryRead(blockFactory, docs, randomOffset);
846+
var block = (TestBlock) timestampDV.tryRead(blockFactory, docs, randomOffset, null);
847847
assertNotNull(block);
848848
assertEquals(size, block.size());
849849
for (int j = 0; j < block.size(); j++) {
@@ -855,11 +855,11 @@ public void testOptionalColumnAtATimeReader() throws Exception {
855855
}
856856
{
857857
// bulk loading counter field:
858-
var block = (TestBlock) counterDV.tryRead(factory, docs, randomOffset);
858+
var block = (TestBlock) counterDV.tryRead(factory, docs, randomOffset, null);
859859
assertNotNull(block);
860860
assertEquals(size, block.size());
861861

862-
var stringBlock = (TestBlock) stringCounterDV.tryRead(factory, docs, randomOffset);
862+
var stringBlock = (TestBlock) stringCounterDV.tryRead(factory, docs, randomOffset, null);
863863
assertNotNull(stringBlock);
864864
assertEquals(size, stringBlock.size());
865865

@@ -877,7 +877,7 @@ public void testOptionalColumnAtATimeReader() throws Exception {
877877
}
878878
{
879879
// bulk loading gauge field:
880-
var block = (TestBlock) gaugeDV.tryRead(factory, docs, randomOffset);
880+
var block = (TestBlock) gaugeDV.tryRead(factory, docs, randomOffset, null);
881881
assertNotNull(block);
882882
assertEquals(size, block.size());
883883
for (int j = 0; j < block.size(); j++) {
@@ -902,11 +902,11 @@ public void testOptionalColumnAtATimeReader() throws Exception {
902902
stringCounterDV = getBaseSortedDocValues(leafReader, counterFieldAsString);
903903
{
904904
// bulk loading counter field:
905-
var block = (TestBlock) counterDV.tryRead(factory, docs, 0);
905+
var block = (TestBlock) counterDV.tryRead(factory, docs, 0, null);
906906
assertNotNull(block);
907907
assertEquals(size, block.size());
908908

909-
var stringBlock = (TestBlock) stringCounterDV.tryRead(factory, docs, 0);
909+
var stringBlock = (TestBlock) stringCounterDV.tryRead(factory, docs, 0, null);
910910
assertNotNull(stringBlock);
911911
assertEquals(size, stringBlock.size());
912912

@@ -1001,7 +1001,7 @@ public void testOptionalColumnAtATimeReaderWithSparseDocs() throws Exception {
10011001
var docs = TestBlock.docs(docIds);
10021002
{
10031003
timestampDV = getBaseDenseNumericValues(leafReader, timestampField);
1004-
var block = (TestBlock) timestampDV.tryRead(factory, docs, 0);
1004+
var block = (TestBlock) timestampDV.tryRead(factory, docs, 0, null);
10051005
assertNotNull(block);
10061006
assertEquals(numDocsPerQValue, block.size());
10071007
for (int j = 0; j < block.size(); j++) {
@@ -1012,7 +1012,7 @@ public void testOptionalColumnAtATimeReaderWithSparseDocs() throws Exception {
10121012
}
10131013
{
10141014
counterDV = getBaseDenseNumericValues(leafReader, counterField);
1015-
var block = (TestBlock) counterDV.tryRead(factory, docs, 0);
1015+
var block = (TestBlock) counterDV.tryRead(factory, docs, 0, null);
10161016
assertNotNull(block);
10171017
assertEquals(numDocsPerQValue, block.size());
10181018
for (int j = 0; j < block.size(); j++) {
@@ -1023,7 +1023,7 @@ public void testOptionalColumnAtATimeReaderWithSparseDocs() throws Exception {
10231023
}
10241024
{
10251025
counterAsStringDV = getBaseSortedDocValues(leafReader, counterAsStringField);
1026-
var block = (TestBlock) counterAsStringDV.tryRead(factory, docs, 0);
1026+
var block = (TestBlock) counterAsStringDV.tryRead(factory, docs, 0, null);
10271027
assertNotNull(block);
10281028
assertEquals(numDocsPerQValue, block.size());
10291029
for (int j = 0; j < block.size(); j++) {
@@ -1086,7 +1086,7 @@ public int get(int i) {
10861086
}
10871087
};
10881088
var idReader = ESTestCase.asInstanceOf(OptionalColumnAtATimeReader.class, leaf.reader().getNumericDocValues("id"));
1089-
TestBlock idBlock = (TestBlock) idReader.tryRead(factory, docs, 0);
1089+
TestBlock idBlock = (TestBlock) idReader.tryRead(factory, docs, 0, null);
10901090
assertNotNull(idBlock);
10911091

10921092
{
@@ -1100,7 +1100,7 @@ public int get(int i) {
11001100
block = (TestBlock) reader2.tryReadAHead(factory, docs, randomOffset);
11011101
} else {
11021102
assertNull(reader2.tryReadAHead(factory, docs, randomOffset));
1103-
block = (TestBlock) reader2.tryRead(factory, docs, randomOffset);
1103+
block = (TestBlock) reader2.tryRead(factory, docs, randomOffset, null);
11041104
}
11051105
assertNotNull(block);
11061106
assertThat(block.size(), equalTo(docs.count() - randomOffset));
@@ -1122,7 +1122,7 @@ public int get(int i) {
11221122
block = (TestBlock) reader3.tryReadAHead(factory, docs, randomOffset);
11231123
} else {
11241124
assertNull(reader3.tryReadAHead(factory, docs, randomOffset));
1125-
block = (TestBlock) reader3.tryRead(factory, docs, randomOffset);
1125+
block = (TestBlock) reader3.tryRead(factory, docs, randomOffset, null);
11261126
}
11271127
assertNotNull(reader3);
11281128
assertNotNull(block);

test/framework/src/main/java/org/elasticsearch/index/mapper/TestBlock.java

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,48 @@ public BlockLoader.Builder endPositionEntry() {
247247
}
248248

249249
@Override
250-
public void setToDouble(BlockDocValuesReader.ToDouble toDouble) {
251-
this.toDouble = toDouble;
250+
public void close() {}
251+
};
252+
}
253+
254+
@Override
255+
public BlockLoader.SingletonDoubleBuilder singletonDoubles(int expectedCount) {
256+
final double[] values = new double[expectedCount];
257+
258+
return new BlockLoader.SingletonDoubleBuilder() {
259+
private int count;
260+
261+
@Override
262+
public BlockLoader.Block build() {
263+
return new TestBlock(Arrays.stream(values).boxed().collect(Collectors.toUnmodifiableList()));
264+
}
265+
266+
@Override
267+
public BlockLoader.SingletonDoubleBuilder appendDoubles(double[] newValues, int from, int length) {
268+
System.arraycopy(newValues, from, values, count, length);
269+
count += length;
270+
return this;
271+
}
272+
273+
@Override
274+
public BlockLoader.SingletonDoubleBuilder appendDouble(double value) {
275+
values[count++] = value;
276+
return this;
277+
}
278+
279+
@Override
280+
public BlockLoader.Builder appendNull() {
281+
throw new UnsupportedOperationException();
282+
}
283+
284+
@Override
285+
public BlockLoader.Builder beginPositionEntry() {
286+
throw new UnsupportedOperationException();
287+
}
288+
289+
@Override
290+
public BlockLoader.Builder endPositionEntry() {
291+
throw new UnsupportedOperationException();
252292
}
253293

254294
@Override

0 commit comments

Comments
 (0)