Skip to content

Commit a318054

Browse files
committed
introduce dedicated block loader for timestamp field.
1 parent 583b8d6 commit a318054

File tree

4 files changed

+106
-56
lines changed

4 files changed

+106
-56
lines changed

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

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,7 @@
2020
import org.apache.lucene.index.SortedSetDocValues;
2121
import org.apache.lucene.util.BytesRef;
2222
import org.elasticsearch.common.io.stream.ByteArrayStreamInput;
23-
import org.elasticsearch.index.IndexMode;
2423
import org.elasticsearch.index.IndexVersion;
25-
import org.elasticsearch.index.codec.tsdb.es819.BlockAwareNumericDocValues;
26-
import org.elasticsearch.index.codec.tsdb.es819.SingletonLongDocValuesBlockLoader;
2724
import org.elasticsearch.index.mapper.BlockLoader.BlockFactory;
2825
import org.elasticsearch.index.mapper.BlockLoader.BooleanBuilder;
2926
import org.elasticsearch.index.mapper.BlockLoader.Builder;
@@ -91,16 +88,9 @@ public SortedSetDocValues ordinals(LeafReaderContext context) throws IOException
9188

9289
public static class LongsBlockLoader extends DocValuesBlockLoader {
9390
private final String fieldName;
94-
private final IndexMode indexMode;
9591

9692
public LongsBlockLoader(String fieldName) {
9793
this.fieldName = fieldName;
98-
this.indexMode = null;
99-
}
100-
101-
public LongsBlockLoader(String fieldName, IndexMode indexMode) {
102-
this.fieldName = fieldName;
103-
this.indexMode = indexMode;
10494
}
10595

10696
@Override
@@ -110,15 +100,6 @@ public Builder builder(BlockFactory factory, int expectedCount) {
110100

111101
@Override
112102
public AllReader reader(LeafReaderContext context) throws IOException {
113-
if (fieldName.equals("@timestamp") && (indexMode == IndexMode.TIME_SERIES || indexMode == IndexMode.LOGSDB)) {
114-
var singleton = context.reader().getNumericDocValues(fieldName);
115-
if (singleton == null) {
116-
var docValues = context.reader().getSortedNumericDocValues(fieldName);
117-
singleton = DocValues.unwrapSingleton(docValues);
118-
}
119-
return new BlockAwareSingletonLongs((BlockAwareNumericDocValues) singleton);
120-
}
121-
122103
SortedNumericDocValues docValues = context.reader().getSortedNumericDocValues(fieldName);
123104
if (docValues != null) {
124105
NumericDocValues singleton = DocValues.unwrapSingleton(docValues);
@@ -135,7 +116,7 @@ public AllReader reader(LeafReaderContext context) throws IOException {
135116
}
136117
}
137118

138-
private static class SingletonLongs extends BlockDocValuesReader {
119+
static class SingletonLongs extends BlockDocValuesReader {
139120
private final NumericDocValues numericDocValues;
140121

141122
SingletonLongs(NumericDocValues numericDocValues) {
@@ -183,37 +164,6 @@ public String toString() {
183164
}
184165
}
185166

186-
private static class BlockAwareSingletonLongs extends BlockDocValuesReader {
187-
private final SingletonLongDocValuesBlockLoader blockLoader;
188-
189-
BlockAwareSingletonLongs(BlockAwareNumericDocValues blockAware) {
190-
this.blockLoader = blockAware.getSingletonBlockLoader();
191-
}
192-
193-
@Override
194-
public BlockLoader.Block read(BlockFactory factory, Docs docs, int offset) throws IOException {
195-
try (BlockLoader.SingletonLongBuilder builder = factory.singletonLongs(docs.count() - offset)) {
196-
blockLoader.loadBlock(builder, docs, offset);
197-
return builder.build();
198-
}
199-
}
200-
201-
@Override
202-
public void read(int docId, BlockLoader.StoredFields storedFields, Builder builder) throws IOException {
203-
throw new UnsupportedOperationException();
204-
}
205-
206-
@Override
207-
public int docId() {
208-
return blockLoader.docID();
209-
}
210-
211-
@Override
212-
public String toString() {
213-
return "BlockDocValuesReader.BlockAwareSingletonLongs";
214-
}
215-
}
216-
217167
private static class Longs extends BlockDocValuesReader {
218168
private final SortedNumericDocValues numericDocValues;
219169
private int docID = -1;

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -996,8 +996,13 @@ public Function<byte[], Number> pointReaderIfPossible() {
996996

997997
@Override
998998
public BlockLoader blockLoader(BlockLoaderContext blContext) {
999+
var indexMode = blContext.indexSettings().getMode();
9991000
if (hasDocValues()) {
1000-
return new BlockDocValuesReader.LongsBlockLoader(name(), blContext.indexSettings().getMode());
1001+
if (name().equals("@timestamp") && (indexMode == IndexMode.TIME_SERIES || indexMode == IndexMode.LOGSDB)) {
1002+
return new TimestampBlockLoader();
1003+
} else {
1004+
return new BlockDocValuesReader.LongsBlockLoader(name());
1005+
}
10011006
}
10021007

10031008
// Multi fields don't have fallback synthetic source.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.index.mapper;
11+
12+
import org.apache.lucene.index.DocValues;
13+
import org.apache.lucene.index.LeafReaderContext;
14+
import org.apache.lucene.index.NumericDocValues;
15+
import org.apache.lucene.index.SortedSetDocValues;
16+
import org.elasticsearch.index.codec.tsdb.es819.BlockAwareNumericDocValues;
17+
import org.elasticsearch.index.codec.tsdb.es819.SingletonLongDocValuesBlockLoader;
18+
import org.elasticsearch.search.fetch.StoredFieldsSpec;
19+
20+
import java.io.IOException;
21+
22+
public final class TimestampBlockLoader implements BlockLoader {
23+
24+
private static final String FIELD_NAME = "@timestamp";
25+
26+
@Override
27+
public Builder builder(BlockFactory factory, int expectedCount) {
28+
return factory.longs(expectedCount);
29+
}
30+
31+
@Override
32+
public ColumnAtATimeReader columnAtATimeReader(LeafReaderContext context) throws IOException {
33+
var singleton = getNumericDocValues(context);
34+
return new Timestamps((BlockAwareNumericDocValues) singleton);
35+
}
36+
37+
private static NumericDocValues getNumericDocValues(LeafReaderContext context) throws IOException {
38+
var singleton = context.reader().getNumericDocValues(FIELD_NAME);
39+
if (singleton == null) {
40+
var docValues = context.reader().getSortedNumericDocValues(FIELD_NAME);
41+
singleton = DocValues.unwrapSingleton(docValues);
42+
}
43+
return singleton;
44+
}
45+
46+
@Override
47+
public RowStrideReader rowStrideReader(LeafReaderContext context) throws IOException {
48+
return new BlockDocValuesReader.SingletonLongs(getNumericDocValues(context));
49+
}
50+
51+
@Override
52+
public StoredFieldsSpec rowStrideStoredFieldSpec() {
53+
return StoredFieldsSpec.NO_REQUIREMENTS;
54+
}
55+
56+
@Override
57+
public boolean supportsOrdinals() {
58+
return false;
59+
}
60+
61+
@Override
62+
public SortedSetDocValues ordinals(LeafReaderContext context) throws IOException {
63+
throw new UnsupportedOperationException();
64+
}
65+
66+
public static final class Timestamps implements ColumnAtATimeReader {
67+
private final Thread creationThread;
68+
private final SingletonLongDocValuesBlockLoader blockLoader;
69+
70+
Timestamps(BlockAwareNumericDocValues blockAware) {
71+
this.creationThread = Thread.currentThread();
72+
this.blockLoader = blockAware.getSingletonBlockLoader();
73+
}
74+
75+
@Override
76+
public BlockLoader.Block read(BlockFactory factory, Docs docs, int offset) throws IOException {
77+
try (BlockLoader.SingletonLongBuilder builder = factory.singletonLongs(docs.count() - offset)) {
78+
blockLoader.loadBlock(builder, docs, offset);
79+
return builder.build();
80+
}
81+
}
82+
83+
@Override
84+
public boolean canReuse(int startingDocID) {
85+
return creationThread == Thread.currentThread() && blockLoader.docID() <= startingDocID;
86+
}
87+
88+
@Override
89+
public String toString() {
90+
return "TimestampBlockLoader.Timestamps";
91+
}
92+
}
93+
}

server/src/test/java/org/elasticsearch/index/mapper/blockloader/DateBulkBlockLoadingTests.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@
2929
import org.elasticsearch.index.mapper.MappedFieldType;
3030
import org.elasticsearch.index.mapper.MapperServiceTestCase;
3131
import org.elasticsearch.index.mapper.TestBlock;
32+
import org.elasticsearch.index.mapper.TimestampBlockLoader;
3233

3334
import java.util.stream.IntStream;
3435

3536
import static org.hamcrest.Matchers.equalTo;
37+
import static org.hamcrest.Matchers.instanceOf;
3638
import static org.mockito.Mockito.mock;
3739
import static org.mockito.Mockito.when;
3840

@@ -78,7 +80,7 @@ public void testManyValues() throws Exception {
7880
{
7981
// One big doc block
8082
var columnReader = blockLoader.columnAtATimeReader(context);
81-
assertThat(columnReader.getClass().getSimpleName(), equalTo("BlockAwareSingletonLongs"));
83+
assertThat(columnReader, instanceOf(TimestampBlockLoader.Timestamps.class));
8284
var docBlock = TestBlock.docs(IntStream.range(from, to).toArray());
8385
var block = (TestBlock) columnReader.read(TestBlock.factory(), docBlock, 0);
8486
assertThat(block.size(), equalTo(to - from));
@@ -90,7 +92,7 @@ public void testManyValues() throws Exception {
9092
// Smaller doc blocks
9193
int docBlockSize = 1000;
9294
var columnReader = blockLoader.columnAtATimeReader(context);
93-
assertThat(columnReader.getClass().getSimpleName(), equalTo("BlockAwareSingletonLongs"));
95+
assertThat(columnReader, instanceOf(TimestampBlockLoader.Timestamps.class));
9496
for (int i = from; i < to; i += docBlockSize) {
9597
var docBlock = TestBlock.docs(IntStream.range(i, i + docBlockSize).toArray());
9698
var block = (TestBlock) columnReader.read(TestBlock.factory(), docBlock, 0);
@@ -104,7 +106,7 @@ public void testManyValues() throws Exception {
104106
{
105107
// One smaller doc block:
106108
var columnReader = blockLoader.columnAtATimeReader(context);
107-
assertThat(columnReader.getClass().getSimpleName(), equalTo("BlockAwareSingletonLongs"));
109+
assertThat(columnReader, instanceOf(TimestampBlockLoader.Timestamps.class));
108110
var docBlock = TestBlock.docs(IntStream.range(1010, 2020).toArray());
109111
var block = (TestBlock) columnReader.read(TestBlock.factory(), docBlock, 0);
110112
assertThat(block.size(), equalTo(1010));
@@ -116,7 +118,7 @@ public void testManyValues() throws Exception {
116118
{
117119
// Read two tiny blocks:
118120
var columnReader = blockLoader.columnAtATimeReader(context);
119-
assertThat(columnReader.getClass().getSimpleName(), equalTo("BlockAwareSingletonLongs"));
121+
assertThat(columnReader, instanceOf(TimestampBlockLoader.Timestamps.class));
120122
var docBlock = TestBlock.docs(IntStream.range(32, 64).toArray());
121123
var block = (TestBlock) columnReader.read(TestBlock.factory(), docBlock, 0);
122124
assertThat(block.size(), equalTo(32));

0 commit comments

Comments
 (0)