This is an automated email from the ASF dual-hosted git repository.
jiangtian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 100cf590344 Add a switch to control if allow null value be included in
the "quantity total" metric statistic (#16057)
100cf590344 is described below
commit 100cf590344146d7ec902e439f5e02843ed486e7
Author: libo <[email protected]>
AuthorDate: Wed Aug 13 17:35:04 2025 +0800
Add a switch to control if allow null value be included in the "quantity
total" metric statistic (#16057)
* Add a switch, control if allow null value be included in the "quantity
total" metric statistic.
* Consistent with the rules of insertRow function, are controlled by the
switch named "isEnableNullValueIncludedInQuatityStats".
* Consistent with the rules of insertRow function, are controlled by the
switch named "isEnableNullValueIncludedInQuatityStats".
* delete some unuseful variables.
* Correct the method that compute point numbers exist null value in the
Tablet structure.
* Support hot reload configuration with two kinds of command:
set configuration "enable_null_value_included_in_quatity_stats"="true" on 1;
load configuration;
Fix wrong about algorithm that compute table null value number.
Add a new configuration in the configuration template file.
* format test code.
* Rename name of config item.
* Format code.
---
.../iotdb/AlignedTimeseriesSessionExample.java | 78 ++++++++++++++++++++++
.../main/java/org/apache/iotdb/SessionExample.java | 55 +++++++++++++++
.../java/org/apache/iotdb/db/conf/IoTDBConfig.java | 11 +++
.../org/apache/iotdb/db/conf/IoTDBDescriptor.java | 13 ++++
.../dataregion/memtable/AbstractMemTable.java | 56 ++++++++++++++--
.../conf/iotdb-system.properties.template | 5 ++
6 files changed, 211 insertions(+), 7 deletions(-)
diff --git
a/example/session/src/main/java/org/apache/iotdb/AlignedTimeseriesSessionExample.java
b/example/session/src/main/java/org/apache/iotdb/AlignedTimeseriesSessionExample.java
index 4dbcc16fd17..288bd65ddcb 100644
---
a/example/session/src/main/java/org/apache/iotdb/AlignedTimeseriesSessionExample.java
+++
b/example/session/src/main/java/org/apache/iotdb/AlignedTimeseriesSessionExample.java
@@ -623,4 +623,82 @@ public class AlignedTimeseriesSessionExample {
tablet3.reset();
}
}
+
+ private static void insertTabletsWithAlignedTimeseriesWithNullValue()
+ throws IoTDBConnectionException, StatementExecutionException {
+
+ List<IMeasurementSchema> schemaList1 = new ArrayList<>();
+ schemaList1.add(new MeasurementSchema("s1", TSDataType.INT64));
+ schemaList1.add(new MeasurementSchema("s2", TSDataType.INT64));
+
+ List<IMeasurementSchema> schemaList2 = new ArrayList<>();
+ schemaList2.add(new MeasurementSchema("s1", TSDataType.INT64));
+ schemaList2.add(new MeasurementSchema("s2", TSDataType.INT64));
+
+ List<IMeasurementSchema> schemaList3 = new ArrayList<>();
+ schemaList3.add(new MeasurementSchema("s1", TSDataType.INT64));
+ schemaList3.add(new MeasurementSchema("s2", TSDataType.INT64));
+
+ Tablet tablet1 = new Tablet(ROOT_SG2_D1_VECTOR6, schemaList1, 100);
+ Tablet tablet2 = new Tablet(ROOT_SG2_D1_VECTOR7, schemaList2, 100);
+ Tablet tablet3 = new Tablet(ROOT_SG2_D1_VECTOR8, schemaList3, 100);
+
+ Map<String, Tablet> tabletMap = new HashMap<>();
+ tabletMap.put(ROOT_SG2_D1_VECTOR6, tablet1);
+ tabletMap.put(ROOT_SG2_D1_VECTOR7, tablet2);
+ tabletMap.put(ROOT_SG2_D1_VECTOR8, tablet3);
+
+ // Method 1 to add tablet data
+ long timestamp = System.currentTimeMillis();
+ for (long row = 0; row < 90; row++) {
+ int row1 = tablet1.getRowSize();
+ int row2 = tablet2.getRowSize();
+ int row3 = tablet3.getRowSize();
+ tablet1.addTimestamp(row1, timestamp);
+ tablet2.addTimestamp(row2, timestamp);
+ tablet3.addTimestamp(row3, timestamp);
+ for (int i = 0; i < 2; i++) {
+ long value = new SecureRandom().nextLong();
+ tablet1.addValue(schemaList1.get(i).getMeasurementName(), row1, value);
+ tablet2.addValue(schemaList2.get(i).getMeasurementName(), row2, value);
+ tablet3.addValue(schemaList3.get(i).getMeasurementName(), row3, value);
+ }
+ if (tablet1.getRowSize() == tablet1.getMaxRowNumber()) {
+ session.insertAlignedTablets(tabletMap, true);
+ tablet1.reset();
+ tablet2.reset();
+ tablet3.reset();
+ }
+ timestamp++;
+ }
+
+ for (long row = 90; row < 100; row++) {
+ int row1 = tablet1.getRowSize();
+ int row2 = tablet2.getRowSize();
+ int row3 = tablet3.getRowSize();
+ tablet1.addTimestamp(row1, timestamp);
+ tablet2.addTimestamp(row2, timestamp);
+ tablet3.addTimestamp(row3, timestamp);
+ for (int i = 0; i < 2; i++) {
+ Object value = null;
+ tablet1.addValue(schemaList1.get(i).getMeasurementName(), row1, value);
+ tablet2.addValue(schemaList2.get(i).getMeasurementName(), row2, value);
+ tablet3.addValue(schemaList3.get(i).getMeasurementName(), row3, value);
+ }
+ if (tablet1.getRowSize() == tablet1.getMaxRowNumber()) {
+ session.insertAlignedTablets(tabletMap, true);
+ tablet1.reset();
+ tablet2.reset();
+ tablet3.reset();
+ }
+ timestamp++;
+ }
+
+ if (tablet1.getRowSize() != 0) {
+ session.insertAlignedTablets(tabletMap, true);
+ tablet1.reset();
+ tablet2.reset();
+ tablet3.reset();
+ }
+ }
}
diff --git a/example/session/src/main/java/org/apache/iotdb/SessionExample.java
b/example/session/src/main/java/org/apache/iotdb/SessionExample.java
index d5c6f0a5a6a..b7e9bddfe41 100644
--- a/example/session/src/main/java/org/apache/iotdb/SessionExample.java
+++ b/example/session/src/main/java/org/apache/iotdb/SessionExample.java
@@ -472,6 +472,61 @@ public class SessionExample {
}
}
+ private static void insertTabletWithNullValue()
+ throws IoTDBConnectionException, StatementExecutionException {
+ /*
+ * A Tablet example:
+ * device1
+ * time s1, s2, s3
+ * 1, 1, 1, 1
+ * 2, 2, 2, 2
+ * 3, 3, 3, 3
+ */
+ // The schema of measurements of one device
+ // only measurementId and data type in MeasurementSchema take effects in
Tablet
+ List<IMeasurementSchema> schemaList = new ArrayList<>();
+ schemaList.add(new MeasurementSchema("s1", TSDataType.INT64));
+ schemaList.add(new MeasurementSchema("s2", TSDataType.INT64));
+ schemaList.add(new MeasurementSchema("s3", TSDataType.INT64));
+
+ Tablet tablet = new Tablet(ROOT_SG1_D1, schemaList, 100);
+
+ long timestamp = System.currentTimeMillis();
+
+ for (long row = 0; row < 90; row++) {
+ int rowIndex = tablet.getRowSize();
+ tablet.addTimestamp(rowIndex, timestamp);
+ for (int s = 0; s < 3; s++) {
+ long value = random.nextLong();
+ tablet.addValue(schemaList.get(s).getMeasurementName(), rowIndex,
value);
+ }
+ if (tablet.getRowSize() == tablet.getMaxRowNumber()) {
+ session.insertTablet(tablet, true);
+ tablet.reset();
+ }
+ timestamp++;
+ }
+
+ for (long row = 90; row < 100; row++) {
+ int rowIndex = tablet.getRowSize();
+ tablet.addTimestamp(rowIndex, timestamp);
+ for (int s = 0; s < 3; s++) {
+ Object value = null;
+ tablet.addValue(schemaList.get(s).getMeasurementName(), rowIndex,
value);
+ }
+ if (tablet.getRowSize() == tablet.getMaxRowNumber()) {
+ session.insertTablet(tablet, true);
+ tablet.reset();
+ }
+ timestamp++;
+ }
+
+ if (tablet.getRowSize() != 0) {
+ session.insertTablet(tablet);
+ tablet.reset();
+ }
+ }
+
private static void insertTabletWithNullValues()
throws IoTDBConnectionException, StatementExecutionException {
/*
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
index 75dac521f2f..2f6accf13f7 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
@@ -1164,6 +1164,8 @@ public class IoTDBConfig {
private long cacheLastValuesMemoryBudgetInByte = 4 * 1024 * 1024;
+ private boolean includeNullValueInWriteThroughputMetric = false;
+
IoTDBConfig() {}
public int getMaxLogEntriesNumPerBatch() {
@@ -4138,4 +4140,13 @@ public class IoTDBConfig {
public void setCacheLastValuesMemoryBudgetInByte(long
cacheLastValuesMemoryBudgetInByte) {
this.cacheLastValuesMemoryBudgetInByte = cacheLastValuesMemoryBudgetInByte;
}
+
+ public boolean isIncludeNullValueInWriteThroughputMetric() {
+ return includeNullValueInWriteThroughputMetric;
+ }
+
+ public void setIncludeNullValueInWriteThroughputMetric(
+ boolean includeNullValueInWriteThroughputMetric) {
+ this.includeNullValueInWriteThroughputMetric =
includeNullValueInWriteThroughputMetric;
+ }
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
index 7a6bfc8aa58..753607db4a6 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
@@ -1088,6 +1088,12 @@ public class IoTDBDescriptor {
loadQuerySampleThroughput(properties);
// update trusted_uri_pattern
loadTrustedUriPattern(properties);
+
+ conf.setIncludeNullValueInWriteThroughputMetric(
+ Boolean.parseBoolean(
+ properties.getProperty(
+ "include_null_value_in_write_throughput_metric",
+
String.valueOf(conf.isIncludeNullValueInWriteThroughputMetric()))));
}
private void loadSortBuffer(TrimProperties properties) {
@@ -2084,6 +2090,13 @@ public class IoTDBDescriptor {
// sort_buffer_size_in_bytes
loadSortBuffer(properties);
+
+ conf.setIncludeNullValueInWriteThroughputMetric(
+ Boolean.parseBoolean(
+ properties.getProperty(
+ "include_null_value_in_write_throughput_metric",
+ ConfigurationFileUtils.getConfigurationDefaultValue(
+ "include_null_value_in_write_throughput_metric"))));
} catch (Exception e) {
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AbstractMemTable.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AbstractMemTable.java
index a4b235650cf..f2f4d5e2943 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AbstractMemTable.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AbstractMemTable.java
@@ -26,6 +26,7 @@ import org.apache.iotdb.commons.path.IFullPath;
import org.apache.iotdb.commons.path.NonAlignedFullPath;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
import org.apache.iotdb.db.exception.WriteProcessException;
import org.apache.iotdb.db.exception.query.QueryProcessException;
import org.apache.iotdb.db.queryengine.execution.fragment.QueryContext;
@@ -211,7 +212,9 @@ public abstract class AbstractMemTable implements IMemTable
{
int pointsInserted =
insertRowNode.getMeasurements().length
- insertRowNode.getFailedMeasurementNumber()
- - nullPointsNumber;
+ -
(IoTDBDescriptor.getInstance().getConfig().isIncludeNullValueInWriteThroughputMetric()
+ ? 0
+ : nullPointsNumber);
totalPointsNum += pointsInserted;
return pointsInserted;
@@ -224,12 +227,16 @@ public abstract class AbstractMemTable implements
IMemTable {
Object[] values = insertRowNode.getValues();
List<IMeasurementSchema> schemaList = new ArrayList<>();
List<TSDataType> dataTypes = new ArrayList<>();
+ int nullPointsNumber = 0;
for (int i = 0; i < insertRowNode.getMeasurements().length; i++) {
// Use measurements[i] to ignore failed partial insert
if (measurements[i] == null
|| values[i] == null
|| insertRowNode.getColumnCategories() != null
&& insertRowNode.getColumnCategories()[i] !=
TsTableColumnCategory.FIELD) {
+ if (values[i] == null) {
+ nullPointsNumber++;
+ }
schemaList.add(null);
continue;
}
@@ -244,7 +251,11 @@ public abstract class AbstractMemTable implements
IMemTable {
MemUtils.getAlignedRowRecordSize(dataTypes, values,
insertRowNode.getColumnCategories());
writeAlignedRow(insertRowNode.getDeviceID(), schemaList,
insertRowNode.getTime(), values);
int pointsInserted =
- insertRowNode.getMeasurementColumnCnt() -
insertRowNode.getFailedMeasurementNumber();
+ insertRowNode.getMeasurementColumnCnt()
+ - insertRowNode.getFailedMeasurementNumber()
+ -
(IoTDBDescriptor.getInstance().getConfig().isIncludeNullValueInWriteThroughputMetric()
+ ? 0
+ : nullPointsNumber);
totalPointsNum += pointsInserted;
return pointsInserted;
}
@@ -253,11 +264,17 @@ public abstract class AbstractMemTable implements
IMemTable {
public int insertTablet(InsertTabletNode insertTabletNode, int start, int
end)
throws WriteProcessException {
try {
+ int nullPointsNumber = computeTabletNullPointsNumber(insertTabletNode,
start, end);
writeTabletNode(insertTabletNode, start, end);
memSize += MemUtils.getTabletSize(insertTabletNode, start, end);
int pointsInserted =
- (insertTabletNode.getDataTypes().length -
insertTabletNode.getFailedMeasurementNumber())
- * (end - start);
+ ((insertTabletNode.getDataTypes().length -
insertTabletNode.getFailedMeasurementNumber())
+ * (end - start))
+ - (IoTDBDescriptor.getInstance()
+ .getConfig()
+ .isIncludeNullValueInWriteThroughputMetric()
+ ? 0
+ : nullPointsNumber);
totalPointsNum += pointsInserted;
return pointsInserted;
} catch (RuntimeException e) {
@@ -270,13 +287,19 @@ public abstract class AbstractMemTable implements
IMemTable {
InsertTabletNode insertTabletNode, int start, int end, TSStatus[]
results)
throws WriteProcessException {
try {
+ int nullPointsNumber = computeTabletNullPointsNumber(insertTabletNode,
start, end);
writeAlignedTablet(insertTabletNode, start, end, results);
// TODO-Table: what is the relation between this and
TsFileProcessor.checkMemCost
memSize += MemUtils.getAlignedTabletSize(insertTabletNode, start, end,
results);
int pointsInserted =
- (insertTabletNode.getMeasurementColumnCnt()
- - insertTabletNode.getFailedMeasurementNumber())
- * (end - start);
+ ((insertTabletNode.getMeasurementColumnCnt()
+ - insertTabletNode.getFailedMeasurementNumber())
+ * (end - start))
+ - (IoTDBDescriptor.getInstance()
+ .getConfig()
+ .isIncludeNullValueInWriteThroughputMetric()
+ ? 0
+ : nullPointsNumber);
totalPointsNum += pointsInserted;
return pointsInserted;
} catch (RuntimeException e) {
@@ -284,6 +307,25 @@ public abstract class AbstractMemTable implements
IMemTable {
}
}
+ private static int computeTabletNullPointsNumber(
+ InsertTabletNode insertTabletNode, int start, int end) {
+ Object[] values = insertTabletNode.getBitMaps();
+ int nullPointsNumber = 0;
+ if (values != null) {
+ for (int i = 0; i < insertTabletNode.getMeasurements().length; i++) {
+ BitMap bitMap = (BitMap) values[i];
+ if (bitMap != null && !bitMap.isAllUnmarked()) {
+ for (int j = start; j < end; j++) {
+ if (bitMap.isMarked(j)) {
+ nullPointsNumber++;
+ }
+ }
+ }
+ }
+ }
+ return nullPointsNumber;
+ }
+
@Override
public void write(
IDeviceID deviceId,
diff --git
a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template
b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template
index 7eb20db14f3..288c814613e 100644
---
a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template
+++
b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template
@@ -2154,3 +2154,8 @@
write_request_remote_dispatch_max_retry_duration_in_ms=60000
# effectiveMode: hot_reload
# Datatype: boolean
enable_retry_for_unknown_error=false
+
+# The switch to control if allow null value be included in the "quantity
total" metric statistic.
+# effectiveMode: hot_reload
+# Datatype: Boolean
+include_null_value_in_write_throughput_metric=false
\ No newline at end of file