@@ -101,6 +101,7 @@ public class TsFileInsertionEventTableParserTabletIterator implements Iterator<T
101101 private List <ColumnCategory > columnTypes ;
102102 private List <String > measurementList ;
103103 private List <TSDataType > dataTypeList ;
104+ private List <IMeasurementSchema > fieldSchemaList ;
104105 private int deviceIdSize ;
105106
106107 private List <ModsOperationUtil .ModsInfo > modsInfoList ;
@@ -194,7 +195,7 @@ public boolean hasNext() {
194195
195196 long size = 0 ;
196197 List <AbstractAlignedChunkMetadata > iChunkMetadataList =
197- reader .getAlignedChunkMetadata (pair .left , true );
198+ reader .getAlignedChunkMetadata (pair .left , false );
198199
199200 Iterator <AbstractAlignedChunkMetadata > chunkMetadataIterator =
200201 iChunkMetadataList .iterator ();
@@ -213,27 +214,7 @@ public boolean hasNext() {
213214 continue ;
214215 }
215216
216- Iterator <IChunkMetadata > iChunkMetadataIterator =
217- alignedChunkMetadata .getValueChunkMetadataList ().iterator ();
218- while (iChunkMetadataIterator .hasNext ()) {
219- IChunkMetadata iChunkMetadata = iChunkMetadataIterator .next ();
220- if (iChunkMetadata == null ) {
221- iChunkMetadataIterator .remove ();
222- continue ;
223- }
224-
225- if (!modifications .isEmpty ()
226- && ModsOperationUtil .isAllDeletedByMods (
227- pair .getLeft (),
228- iChunkMetadata .getMeasurementUid (),
229- alignedChunkMetadata .getStartTime (),
230- alignedChunkMetadata .getEndTime (),
231- modifications )) {
232- iChunkMetadataIterator .remove ();
233- }
234- }
235-
236- if (alignedChunkMetadata .getValueChunkMetadataList ().isEmpty ()) {
217+ if (areAllFieldsDeletedByMods (pair .getLeft (), alignedChunkMetadata )) {
237218 chunkMetadataIterator .remove ();
238219 continue ;
239220 }
@@ -267,6 +248,7 @@ public boolean hasNext() {
267248 dataTypeList = new ArrayList <>();
268249 columnTypes = new ArrayList <>();
269250 measurementList = new ArrayList <>();
251+ fieldSchemaList = new ArrayList <>();
270252
271253 for (int i = 0 ; i < columnSchemaSize ; i ++) {
272254 final IMeasurementSchema schema = tableSchema .getColumnSchemas ().get (i );
@@ -280,6 +262,9 @@ public boolean hasNext() {
280262 measurementList .add (measurementName );
281263 dataTypeList .add (schema .getType ());
282264 }
265+ if (ColumnCategory .FIELD .equals (columnCategory )) {
266+ fieldSchemaList .add (schema );
267+ }
283268 }
284269 }
285270 deviceIdSize = dataTypeList .size ();
@@ -331,9 +316,9 @@ private Tablet buildNextTablet() {
331316 tablet =
332317 new Tablet (
333318 tableName ,
334- measurementList ,
335- dataTypeList ,
336- columnTypes ,
319+ new ArrayList <>( measurementList ) ,
320+ new ArrayList <>( dataTypeList ) ,
321+ new ArrayList <>( columnTypes ) ,
337322 rowCountAndMemorySize .getLeft ());
338323 tablet .initBitMaps ();
339324 isFirstRow = false ;
@@ -376,6 +361,20 @@ private void initChunkReader(final AbstractAlignedChunkMetadata alignedChunkMeta
376361 long size = timeChunkSize ;
377362
378363 final List <Chunk > valueChunkList = new ArrayList <>();
364+ final Map <String , IChunkMetadata > valueChunkMetadataMap =
365+ alignedChunkMetadata .getValueChunkMetadataList ().stream ()
366+ .filter (Objects ::nonNull )
367+ .filter (
368+ metadata ->
369+ !isFieldDeletedByMods (
370+ metadata .getMeasurementUid (),
371+ alignedChunkMetadata .getStartTime (),
372+ alignedChunkMetadata .getEndTime ()))
373+ .collect (
374+ Collectors .toMap (
375+ IChunkMetadata ::getMeasurementUid ,
376+ metadata -> metadata ,
377+ (left , right ) -> left ));
379378
380379 // To ensure that the Tablet has the same alignedChunk column as the current one,
381380 // you need to create a new Tablet to fill in the data.
@@ -392,50 +391,98 @@ private void initChunkReader(final AbstractAlignedChunkMetadata alignedChunkMeta
392391 measurementList .subList (deviceIdSize , measurementList .size ()).clear ();
393392 dataTypeList .subList (deviceIdSize , dataTypeList .size ()).clear ();
394393
395- for (; offset < alignedChunkMetadata .getValueChunkMetadataList ().size (); ++offset ) {
396- final IChunkMetadata metadata = alignedChunkMetadata .getValueChunkMetadataList ().get (offset );
394+ boolean hasSelectedField = fieldSchemaList .isEmpty ();
395+ boolean hasSelectedNonNullChunk = false ;
396+ for (; offset < fieldSchemaList .size (); ++offset ) {
397+ final IMeasurementSchema schema = fieldSchemaList .get (offset );
398+ if (isFieldDeletedByMods (
399+ schema .getMeasurementName (),
400+ alignedChunkMetadata .getStartTime (),
401+ alignedChunkMetadata .getEndTime ())) {
402+ continue ;
403+ }
404+
405+ final IChunkMetadata metadata = valueChunkMetadataMap .get (schema .getMeasurementName ());
406+ Chunk chunk = null ;
397407 if (metadata != null ) {
398- final Chunk chunk = reader .readMemChunk ((ChunkMetadata ) metadata );
399- size += PipeMemoryWeightUtil .calculateChunkRamBytesUsed (chunk );
400- if (size > allocatedMemoryBlockForChunk .getMemoryUsageInBytes ()) {
401- if (valueChunkList . isEmpty () ) {
408+ chunk = reader .readMemChunk ((ChunkMetadata ) metadata );
409+ final long newSize = size + PipeMemoryWeightUtil .calculateChunkRamBytesUsed (chunk );
410+ if (newSize > allocatedMemoryBlockForChunk .getMemoryUsageInBytes ()) {
411+ if (! hasSelectedNonNullChunk ) {
402412 // If the first chunk exceeds the memory limit, we need to allocate more memory
413+ size = newSize ;
403414 PipeDataNodeResourceManager .memory ().forceResize (allocatedMemoryBlockForChunk , size );
404- columnTypes .add (ColumnCategory .FIELD );
405- measurementList .add (metadata .getMeasurementUid ());
406- dataTypeList .add (metadata .getDataType ());
407- valueChunkList .add (chunk );
408- ++offset ;
415+ } else {
416+ break ;
409417 }
410- break ;
411418 } else {
412- // Record the column information corresponding to Meta to fill in Tablet
413- columnTypes .add (ColumnCategory .FIELD );
414- measurementList .add (metadata .getMeasurementUid ());
415- dataTypeList .add (metadata .getDataType ());
416- valueChunkList .add (chunk );
419+ size = newSize ;
417420 }
421+ hasSelectedNonNullChunk = true ;
418422 }
423+ columnTypes .add (ColumnCategory .FIELD );
424+ measurementList .add (schema .getMeasurementName ());
425+ dataTypeList .add (schema .getType ());
426+ valueChunkList .add (chunk );
427+ hasSelectedField = true ;
419428 }
420429
421- if (offset >= alignedChunkMetadata . getValueChunkMetadataList () .size ()) {
430+ if (offset >= fieldSchemaList .size ()) {
422431 currentChunkMetadata = null ;
423432 }
424433
434+ if (!hasSelectedField ) {
435+ this .chunkReader = null ;
436+ this .batchData = null ;
437+ return ;
438+ }
439+
425440 this .chunkReader = new TableChunkReader (timeChunk , valueChunkList , null );
426441 this .modsInfoList =
427442 ModsOperationUtil .initializeMeasurementMods (deviceID , measurementList , modifications );
428443 }
429444
445+ private boolean areAllFieldsDeletedByMods (
446+ final IDeviceID currentDeviceID , final AbstractAlignedChunkMetadata alignedChunkMetadata ) {
447+ if (modifications .isEmpty () || fieldSchemaList .isEmpty ()) {
448+ return false ;
449+ }
450+
451+ for (final IMeasurementSchema schema : fieldSchemaList ) {
452+ if (!ModsOperationUtil .isAllDeletedByMods (
453+ currentDeviceID ,
454+ schema .getMeasurementName (),
455+ alignedChunkMetadata .getStartTime (),
456+ alignedChunkMetadata .getEndTime (),
457+ modifications )) {
458+ return false ;
459+ }
460+ }
461+ return true ;
462+ }
463+
464+ private boolean isFieldDeletedByMods (
465+ final String measurementID , final long startTime , final long endTime ) {
466+ return !modifications .isEmpty ()
467+ && ModsOperationUtil .isAllDeletedByMods (
468+ deviceID , measurementID , startTime , endTime , modifications );
469+ }
470+
430471 private boolean fillMeasurementValueColumns (
431472 final BatchData data , final Tablet tablet , final int rowIndex ) {
432- final TsPrimitiveType [] primitiveTypes = data .getVector ();
473+ final TsPrimitiveType [] primitiveTypes =
474+ Objects .nonNull (data .getVector ()) ? data .getVector () : new TsPrimitiveType [0 ];
433475 boolean needFillTime = false ;
476+ boolean hasNonDeletedField = dataTypeList .size () == deviceIdSize ;
434477
435478 for (int i = deviceIdSize , size = dataTypeList .size (); i < size ; i ++) {
436- final TsPrimitiveType primitiveType = primitiveTypes [i - deviceIdSize ];
437- if (primitiveType == null
438- || ModsOperationUtil .isDelete (data .currentTime (), modsInfoList .get (i ))) {
479+ final TsPrimitiveType primitiveType =
480+ i - deviceIdSize < primitiveTypes .length ? primitiveTypes [i - deviceIdSize ] : null ;
481+ final boolean isDeleted = ModsOperationUtil .isDelete (data .currentTime (), modsInfoList .get (i ));
482+ if (!isDeleted ) {
483+ hasNonDeletedField = true ;
484+ }
485+ if (primitiveType == null || isDeleted ) {
439486 switch (dataTypeList .get (i )) {
440487 case TEXT :
441488 case BLOB :
@@ -480,7 +527,7 @@ private boolean fillMeasurementValueColumns(
480527 throw new UnSupportedDataTypeException ("UnSupported" + primitiveType .getDataType ());
481528 }
482529 }
483- return needFillTime ;
530+ return needFillTime || hasNonDeletedField ;
484531 }
485532
486533 private void fillDeviceIdColumns (
0 commit comments