Skip to content

Commit 5968100

Browse files
authored
[To dev/1.3]Memtable enhance fix (#15040)
* perf: improve seq inserting * rename MergeSortTvListIterator to MergeSortTVListIterator * fix: concurrent indices modification during query sort and flush sort * revert: iterate rows in aligned memChunk * fix: testMemAlignedChunkLoader test * fix: no need to synchronize list since sort is already an synchronized method * fix: optimize mininum time update in TVList * perf: special case for merge sort iterator when no handover occurs
1 parent 3bb1e17 commit 5968100

25 files changed

+435
-798
lines changed

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AbstractMemTable.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -385,15 +385,6 @@ public boolean checkIfChunkDoesNotExist(IDeviceID deviceId, String measurement)
385385
return !memChunkGroup.contains(measurement);
386386
}
387387

388-
@Override
389-
public long getMeasurementSize(IDeviceID deviceId, String measurement) {
390-
IWritableMemChunkGroup memChunkGroup = memTableMap.get(deviceId);
391-
if (null == memChunkGroup) {
392-
return 0;
393-
}
394-
return memChunkGroup.getMeasurementSize(measurement);
395-
}
396-
397388
@Override
398389
public IWritableMemChunk getWritableMemChunk(IDeviceID deviceId, String measurement) {
399390
IWritableMemChunkGroup memChunkGroup = memTableMap.get(deviceId);

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedReadOnlyMemChunk.java

Lines changed: 100 additions & 214 deletions
Large diffs are not rendered by default.

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedWritableMemChunk.java

Lines changed: 36 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@
2828
import org.apache.iotdb.db.storageengine.dataregion.wal.utils.WALWriteUtils;
2929
import org.apache.iotdb.db.utils.datastructure.AlignedTVList;
3030
import org.apache.iotdb.db.utils.datastructure.MergeSortAlignedTVListIterator;
31-
import org.apache.iotdb.db.utils.datastructure.PageColumnAccessInfo;
3231
import org.apache.iotdb.db.utils.datastructure.TVList;
3332

3433
import org.apache.tsfile.common.conf.TSFileDescriptor;
3534
import org.apache.tsfile.enums.TSDataType;
35+
import org.apache.tsfile.read.TimeValuePair;
3636
import org.apache.tsfile.read.common.TimeRange;
3737
import org.apache.tsfile.utils.Binary;
3838
import org.apache.tsfile.utils.BitMap;
@@ -702,85 +702,6 @@ private void handleEncoding(
702702
}
703703
}
704704

