Skip to content

Commit 2ec3441

Browse files
authored
[To dev/1.3] perf: Optimize the mark bitmap operation of AlignedTVList InsertTablet (#16199) (#16590)
(cherry picked from commit 51fe585)
1 parent 7770bac commit 2ec3441

2 files changed

Lines changed: 72 additions & 43 deletions

File tree

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/resource/memory/InsertNodeMemoryEstimator.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -553,10 +553,12 @@ private static long getBinarySize(final Binary[] binaries) {
553553
return 0L;
554554
}
555555

556-
return RamUsageEstimator.shallowSizeOf(binaries)
557-
+ Arrays.stream(binaries)
558-
.mapToLong(InsertNodeMemoryEstimator::sizeOfBinary)
559-
.reduce(0L, Long::sum);
556+
long size = 0L;
557+
for (Binary binary : binaries) {
558+
size += InsertNodeMemoryEstimator.sizeOfBinary(binary);
559+
}
560+
561+
return size + RamUsageEstimator.shallowSizeOf(binaries);
560562
}
561563

562564
public static long sizeOfValues(

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java

Lines changed: 66 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -712,14 +712,9 @@ public synchronized void putAlignedValues(
712712
if (indices != null) {
713713
indices.get(arrayIdx)[elementIdx + i] = rowCount;
714714
}
715-
for (int j = 0; j < values.size(); j++) {
716-
if (value[j] == null
717-
|| bitMaps != null && bitMaps[j] != null && bitMaps[j].isMarked(idx + i)) {
718-
markNullValue(j, arrayIdx, elementIdx + i);
719-
}
720-
}
721715
rowCount++;
722716
}
717+
markNullBitmapRange(value, bitMaps, idx, elementIdx, inputRemaining, arrayIdx);
723718
break;
724719
} else {
725720
// the remaining inputs cannot fit the last array, fill the last array and create a new
@@ -730,20 +725,31 @@ public synchronized void putAlignedValues(
730725
if (indices != null) {
731726
indices.get(arrayIdx)[elementIdx + i] = rowCount;
732727
}
733-
for (int j = 0; j < values.size(); j++) {
734-
if (value[j] == null
735-
|| bitMaps != null && bitMaps[j] != null && bitMaps[j].isMarked(idx + i)) {
736-
markNullValue(j, arrayIdx, elementIdx + i);
737-
}
738-
}
739728
rowCount++;
740729
}
730+
markNullBitmapRange(value, bitMaps, idx, elementIdx, internalRemaining, arrayIdx);
741731
idx += internalRemaining;
742732
checkExpansion();
743733
}
744734
}
745735
}
746736

