@@ -133,11 +133,12 @@ public Page getCheckedOutput() throws IOException {
133
133
if (docCollector != null ) {
134
134
blocks [blockIndex ++] = docCollector .build ().asBlock ();
135
135
}
136
- blocks [blockIndex ++] = tsHashesBuilder .build ().asBlock ();
136
+ OrdinalBytesRefVector tsidVector = tsHashesBuilder .build ();
137
+ blocks [blockIndex ++] = tsidVector .asBlock ();
137
138
tsHashesBuilder = new TsidBuilder (blockFactory , Math .min (remainingDocs , maxPageSize ));
138
139
blocks [blockIndex ++] = timestampsBuilder .build ().asBlock ();
139
140
timestampsBuilder = blockFactory .newLongVectorBuilder (Math .min (remainingDocs , maxPageSize ));
140
- System .arraycopy (fieldsReader .buildBlocks (), 0 , blocks , blockIndex , fieldsToExtracts .size ());
141
+ System .arraycopy (fieldsReader .buildBlocks (tsidVector . getOrdinalsVector () ), 0 , blocks , blockIndex , fieldsToExtracts .size ());
141
142
page = new Page (currentPagePos , blocks );
142
143
currentPagePos = 0 ;
143
144
}
@@ -217,6 +218,7 @@ void readDocsForNextPage() throws IOException {
217
218
}
218
219
219
220
private boolean readValuesForOneTsid (PriorityQueue <LeafIterator > sub ) throws IOException {
221
+ boolean first = true ;
220
222
do {
221
223
LeafIterator top = sub .top ();
222
224
currentPagePos ++;
@@ -226,7 +228,8 @@ private boolean readValuesForOneTsid(PriorityQueue<LeafIterator> sub) throws IOE
226
228
}
227
229
tsHashesBuilder .appendOrdinal ();
228
230
timestampsBuilder .appendLong (top .timestamp );
229
- fieldsReader .readValues (top .segmentOrd , top .docID );
231
+ fieldsReader .readValues (top .segmentOrd , top .docID , first == false );
232
+ first = false ;
230
233
if (top .nextDoc ()) {
231
234
sub .updateTop ();
232
235
} else if (top .docID == DocIdSetIterator .NO_MORE_DOCS ) {
@@ -350,6 +353,7 @@ static final class ShardLevelFieldsReader implements Releasable {
350
353
private final BlockLoaderFactory blockFactory ;
351
354
private final SegmentLevelFieldsReader [] segments ;
352
355
private final BlockLoader [] loaders ;
356
+ private final boolean [] dimensions ;
353
357
private final Block .Builder [] builders ;
354
358
private final StoredFieldsSpec storedFieldsSpec ;
355
359
private final SourceLoader sourceLoader ;
@@ -377,10 +381,18 @@ static final class ShardLevelFieldsReader implements Releasable {
377
381
sourceLoader = null ;
378
382
}
379
383
this .storedFieldsSpec = storedFieldsSpec ;
384
+ this .dimensions = new boolean [fields .size ()];
385
+ for (int i = 0 ; i < fields .size (); i ++) {
386
+ dimensions [i ] = shardContext .fieldType (fields .get (i ).name ()).isDimension ();
387
+ }
380
388
}
381
389
382
- void readValues (int segment , int docID ) throws IOException {
383
- segments [segment ].read (docID , builders );
390
+ /**
391
+ * For dimension fields, skips reading them when {@code nonDimensionFieldsOnly} is true,
392
+ * since they only need to be read once per tsid.
393
+ */
394
+ void readValues (int segment , int docID , boolean nonDimensionFieldsOnly ) throws IOException {
395
+ segments [segment ].read (docID , builders , nonDimensionFieldsOnly , dimensions );
384
396
}
385
397
386
398
void prepareForReading (int estimatedSize ) throws IOException {
@@ -396,12 +408,46 @@ void prepareForReading(int estimatedSize) throws IOException {
396
408
}
397
409
}
398
410
399
- Block [] buildBlocks () {
400
- Block [] blocks = Block .Builder .buildAll (builders );
401
- Arrays .fill (builders , null );
411
+ Block [] buildBlocks (IntVector tsidOrdinals ) {
412
+ final Block [] blocks = new Block [loaders .length ];
413
+ try {
414
+ for (int i = 0 ; i < builders .length ; i ++) {
415
+ if (dimensions [i ]) {
416
+ blocks [i ] = buildBlockForDimensionField (builders [i ], tsidOrdinals );
417
+ } else {
418
+ blocks [i ] = builders [i ].build ();
419
+ }
420
+ }
421
+ Arrays .fill (builders , null );
422
+ } finally {
423
+ if (blocks .length > 0 && blocks [blocks .length - 1 ] == null ) {
424
+ Releasables .close (blocks );
425
+ }
426
+ }
402
427
return blocks ;
403
428
}
404
429
430
+ private Block buildBlockForDimensionField (Block .Builder builder , IntVector tsidOrdinals ) {
431
+ try (var values = builder .build ()) {
432
+ if (values .asVector () instanceof BytesRefVector bytes ) {
433
+ tsidOrdinals .incRef ();
434
+ values .incRef ();
435
+ return new OrdinalBytesRefVector (tsidOrdinals , bytes ).asBlock ();
436
+ } else if (values .areAllValuesNull ()) {
437
+ return blockFactory .factory .newConstantNullBlock (tsidOrdinals .getPositionCount ());
438
+ } else {
439
+ final int positionCount = tsidOrdinals .getPositionCount ();
440
+ try (var newBuilder = values .elementType ().newBlockBuilder (positionCount , blockFactory .factory )) {
441
+ for (int p = 0 ; p < positionCount ; p ++) {
442
+ int pos = tsidOrdinals .getInt (p );
443
+ newBuilder .copyFrom (values , pos , pos + 1 );
444
+ }
445
+ return newBuilder .build ();
446
+ }
447
+ }
448
+ }
449
+ }
450
+
405
451
@ Override
406
452
public void close () {
407
453
Releasables .close (builders );
@@ -435,10 +481,18 @@ private void reinitializeIfNeeded(SourceLoader sourceLoader, StoredFieldsSpec st
435
481
}
436
482
}
437
483
438
- void read (int docId , Block .Builder [] builder ) throws IOException {
484
+ void read (int docId , Block .Builder [] builder , boolean nonDimensionFieldsOnly , boolean [] dimensions ) throws IOException {
439
485
storedFields .advanceTo (docId );
440
- for (int i = 0 ; i < rowStride .length ; i ++) {
441
- rowStride [i ].read (docId , storedFields , builder [i ]);
486
+ if (nonDimensionFieldsOnly ) {
487
+ for (int i = 0 ; i < rowStride .length ; i ++) {
488
+ if (dimensions [i ] == false ) {
489
+ rowStride [i ].read (docId , storedFields , builder [i ]);
490
+ }
491
+ }
492
+ } else {
493
+ for (int i = 0 ; i < rowStride .length ; i ++) {
494
+ rowStride [i ].read (docId , storedFields , builder [i ]);
495
+ }
442
496
}
443
497
}
444
498
}
@@ -480,9 +534,9 @@ public void close() {
480
534
Releasables .close (dictBuilder , ordinalsBuilder );
481
535
}
482
536
483
- BytesRefVector build () throws IOException {
537
+ OrdinalBytesRefVector build () throws IOException {
484
538
BytesRefVector dict = null ;
485
- BytesRefVector result = null ;
539
+ OrdinalBytesRefVector result = null ;
486
540
IntVector ordinals = null ;
487
541
try {
488
542
dict = dictBuilder .build ();
0 commit comments