in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java [1943:2074]
public void encodeBatch(IChunkWriter chunkWriter, BatchEncodeInfo encodeInfo, long[] times) {
AlignedChunkWriterImpl alignedChunkWriter = (AlignedChunkWriterImpl) chunkWriter;
// duplicated time or deleted time are all invalid, true if we don't need this row
BitMap timeDuplicateInfo = null;
int startIndex = index;
// time column
for (; index < rows; index++) {
if (encodeInfo.pointNumInChunk >= encodeInfo.maxNumberOfPointsInChunk
|| encodeInfo.pointNumInPage >= encodeInfo.maxNumberOfPointsInPage) {
break;
}
// skip empty row
if (allValueColDeletedMap != null && allValueColDeletedMap.isMarked(getValueIndex(index))) {
continue;
}
if (isTimeDeleted(index)) {
continue;
}
int nextRowIndex = index + 1;
while (nextRowIndex < rows
&& ((allValueColDeletedMap != null
&& allValueColDeletedMap.isMarked(getValueIndex(nextRowIndex)))
|| (isTimeDeleted(nextRowIndex)))) {
nextRowIndex++;
}
long time = getTime(index);
if (nextRowIndex == rows || time != getTime(nextRowIndex)) {
times[encodeInfo.pointNumInPage++] = time;
encodeInfo.pointNumInChunk++;
} else {
if (Objects.isNull(timeDuplicateInfo)) {
timeDuplicateInfo = new BitMap(rows);
}
timeDuplicateInfo.mark(index);
}
index = nextRowIndex - 1;
}
int columnCount = dataTypeList.size();
// value columns
for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
ValueChunkWriter valueChunkWriter =
alignedChunkWriter.getValueChunkWriterByIndex(columnIndex);
int validColumnIndex = columnIndexList.get(columnIndex);
// Pair of Time and Index
Pair<Long, Integer> lastValidPointIndexForTimeDupCheck = null;
if (Objects.nonNull(timeDuplicateInfo)) {
lastValidPointIndexForTimeDupCheck = new Pair<>(Long.MIN_VALUE, null);
}
for (int sortedRowIndex = startIndex; sortedRowIndex < index; sortedRowIndex++) {
// skip empty row
if ((allValueColDeletedMap != null
&& allValueColDeletedMap.isMarked(getValueIndex(sortedRowIndex)))
|| (isTimeDeleted(sortedRowIndex))) {
continue;
}
long time = getTime(sortedRowIndex);
// skip time duplicated or totally deleted rows
if (Objects.nonNull(timeDuplicateInfo)) {
if (!outer.isNullValue(getValueIndex(sortedRowIndex), validColumnIndex)) {
lastValidPointIndexForTimeDupCheck.left = getTime(sortedRowIndex);
lastValidPointIndexForTimeDupCheck.right = getValueIndex(sortedRowIndex);
}
if (timeDuplicateInfo.isMarked(sortedRowIndex)) {
continue;
}
}
// The part of code solves the following problem:
// Time: 1,2,2,3
// Value: 1,2,null,null
// When rowIndex:1, pair(min,null), timeDuplicateInfo:false, write(T:1,V:1)
// When rowIndex:2, pair(2,2), timeDuplicateInfo:true, skip writing value
// When rowIndex:3, pair(2,2), timeDuplicateInfo:false, T:2==pair.left:2, write(T:2,V:2)
// When rowIndex:4, pair(2,2), timeDuplicateInfo:false, T:3!=pair.left:2,
// write(T:3,V:null)
int originRowIndex;
if (Objects.nonNull(lastValidPointIndexForTimeDupCheck)
&& (getTime(sortedRowIndex) == lastValidPointIndexForTimeDupCheck.left)) {
originRowIndex = lastValidPointIndexForTimeDupCheck.right;
} else {
originRowIndex = getValueIndex(sortedRowIndex);
}
boolean isNull = outer.isNullValue(originRowIndex, validColumnIndex);
switch (dataTypeList.get(columnIndex)) {
case BOOLEAN:
valueChunkWriter.write(
time,
!isNull && getBooleanByValueIndex(originRowIndex, validColumnIndex),
isNull);
break;
case INT32:
case DATE:
valueChunkWriter.write(
time, isNull ? 0 : getIntByValueIndex(originRowIndex, validColumnIndex), isNull);
break;
case INT64:
case TIMESTAMP:
valueChunkWriter.write(
time, isNull ? 0 : getLongByValueIndex(originRowIndex, validColumnIndex), isNull);
break;
case FLOAT:
valueChunkWriter.write(
time,
isNull ? 0 : getFloatByValueIndex(originRowIndex, validColumnIndex),
isNull);
break;
case DOUBLE:
valueChunkWriter.write(
time,
isNull ? 0 : getDoubleByValueIndex(originRowIndex, validColumnIndex),
isNull);
break;
case TEXT:
case BLOB:
case STRING:
valueChunkWriter.write(
time,
isNull ? null : getBinaryByValueIndex(originRowIndex, validColumnIndex),
isNull);
break;
default:
break;
}
}
}
probeNext = false;
}