705-
private void writePageValuesIntoWriter(
706-
IChunkWriter chunkWriter,
707-
long[] times,
708-
PageColumnAccessInfo[] pageColumnAccessInfo,
709-
MergeSortAlignedTVListIterator timeValuePairIterator) {
710-
AlignedChunkWriterImpl alignedChunkWriter = (AlignedChunkWriterImpl) chunkWriter;
711-
712-
// update value statistics
713-
for (int columnIndex = 0; columnIndex < dataTypes.size(); columnIndex++) {
714-
ValueChunkWriter valueChunkWriter =
715-
alignedChunkWriter.getValueChunkWriterByIndex(columnIndex);
716-
PageColumnAccessInfo pageAccessInfo = pageColumnAccessInfo[columnIndex];
717-
switch (dataTypes.get(columnIndex)) {
718-
case BOOLEAN:
719-
for (int index = 0; index < pageAccessInfo.count(); index++) {
720-
int[] accessInfo = pageAccessInfo.get(index);
721-
TsPrimitiveType value =
722-
timeValuePairIterator.getPrimitiveObject(accessInfo, columnIndex);
723-
valueChunkWriter.write(
724-
times[index], value != null && value.getBoolean(), value == null);
725-
}
726-
break;
727-
case INT32:
728-
case DATE:
729-
for (int index = 0; index < pageAccessInfo.count(); index++) {
730-
int[] accessInfo = pageAccessInfo.get(index);
731-
TsPrimitiveType value =
732-
timeValuePairIterator.getPrimitiveObject(accessInfo, columnIndex);
733-
valueChunkWriter.write(times[index], value == null ? 0 : value.getInt(), value == null);
734-
}
735-
break;
736-
case INT64:
737-
case TIMESTAMP:
738-
for (int index = 0; index < pageAccessInfo.count(); index++) {
739-
int[] accessInfo = pageAccessInfo.get(index);
740-
TsPrimitiveType value =
741-
timeValuePairIterator.getPrimitiveObject(accessInfo, columnIndex);
742-
valueChunkWriter.write(
743-
times[index], value == null ? 0L : value.getLong(), value == null);
744-
}
745-
break;
746-
case FLOAT:
747-
for (int index = 0; index < pageAccessInfo.count(); index++) {
748-
int[] accessInfo = pageAccessInfo.get(index);
749-
TsPrimitiveType value =
750-
timeValuePairIterator.getPrimitiveObject(accessInfo, columnIndex);
751-
valueChunkWriter.write(
752-
times[index], value == null ? 0f : value.getFloat(), value == null);
753-
}
754-
break;
755-
case DOUBLE:
756-
for (int index = 0; index < pageAccessInfo.count(); index++) {
757-
int[] accessInfo = pageAccessInfo.get(index);
758-
TsPrimitiveType value =
759-
timeValuePairIterator.getPrimitiveObject(accessInfo, columnIndex);
760-
valueChunkWriter.write(
761-
times[index], value == null ? 0d : value.getDouble(), value == null);
762-
}
763-
break;
764-
case TEXT:
765-
case BLOB:
766-
case STRING:
767-
for (int index = 0; index < pageAccessInfo.count(); index++) {
768-
int[] accessInfo = pageAccessInfo.get(index);
769-
TsPrimitiveType value =
770-
timeValuePairIterator.getPrimitiveObject(accessInfo, columnIndex);
771-
valueChunkWriter.write(
772-
times[index],
773-
value == null ? Binary.EMPTY_VALUE : value.getBinary(),
774-
value == null);
775-
}
776-
break;
777-
default:
778-
throw new UnSupportedDataTypeException(
779-
String.format("Data type %s is not supported.", dataTypes.get(columnIndex)));
780-
}
781-
}
782-
}
783-
784705
@Override
785706
public synchronized void encode(BlockingQueue<Object> ioTaskQueue) {
786707
if (TVLIST_SORT_THRESHOLD == 0) {
@@ -799,30 +720,49 @@ public synchronized void encode(BlockingQueue<Object> ioTaskQueue) {
799720
int pointNumInChunk = 0;
800721
long[] times = new long[MAX_NUMBER_OF_POINTS_IN_PAGE];
801722

802-
PageColumnAccessInfo[] pageColumnAccessInfo = new PageColumnAccessInfo[dataTypes.size()];
803-
for (int i = 0; i < pageColumnAccessInfo.length; i++) {
804-
pageColumnAccessInfo[i] = new PageColumnAccessInfo(MAX_NUMBER_OF_POINTS_IN_PAGE);
805-
}
806-
807723
while (timeValuePairIterator.hasNextTimeValuePair()) {
808-
// prepare column access info for current page
809-
int[][] accessInfo = timeValuePairIterator.getColumnAccessInfo();
810-
times[pointNumInPage] = timeValuePairIterator.getTime();
811-
for (int i = 0; i < dataTypes.size(); i++) {
812-
pageColumnAccessInfo[i].add(accessInfo[i]);
724+
TimeValuePair tvPair = timeValuePairIterator.nextTimeValuePair();
725+
times[pointNumInPage] = tvPair.getTimestamp();
726+
TsPrimitiveType[] values = tvPair.getValue().getVector();
727+
728+
for (int columnIndex = 0; columnIndex < values.length; columnIndex++) {
729+
ValueChunkWriter valueChunkWriter =
730+
alignedChunkWriter.getValueChunkWriterByIndex(columnIndex);
731+
boolean isNull = values[columnIndex] == null;
732+
switch (schemaList.get(columnIndex).getType()) {
733+
case BOOLEAN:
734+
valueChunkWriter.write(tvPair.getTimestamp(), values[columnIndex].getBoolean(), isNull);
735+
break;
736+
case INT32:
737+
case DATE:
738+
valueChunkWriter.write(tvPair.getTimestamp(), values[columnIndex].getInt(), isNull);
739+
break;
740+
case INT64:
741+
case TIMESTAMP:
742+
valueChunkWriter.write(tvPair.getTimestamp(), values[columnIndex].getLong(), isNull);
743+
break;
744+
case FLOAT:
745+
valueChunkWriter.write(tvPair.getTimestamp(), values[columnIndex].getFloat(), isNull);
746+
break;
747+
case DOUBLE:
748+
valueChunkWriter.write(tvPair.getTimestamp(), values[columnIndex].getDouble(), isNull);
749+
break;
750+
case TEXT:
751+
case BLOB:
752+
case STRING:
753+
valueChunkWriter.write(tvPair.getTimestamp(), values[columnIndex].getBinary(), isNull);
754+
break;
755+
default:
756+
break;
757+
}
813758
}
814-
timeValuePairIterator.step();
759+
815760
pointNumInPage++;
816761
pointNumInChunk++;
817762

818763
if (pointNumInPage == MAX_NUMBER_OF_POINTS_IN_PAGE
819764
|| pointNumInChunk >= maxNumberOfPointsInChunk) {
820-
writePageValuesIntoWriter(
821-
alignedChunkWriter, times, pageColumnAccessInfo, timeValuePairIterator);
822765
alignedChunkWriter.write(times, pointNumInPage, 0);
823-
for (PageColumnAccessInfo columnAccessInfo : pageColumnAccessInfo) {
824-
columnAccessInfo.reset();
825-
}
826766
pointNumInPage = 0;
827767
}
828768

@@ -842,8 +782,6 @@ public synchronized void encode(BlockingQueue<Object> ioTaskQueue) {
842782
// last batch of points
843783
if (pointNumInChunk > 0) {
844784
if (pointNumInPage > 0) {
845-
writePageValuesIntoWriter(
846-
alignedChunkWriter, times, pageColumnAccessInfo, timeValuePairIterator);
847785
alignedChunkWriter.write(times, pointNumInPage, 0);
848786
alignedChunkWriter.sealCurrentPage();
849787
alignedChunkWriter.clearPageWriter();

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedWritableMemChunkGroup.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,6 @@ public int delete(
139139
return deletedPointsNumber;
140140
}
141141

142-
@Override
143-
public long getMeasurementSize(String measurement) {
144-
return memChunk.rowCount();
145-
}
146-
147142
@Override
148143
public IWritableMemChunk getWritableMemChunk(String measurement) {
149144
return memChunk;

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/IMemTable.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,6 @@ void queryForDeviceRegionScan(
173173
boolean checkIfChunkDoesNotExist(IDeviceID deviceId, String measurement);
174174

175175
/** only used when mem control enabled */
176-
long getMeasurementSize(IDeviceID deviceId, String measurement);
177-
178176
IWritableMemChunk getWritableMemChunk(IDeviceID deviceId, String measurement);
179177

180178
/** only used when mem control enabled */

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/IWritableMemChunkGroup.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ void writeTablet(
5151
int delete(
5252
PartialPath originalPath, PartialPath devicePath, long startTimestamp, long endTimestamp);
5353

54-
long getMeasurementSize(String measurement);
55-
5654
IWritableMemChunk getWritableMemChunk(String measurement);
5755

5856
long getMaxTime();

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/ReadOnlyMemChunk.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import org.apache.iotdb.db.queryengine.execution.fragment.QueryContext;
2525
import org.apache.iotdb.db.storageengine.dataregion.read.reader.chunk.MemChunkLoader;
2626
import org.apache.iotdb.db.utils.MathUtils;
27-
import org.apache.iotdb.db.utils.datastructure.MergeSortTvListIterator;
27+
import org.apache.iotdb.db.utils.datastructure.MergeSortTVListIterator;
2828
import org.apache.iotdb.db.utils.datastructure.TVList;
2929

3030
import org.apache.tsfile.common.conf.TSFileDescriptor;
@@ -85,7 +85,7 @@ public class ReadOnlyMemChunk {
8585
// TVList and its rowCount during query
8686
private Map<TVList, Integer> tvListQueryMap;
8787

88-
private MergeSortTvListIterator timeValuePairIterator;
88+
private MergeSortTVListIterator timeValuePairIterator;
8989

9090
protected final int MAX_NUMBER_OF_POINTS_IN_PAGE =
9191
TSFileDescriptor.getInstance().getConfig().getMaxNumberOfPointsInPage();
@@ -145,13 +145,13 @@ public void sortTvLists() {
145145
public void initChunkMetaFromTvLists() {
146146
// create chunk statistics
147147
Statistics<? extends Serializable> chunkStatistics = Statistics.getStatsByType(dataType);
148-
int cnt = 0;
148+
int pointsInChunk = 0;
149149
int[] deleteCursor = {0};
150150
List<TVList> tvLists = new ArrayList<>(tvListQueryMap.keySet());
151-
timeValuePairIterator = new MergeSortTvListIterator(tvLists, floatPrecision, encoding);
151+
timeValuePairIterator = new MergeSortTVListIterator(tvLists, floatPrecision, encoding);
152152
int[] tvListOffsets = timeValuePairIterator.getTVListOffsets();
153153
while (timeValuePairIterator.hasNextTimeValuePair()) {
154-
if (cnt % MAX_NUMBER_OF_POINTS_IN_PAGE == 0) {
154+
if (pointsInChunk % MAX_NUMBER_OF_POINTS_IN_PAGE == 0) {
155155
Statistics<? extends Serializable> stats = Statistics.getStatsByType(dataType);
156156
pageStatisticsList.add(stats);
157157
pageOffsetsList.add(Arrays.copyOf(tvListOffsets, tvListOffsets.length));
@@ -194,7 +194,7 @@ public void initChunkMetaFromTvLists() {
194194
String.format("Data type %s is not supported.", dataType));
195195
}
196196
}
197-
cnt++;
197+
pointsInChunk++;
198198
}
199199
pageOffsetsList.add(Arrays.copyOf(tvListOffsets, tvListOffsets.length));
200200

@@ -245,7 +245,7 @@ private void writeValidValuesIntoTsBlock(TsBlockBuilder builder) throws IOExcept
245245
int[] deleteCursor = {0};
246246
List<TVList> tvLists = new ArrayList<>(tvListQueryMap.keySet());
247247
IPointReader timeValuePairIterator =
248-
new MergeSortTvListIterator(tvLists, floatPrecision, encoding);
248+
new MergeSortTVListIterator(tvLists, floatPrecision, encoding);
249249

250250
while (timeValuePairIterator.hasNextTimeValuePair()) {
251251
TimeValuePair tvPair = timeValuePairIterator.nextTimeValuePair();
@@ -333,7 +333,7 @@ public TsBlock getTsBlock() {
333333
return null;
334334
}
335335

336-
public MergeSortTvListIterator getMergeSortTVListIterator() {
336+
public MergeSortTVListIterator getMergeSortTVListIterator() {
337337
return timeValuePairIterator;
338338
}
339339

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/TsFileProcessor.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -581,8 +581,8 @@ private long[] checkMemCostAndAddToTspInfoForRow(
581581
memTableIncrement += TVList.tvListArrayMemCost(dataTypes[i]);
582582
} else {
583583
// here currentChunkPointNum >= 1
584-
long currentChunkPointNum = workMemTable.getMeasurementSize(deviceId, measurements[i]);
585584
IWritableMemChunk memChunk = workMemTable.getWritableMemChunk(deviceId, measurements[i]);
585+
long currentChunkPointNum = memChunk != null ? memChunk.rowCount() : 0;
586586
if (currentChunkPointNum % PrimitiveArrayManager.ARRAY_SIZE == 0) {
587587
memTableIncrement +=
588588
memChunk != null ? memChunk.getWorkingTVList().tvListArrayMemCost() : 0;
@@ -627,12 +627,12 @@ private long[] checkMemCostAndAddToTspInfoForRows(List<InsertRowNode> insertRowN
627627
.putIfAbsent(measurements[i], 1);
628628
} else {
629629
// here currentChunkPointNum >= 1
630-
long currentChunkPointNum = workMemTable.getMeasurementSize(deviceId, measurements[i]);
631630
IWritableMemChunk memChunk = workMemTable.getWritableMemChunk(deviceId, measurements[i]);
632631
int addingPointNum =
633632
increasingMemTableInfo
634633
.computeIfAbsent(deviceId, k -> new HashMap<>())
635634
.computeIfAbsent(measurements[i], k -> 0);
635+
long currentChunkPointNum = memChunk != null ? memChunk.rowCount() : 0;
636636
if ((currentChunkPointNum + addingPointNum) % PrimitiveArrayManager.ARRAY_SIZE == 0) {
637637
memTableIncrement +=
638638
memChunk != null
@@ -873,8 +873,8 @@ private void updateMemCost(
873873
((end - start) / PrimitiveArrayManager.ARRAY_SIZE + 1)
874874
* TVList.tvListArrayMemCost(dataType);
875875
} else {
876-
long currentChunkPointNum = workMemTable.getMeasurementSize(deviceId, measurement);
877876
IWritableMemChunk memChunk = workMemTable.getWritableMemChunk(deviceId, measurement);
877+
long currentChunkPointNum = memChunk != null ? memChunk.rowCount() : 0;
878878
if (currentChunkPointNum % PrimitiveArrayManager.ARRAY_SIZE == 0) {
879879
memIncrements[0] +=
880880
((end - start) / PrimitiveArrayManager.ARRAY_SIZE + 1)
@@ -886,11 +886,7 @@ private void updateMemCost(
886886
(end - start - 1 + (currentChunkPointNum % PrimitiveArrayManager.ARRAY_SIZE))
887887
/ PrimitiveArrayManager.ARRAY_SIZE;
888888
if (acquireArray != 0) {
889-
memIncrements[0] +=
890-
acquireArray
891-
* (memChunk != null
892-
? memChunk.getWorkingTVList().tvListArrayMemCost()
893-
: TVList.tvListArrayMemCost(dataType));
889+
memIncrements[0] += acquireArray * memChunk.getWorkingTVList().tvListArrayMemCost();
894890
}
895891
}
896892
}

0 commit comments

Comments
 (0)