737+
private void markNullBitmapRange(
738+
Object[] values, BitMap[] bitMaps, int idx, int elementIdx, int len, int arrayIndex) {
739+
for (int j = 0; j < values.length; j++) {
740+
/* Fast-path: column is entirely null */
741+
if (values[j] == null) {
742+
getBitMap(j, arrayIndex).markRange(elementIdx, len);
743+
continue;
744+
}
745+
746+
/* 2.mask the column bitmap */
747+
if (bitMaps != null && bitMaps[j] != null) {
748+
getBitMap(j, arrayIndex).merge(bitMaps[j], idx, elementIdx, len);
749+
}
750+
}
751+
}
752+
747753
private void arrayCopy(Object[] value, int idx, int arrayIndex, int elementIndex, int remaining) {
748754
for (int i = 0; i < values.size(); i++) {
749755
if (value[i] == null) {
@@ -791,7 +797,7 @@ private void arrayCopy(Object[] value, int idx, int arrayIndex, int elementIndex
791797
}
792798
}
793799

794-
private void markNullValue(int columnIndex, int arrayIndex, int elementIndex) {
800+
private BitMap getBitMap(int columnIndex, int arrayIndex) {
795801
// init BitMaps if doesn't have
796802
if (bitMaps == null) {
797803
List<List<BitMap>> localBitMaps = new ArrayList<>(dataTypes.size());
@@ -805,18 +811,22 @@ private void markNullValue(int columnIndex, int arrayIndex, int elementIndex) {
805811
if (bitMaps.get(columnIndex) == null) {
806812
List<BitMap> columnBitMaps = new ArrayList<>();
807813
for (int i = 0; i < values.get(columnIndex).size(); i++) {
808-
columnBitMaps.add(new BitMap(ARRAY_SIZE));
814+
columnBitMaps.add(new BitMap(ARRAY_SIZE, new byte[ARRAY_SIZE]));
809815
}
810816
bitMaps.set(columnIndex, columnBitMaps);
811817
}
812818

813819
// if the bitmap in arrayIndex is null, init the bitmap
814820
if (bitMaps.get(columnIndex).get(arrayIndex) == null) {
815-
bitMaps.get(columnIndex).set(arrayIndex, new BitMap(ARRAY_SIZE));
821+
bitMaps.get(columnIndex).set(arrayIndex, new BitMap(ARRAY_SIZE, new byte[ARRAY_SIZE]));
816822
}
817823

824+
return bitMaps.get(columnIndex).get(arrayIndex);
825+
}
826+
827+
private void markNullValue(int columnIndex, int arrayIndex, int elementIndex) {
818828
// mark the null value in the current bitmap
819-
bitMaps.get(columnIndex).get(arrayIndex).mark(elementIndex);
829+
getBitMap(columnIndex, arrayIndex).mark(elementIndex);
820830
}
821831

822832
@Override
@@ -1257,33 +1267,50 @@ public BitMap getAllValueColDeletedMap() {
12571267
}
12581268

12591269
byte[] rowBitsArr = new byte[rowCount / Byte.SIZE + 1];
1260-
for (int row = 0; row < rowCount; row += Byte.SIZE) {
1261-
boolean isFirstColumn = true;
1262-
byte rowBits = 0x00;
1263-
for (int columnIndex = 0; columnIndex < values.size(); columnIndex++) {
1264-
List<BitMap> columnBitMaps = bitMaps.get(columnIndex);
1265-
byte columnBits;
1266-
if (values.get(columnIndex) == null) {
1267-
columnBits = (byte) 0xFF;
1268-
} else if (columnBitMaps == null || columnBitMaps.get(row / ARRAY_SIZE) == null) {
1269-
// row exists when any column value exists
1270-
rowBits = 0x00;
1271-
break;
1272-
} else {
1273-
columnBits =
1274-
columnBitMaps.get(row / ARRAY_SIZE).getByteArray()[(row % ARRAY_SIZE) / Byte.SIZE];
1270+
int bitsMapSize =
1271+
rowCount % ARRAY_SIZE == 0 ? rowCount / ARRAY_SIZE : rowCount / ARRAY_SIZE + 1;
1272+
boolean[] allNotNullArray = new boolean[bitsMapSize];
1273+
Arrays.fill(rowBitsArr, (byte) 0xFF);
1274+
for (int columnIndex = 0; columnIndex < values.size(); columnIndex++) {
1275+
List<BitMap> columnBitMaps = bitMaps.get(columnIndex);
1276+
if (columnBitMaps == null) {
1277+
Arrays.fill(rowBitsArr, (byte) 0x00);
1278+
break;
1279+
} else if (values.get(columnIndex) != null) {
1280+
int row = 0;
1281+
boolean isEnd = true;
1282+
for (int i = 0; i < bitsMapSize; i++) {
1283+
if (allNotNullArray[i]) {
1284+
row += ARRAY_SIZE;
1285+
continue;
1286+
}
1287+
1288+
BitMap bitMap = columnBitMaps.get(i);
1289+
int index = row / Byte.SIZE;
1290+
int size = ((Math.min((rowCount - row), ARRAY_SIZE)) + 7) >>> 3;
1291+
row += ARRAY_SIZE;
1292+
1293+
if (bitMap == null) {
1294+
Arrays.fill(rowBitsArr, index, index + size, (byte) 0x00);
1295+
allNotNullArray[i] = true;
1296+
continue;
1297+
}
1298+
1299+
byte bits = (byte) 0X00;
1300+
for (int j = 0; j < size; j++) {
1301+
rowBitsArr[index] &= bitMap.getByteArray()[j];
1302+
bits |= rowBitsArr[index++];
1303+
isEnd = false;
1304+
}
1305+
1306+
allNotNullArray[i] = bits == (byte) 0;
12751307
}
1276-
// set row to null when all column values are null
1277-
if (isFirstColumn) {
1278-
rowBits = columnBits;
1279-
isFirstColumn = false;
1280-
} else {
1281-
rowBits &= columnBits;
1308+
1309+
if (isEnd) {
1310+
break;
12821311
}
12831312
}
1284-
rowBitsArr[row / Byte.SIZE] = rowBits;
12851313
}
1286-
12871314
return new BitMap(rowCount, rowBitsArr);
12881315
}
12891316

0 commit comments

Comments
 (0)