Skip to content

Commit f7ff379

Browse files
committed
Specialize SingletonOrdinalsBuilder to handle dense cases.
1 parent 852b25e commit f7ff379

File tree

7 files changed

+67
-26
lines changed

7 files changed

+67
-26
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ public long cost() {
373373
@Override
374374
public BlockLoader.Block read(BlockLoader.BlockFactory factory, BlockLoader.Docs docs, int offset) throws IOException {
375375
if (ords instanceof BulkNumericDocValues b) {
376-
try (var builder = factory.singletonOrdinalsBuilder(this, docs.count() - offset)) {
376+
try (var builder = factory.singletonOrdinalsBuilder(this, docs.count() - offset, true)) {
377377
return b.readOrdinals(builder, docs, offset);
378378
}
379379
} else {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ public BlockLoader.Block read(BlockFactory factory, Docs docs, int offset) throw
663663
if (ordinals instanceof BulkSortedDocValues bulkDv && bulkDv.supportsBlockRead()) {
664664
return bulkDv.read(factory, docs, offset);
665665
}
666-
try (var builder = factory.singletonOrdinalsBuilder(ordinals, docs.count() - offset)) {
666+
try (var builder = factory.singletonOrdinalsBuilder(ordinals, docs.count() - offset, false)) {
667667
for (int i = offset; i < docs.count(); i++) {
668668
int doc = docs.get(i);
669669
if (doc < ordinals.docID()) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ interface BlockFactory {
430430
/**
431431
* Build a reader for reading {@link SortedDocValues}
432432
*/
433-
SingletonOrdinalsBuilder singletonOrdinalsBuilder(SortedDocValues ordinals, int count);
433+
SingletonOrdinalsBuilder singletonOrdinalsBuilder(SortedDocValues ordinals, int count, boolean isDense);
434434

435435
/**
436436
* Build a reader for reading {@link SortedSetDocValues}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,11 @@ public BlockLoader.Block constantBytes(BytesRef value, int count) {
268268
}
269269

270270
@Override
271-
public BlockLoader.SingletonOrdinalsBuilder singletonOrdinalsBuilder(SortedDocValues ordinals, int expectedCount) {
271+
public BlockLoader.SingletonOrdinalsBuilder singletonOrdinalsBuilder(
272+
SortedDocValues ordinals,
273+
int expectedCount,
274+
boolean isDense
275+
) {
272276
class SingletonOrdsBuilder extends TestBlock.Builder implements BlockLoader.SingletonOrdinalsBuilder {
273277
private SingletonOrdsBuilder() {
274278
super(expectedCount);

x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/lucene/read/DelegatingBlockLoaderFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ public BlockLoader.Builder nulls(int expectedCount) {
8787
}
8888

8989
@Override
90-
public BlockLoader.SingletonOrdinalsBuilder singletonOrdinalsBuilder(SortedDocValues ordinals, int count) {
91-
return new SingletonOrdinalsBuilder(factory, ordinals, count);
90+
public BlockLoader.SingletonOrdinalsBuilder singletonOrdinalsBuilder(SortedDocValues ordinals, int count, boolean isDense) {
91+
return new SingletonOrdinalsBuilder(factory, ordinals, count, isDense);
9292
}
9393

9494
@Override

x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/lucene/read/SingletonOrdinalsBuilder.java

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,23 @@ public class SingletonOrdinalsBuilder implements BlockLoader.SingletonOrdinalsBu
3333
private int maxOrd = Integer.MIN_VALUE;
3434
private final int[] ords;
3535
private int count;
36+
private final boolean isDense;
3637

3738
public SingletonOrdinalsBuilder(BlockFactory blockFactory, SortedDocValues docValues, int count) {
39+
this(blockFactory, docValues, count, false);
40+
}
41+
42+
public SingletonOrdinalsBuilder(BlockFactory blockFactory, SortedDocValues docValues, int count, boolean isDense) {
3843
this.blockFactory = blockFactory;
3944
this.docValues = docValues;
4045
blockFactory.adjustBreaker(ordsSize(count));
4146
this.ords = new int[count];
47+
this.isDense = isDense;
4248
}
4349

4450
@Override
4551
public SingletonOrdinalsBuilder appendNull() {
52+
assert isDense == false;
4653
ords[count++] = -1; // real ords can't be < 0, so we use -1 as null
4754
return this;
4855
}
@@ -78,9 +85,11 @@ private BytesRefBlock tryBuildConstantBlock() {
7885
if (minOrd != maxOrd) {
7986
return null;
8087
}
81-
for (int ord : ords) {
82-
if (ord == -1) {
83-
return null;
88+
if (isDense == false) {
89+
for (int ord : ords) {
90+
if (ord == -1) {
91+
return null;
92+
}
8493
}
8594
}
8695
final BytesRef v;
@@ -116,33 +125,61 @@ BytesRefBlock buildOrdinal() {
116125
try {
117126
int[] newOrds = new int[valueCount];
118127
Arrays.fill(newOrds, -1);
119-
for (int ord : ords) {
120-
if (ord != -1) {
128+
// Re-mapping ordinals to be more space-efficient:
129+
if (isDense) {
130+
for (int ord : ords) {
121131
newOrds[ord - minOrd] = 0;
122132
}
133+
} else {
134+
for (int ord : ords) {
135+
if (ord != -1) {
136+
newOrds[ord - minOrd] = 0;
137+
}
138+
}
123139
}
124140
// resolve the ordinals and remaps the ordinals
125-
int nextOrd = -1;
126-
try (BytesRefVector.Builder bytesBuilder = blockFactory.newBytesRefVectorBuilder(Math.min(valueCount, ords.length))) {
127-
for (int i = 0; i < newOrds.length; i++) {
128-
if (newOrds[i] != -1) {
129-
newOrds[i] = ++nextOrd;
130-
bytesBuilder.appendBytesRef(docValues.lookupOrd(i + minOrd));
141+
try {
142+
int nextOrd = -1;
143+
BytesRef firstTerm = minOrd != Integer.MAX_VALUE ? docValues.lookupOrd(minOrd) : null;
144+
int estimatedSize;
145+
if (firstTerm != null) {
146+
estimatedSize = Math.min(valueCount, ords.length) * firstTerm.length;
147+
} else {
148+
estimatedSize = Math.min(valueCount, ords.length);
149+
}
150+
try (BytesRefVector.Builder bytesBuilder = blockFactory.newBytesRefVectorBuilder(estimatedSize)) {
151+
if (firstTerm != null) {
152+
newOrds[0] = ++nextOrd;
153+
bytesBuilder.appendBytesRef(firstTerm);
154+
}
155+
for (int i = firstTerm != null ? 1 : 0; i < newOrds.length; i++) {
156+
if (newOrds[i] != -1) {
157+
newOrds[i] = ++nextOrd;
158+
bytesBuilder.appendBytesRef(docValues.lookupOrd(i + minOrd));
159+
}
131160
}
161+
bytesVector = bytesBuilder.build();
132162
}
133-
bytesVector = bytesBuilder.build();
134163
} catch (IOException e) {
135164
throw new UncheckedIOException("error resolving ordinals", e);
136165
}
137-
try (IntBlock.Builder ordinalsBuilder = blockFactory.newIntBlockBuilder(ords.length)) {
138-
for (int ord : ords) {
139-
if (ord == -1) {
140-
ordinalsBuilder.appendNull();
141-
} else {
142-
ordinalsBuilder.appendInt(newOrds[ord - minOrd]);
166+
if (isDense) {
167+
// Reusing ords array and overwrite all slots with re-mapped ordinals
168+
for (int i = 0; i < ords.length; i++) {
169+
ords[i] = newOrds[ords[i] - minOrd];
170+
}
171+
ordinalBlock = blockFactory.newIntArrayVector(ords, ords.length).asBlock();
172+
} else {
173+
try (IntBlock.Builder ordinalsBuilder = blockFactory.newIntBlockBuilder(ords.length)) {
174+
for (int ord : ords) {
175+
if (ord == -1) {
176+
ordinalsBuilder.appendNull();
177+
} else {
178+
ordinalsBuilder.appendInt(newOrds[ord - minOrd]);
179+
}
143180
}
181+
ordinalBlock = ordinalsBuilder.build();
144182
}
145-
ordinalBlock = ordinalsBuilder.build();
146183
}
147184
final OrdinalBytesRefBlock result = new OrdinalBytesRefBlock(ordinalBlock, bytesVector);
148185
bytesVector = null;

x-pack/plugin/esql/compute/src/main/java/org/elasticsearch/compute/lucene/read/TimeSeriesExtractFieldOperator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public BlockLoader.Block constantBytes(BytesRef value, int count) {
208208
}
209209

210210
@Override
211-
public BlockLoader.SingletonOrdinalsBuilder singletonOrdinalsBuilder(SortedDocValues ordinals, int count) {
211+
public BlockLoader.SingletonOrdinalsBuilder singletonOrdinalsBuilder(SortedDocValues ordinals, int count, boolean isDense) {
212212
throw new UnsupportedOperationException("must not be used by column readers");
213213
}
214214
}

0 commit comments

Comments
 (0)