Skip to content

Commit dacbf92

Browse files
authored
Optimize InsertTabletStatement tablet conversion (#17805)
1 parent 66d0c07 commit dacbf92

1 file changed

Lines changed: 66 additions & 52 deletions

File tree

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/crud/InsertTabletStatement.java

Lines changed: 66 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -740,25 +740,38 @@ public Tablet convertToTablet() throws MetadataException {
740740

741741
// Build schemas and track valid column indices (skip null columns)
742742
// measurements and dataTypes being null is standard - skip those columns
743-
final List<IMeasurementSchema> schemas = new ArrayList<>();
744-
final List<Integer> validColumnIndices = new ArrayList<>();
745-
for (int i = 0; i < originalSchemaSize; i++) {
746-
if (dataTypes != null && measurements[i] != null && dataTypes[i] != null) {
747-
// Create MeasurementSchema if not present
748-
schemas.add(new MeasurementSchema(measurements[i], dataTypes[i]));
749-
validColumnIndices.add(i);
743+
final List<IMeasurementSchema> schemas = new ArrayList<>(originalSchemaSize);
744+
final int[] validColumnIndices = new int[originalSchemaSize];
745+
int validColumnCount = 0;
746+
if (dataTypes != null) {
747+
final int dataTypeSize = Math.min(originalSchemaSize, dataTypes.length);
748+
for (int i = 0; i < dataTypeSize; i++) {
749+
if (measurements[i] != null && dataTypes[i] != null) {
750+
final MeasurementSchema measurementSchema =
751+
measurementSchemas != null && i < measurementSchemas.length
752+
? measurementSchemas[i]
753+
: null;
754+
schemas.add(
755+
measurementSchema != null
756+
&& Objects.equals(measurementSchema.getMeasurementName(), measurements[i])
757+
&& measurementSchema.getType() == dataTypes[i]
758+
? measurementSchema
759+
: new MeasurementSchema(measurements[i], dataTypes[i]));
760+
validColumnIndices[validColumnCount++] = i;
761+
}
762+
// Skip null columns - don't add to schemas or validColumnIndices
750763
}
751-
// Skip null columns - don't add to schemas or validColumnIndices
752764
}
753765

754-
final int schemaSize = schemas.size();
766+
final int schemaSize = validColumnCount;
755767

756768
// Get columnTypes (for table model) - only for valid columns
757769
final TsTableColumnCategory[] columnCategories = this.getColumnCategories();
758-
final List<ColumnCategory> tabletColumnTypes = new ArrayList<>();
770+
final List<ColumnCategory> tabletColumnTypes = new ArrayList<>(schemaSize);
759771
if (columnCategories != null && columnCategories.length > 0) {
760-
for (final int validIndex : validColumnIndices) {
761-
if (columnCategories[validIndex] != null) {
772+
for (int i = 0; i < schemaSize; i++) {
773+
final int validIndex = validColumnIndices[i];
774+
if (validIndex < columnCategories.length && columnCategories[validIndex] != null) {
762775
tabletColumnTypes.add(columnCategories[validIndex].toTsFileColumnType());
763776
} else {
764777
tabletColumnTypes.add(ColumnCategory.FIELD);
@@ -775,9 +788,10 @@ public Tablet convertToTablet() throws MetadataException {
775788
final long[] times = this.getTimes();
776789
final int rowSize = this.getRowCount();
777790
final long[] timestamps;
778-
if (times != null && times.length >= rowSize && rowSize > 0) {
779-
timestamps = new long[rowSize];
780-
System.arraycopy(times, 0, timestamps, 0, rowSize);
791+
if (rowSize == 0) {
792+
timestamps = new long[0];
793+
} else if (times != null && times.length >= rowSize) {
794+
timestamps = Arrays.copyOf(times, rowSize);
781795
} else {
782796
LOGGER.warn(
783797
"Times array is null or too small. times.length={}, rowSize={}, deviceId={}",
@@ -788,13 +802,15 @@ public Tablet convertToTablet() throws MetadataException {
788802
}
789803

790804
// Get values - convert Statement columns to Tablet format, only for valid columns
791-
// All arrays are truncated/copied to rowSize length
805+
// All arrays are copied to rowSize length
792806
final Object[] statementColumns = this.getColumns();
793807
final Object[] tabletValues = new Object[schemaSize];
794808
if (statementColumns != null && statementColumns.length > 0) {
795-
for (int i = 0; i < validColumnIndices.size(); i++) {
796-
final int originalIndex = validColumnIndices.get(i);
797-
if (statementColumns[originalIndex] != null && dataTypes[originalIndex] != null) {
809+
for (int i = 0; i < schemaSize; i++) {
810+
final int originalIndex = validColumnIndices[i];
811+
if (originalIndex < statementColumns.length
812+
&& statementColumns[originalIndex] != null
813+
&& dataTypes[originalIndex] != null) {
798814
tabletValues[i] =
799815
convertColumnToTablet(
800816
statementColumns[originalIndex], dataTypes[originalIndex], rowSize);
@@ -806,22 +822,25 @@ public Tablet convertToTablet() throws MetadataException {
806822

807823
// Get bitMaps - copy and truncate to rowSize, only for valid columns
808824
final BitMap[] originalBitMaps = this.getBitMaps();
809-
final BitMap[] bitMaps;
825+
BitMap[] bitMaps = null;
810826
if (originalBitMaps != null && originalBitMaps.length > 0) {
811-
bitMaps = new BitMap[schemaSize];
812-
for (int i = 0; i < validColumnIndices.size(); i++) {
813-
final int originalIndex = validColumnIndices.get(i);
814-
if (originalBitMaps[originalIndex] != null) {
815-
// Create a new BitMap truncated to rowSize
816-
final byte[] truncatedBytes =
817-
originalBitMaps[originalIndex].getTruncatedByteArray(rowSize);
818-
bitMaps[i] = new BitMap(rowSize, truncatedBytes);
827+
final BitMap[] copiedBitMaps = new BitMap[schemaSize];
828+
boolean hasMarkedBitMap = false;
829+
for (int i = 0; i < schemaSize; i++) {
830+
final int originalIndex = validColumnIndices[i];
831+
if (originalIndex < originalBitMaps.length && originalBitMaps[originalIndex] != null) {
832+
final BitMap originalBitMap = originalBitMaps[originalIndex];
833+
if (!originalBitMap.isAllUnmarked(Math.min(rowSize, originalBitMap.getSize()))) {
834+
copiedBitMaps[i] = new BitMap(rowSize, originalBitMap.getTruncatedByteArray(rowSize));
835+
hasMarkedBitMap = true;
836+
}
819837
} else {
820-
bitMaps[i] = null;
838+
copiedBitMaps[i] = null;
821839
}
822840
}
823-
} else {
824-
bitMaps = null;
841+
if (hasMarkedBitMap) {
842+
bitMaps = copiedBitMaps;
843+
}
825844
}
826845

827846
// Create Tablet using the full constructor
@@ -834,7 +853,7 @@ public Tablet convertToTablet() throws MetadataException {
834853
tabletColumnTypes,
835854
timestamps,
836855
tabletValues,
837-
BitMapUtils.compactBitMaps(bitMaps, rowSize),
856+
bitMaps,
838857
rowSize);
839858
} catch (final Exception e) {
840859
throw new MetadataException(
@@ -845,13 +864,13 @@ public Tablet convertToTablet() throws MetadataException {
845864
/**
846865
* Convert a single column value from Statement format to Tablet format. Statement uses primitive
847866
* arrays (e.g., int[], long[], float[]), while Tablet may need different format. All arrays are
848-
* copied and truncated to rowSize length to ensure immutability - even if the original array is
849-
* modified, the converted array remains unchanged.
867+
* copied to rowSize length to ensure immutability - even if the original array is modified, the
868+
* converted array remains unchanged.
850869
*
851870
* @param columnValue column value from Statement (primitive array)
852871
* @param dataType data type of the column
853-
* @param rowSize number of rows to copy (truncate to this length)
854-
* @return column value in Tablet format (copied and truncated array)
872+
* @param rowSize number of rows to copy
873+
* @return column value in Tablet format (copied to rowSize)
855874
*/
856875
private Object convertColumnToTablet(
857876
final Object columnValue, final TSDataType dataType, final int rowSize) {
@@ -862,39 +881,34 @@ private Object convertColumnToTablet(
862881

863882
if (TSDataType.DATE.equals(dataType)) {
864883
final int[] values = (int[]) columnValue;
865-
// Copy and truncate to rowSize
866-
final int[] copiedValues = Arrays.copyOf(values, Math.min(values.length, rowSize));
867884
final LocalDate[] localDateValue = new LocalDate[rowSize];
868-
for (int i = 0; i < copiedValues.length; i++) {
869-
localDateValue[i] = DateUtils.parseIntToLocalDate(copiedValues[i]);
870-
}
871-
// Fill remaining with null if needed
872-
for (int i = copiedValues.length; i < rowSize; i++) {
873-
localDateValue[i] = null;
885+
final int size = Math.min(values.length, rowSize);
886+
for (int i = 0; i < size; i++) {
887+
localDateValue[i] = DateUtils.parseIntToLocalDate(values[i]);
874888
}
875889
return localDateValue;
876890
}
877891

878-
// For primitive arrays, copy and truncate to rowSize
892+
// For primitive arrays, copy to rowSize
879893
if (columnValue instanceof boolean[]) {
880894
final boolean[] original = (boolean[]) columnValue;
881-
return Arrays.copyOf(original, Math.min(original.length, rowSize));
895+
return Arrays.copyOf(original, rowSize);
882896
} else if (columnValue instanceof int[]) {
883897
final int[] original = (int[]) columnValue;
884-
return Arrays.copyOf(original, Math.min(original.length, rowSize));
898+
return Arrays.copyOf(original, rowSize);
885899
} else if (columnValue instanceof long[]) {
886900
final long[] original = (long[]) columnValue;
887-
return Arrays.copyOf(original, Math.min(original.length, rowSize));
901+
return Arrays.copyOf(original, rowSize);
888902
} else if (columnValue instanceof float[]) {
889903
final float[] original = (float[]) columnValue;
890-
return Arrays.copyOf(original, Math.min(original.length, rowSize));
904+
return Arrays.copyOf(original, rowSize);
891905
} else if (columnValue instanceof double[]) {
892906
final double[] original = (double[]) columnValue;
893-
return Arrays.copyOf(original, Math.min(original.length, rowSize));
907+
return Arrays.copyOf(original, rowSize);
894908
} else if (columnValue instanceof Binary[]) {
895-
// For Binary arrays, create a new array and copy references, truncate to rowSize
909+
// For Binary arrays, create a new array and copy references to rowSize
896910
final Binary[] original = (Binary[]) columnValue;
897-
return Arrays.copyOf(original, Math.min(original.length, rowSize));
911+
return Arrays.copyOf(original, rowSize);
898912
}
899913

900914
// For other types, return as-is (should not happen for standard types)

0 commit comments

Comments
 (0)