This is an automated email from the ASF dual-hosted git repository.

jt2594838 pushed a commit to branch dev/1.3
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/dev/1.3 by this push:
     new a653aeeff1e Avoid copying measurements when updating last cache 
(#18059) (#18071)
a653aeeff1e is described below

commit a653aeeff1e5ec584f8c53cf0695c3ced5370e50
Author: Caideyipi <[email protected]>
AuthorDate: Wed Jul 1 10:26:26 2026 +0800

    Avoid copying measurements when updating last cache (#18059) (#18071)
    
    * Avoid copying measurements when updating last cache
    
    * spotless
    
    (cherry picked from commit aabf552629bc03dc7f143d5d5b63c39c89fe5f15)
---
 .../analyze/cache/schema/DeviceCacheEntry.java     | 20 ++++++++++-
 .../plan/analyze/cache/schema/DeviceLastCache.java | 36 +++++++++++++++++---
 .../analyze/cache/schema/DeviceNormalSchema.java   | 11 ++++--
 .../analyze/cache/schema/DeviceSchemaCache.java    |  2 +-
 .../plan/planner/plan/node/write/InsertNode.java   | 16 ++++++---
 .../planner/plan/node/write/InsertRowNode.java     | 12 ++-----
 .../planner/plan/node/write/InsertTabletNode.java  | 12 ++-----
 .../db/metadata/cache/DataNodeSchemaCacheTest.java | 39 ++++++++++++++++++++++
 8 files changed, 117 insertions(+), 31 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceCacheEntry.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceCacheEntry.java
index ecd4c297e57..976888959aa 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceCacheEntry.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceCacheEntry.java
@@ -26,6 +26,7 @@ import org.apache.tsfile.utils.RamUsageEstimator;
 import org.apache.tsfile.write.schema.IMeasurementSchema;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import javax.annotation.concurrent.ThreadSafe;
 
 import java.util.Map;
@@ -115,9 +116,19 @@ public class DeviceCacheEntry {
 
   int tryUpdateLastCache(
       final String[] measurements, final TimeValuePair[] timeValuePairs, 
boolean invalidateNull) {
+    return tryUpdateLastCache(measurements, null, timeValuePairs, 
invalidateNull);
+  }
+
+  int tryUpdateLastCache(
+      final String[] measurements,
+      final @Nullable IMeasurementSchema[] measurementSchemas,
+      final TimeValuePair[] timeValuePairs,
+      boolean invalidateNull) {
     final DeviceLastCache cache = lastCache.get();
     final int result =
-        Objects.nonNull(cache) ? cache.tryUpdate(measurements, timeValuePairs, 
invalidateNull) : 0;
+        Objects.nonNull(cache)
+            ? cache.tryUpdate(measurements, measurementSchemas, 
timeValuePairs, invalidateNull)
+            : 0;
     return Objects.nonNull(lastCache.get()) ? result : 0;
   }
 
@@ -125,6 +136,13 @@ public class DeviceCacheEntry {
     return tryUpdateLastCache(measurements, timeValuePairs, false);
   }
 
+  int tryUpdateLastCache(
+      final String[] measurements,
+      final @Nullable IMeasurementSchema[] measurementSchemas,
+      final TimeValuePair[] timeValuePairs) {
+    return tryUpdateLastCache(measurements, measurementSchemas, 
timeValuePairs, false);
+  }
+
   int invalidateLastCache(final String measurement) {
     final DeviceLastCache cache = lastCache.get();
     final int result = Objects.nonNull(cache) ? cache.invalidate(measurement) 
: 0;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceLastCache.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceLastCache.java
index 9ebc1fc413c..78e6cdfb20b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceLastCache.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceLastCache.java
@@ -23,6 +23,7 @@ import org.apache.tsfile.enums.TSDataType;
 import org.apache.tsfile.read.TimeValuePair;
 import org.apache.tsfile.utils.RamUsageEstimator;
 import org.apache.tsfile.utils.TsPrimitiveType;
+import org.apache.tsfile.write.schema.IMeasurementSchema;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -122,15 +123,27 @@ public class DeviceLastCache {
       final @Nonnull String[] measurements,
       final @Nonnull TimeValuePair[] timeValuePairs,
       final boolean invalidateNull) {
+    return tryUpdate(measurements, null, timeValuePairs, invalidateNull);
+  }
+
+  int tryUpdate(
+      final @Nonnull String[] measurements,
+      final @Nullable IMeasurementSchema[] measurementSchemas,
+      final @Nonnull TimeValuePair[] timeValuePairs,
+      final boolean invalidateNull) {
     final AtomicInteger diff = new AtomicInteger(0);
     long lastTime = Long.MIN_VALUE;
 
     for (int i = 0; i < measurements.length; ++i) {
+      final String measurement = getRawMeasurement(measurements, 
measurementSchemas, i);
+      if (Objects.isNull(measurement)) {
+        continue;
+      }
       if (Objects.isNull(timeValuePairs[i])) {
         if (invalidateNull) {
           diff.addAndGet(
-              -((int) RamUsageEstimator.sizeOf(measurements[i])
-                  + 
getTvPairEntrySize(measurement2CachedLastMap.remove(measurements[i]))));
+              -((int) RamUsageEstimator.sizeOf(measurement)
+                  + 
getTvPairEntrySize(measurement2CachedLastMap.remove(measurement))));
         }
         continue;
       }
@@ -140,8 +153,8 @@ public class DeviceLastCache {
         lastTime = timeValuePairs[i].getTimestamp();
       }
       measurement2CachedLastMap.computeIfPresent(
-          measurements[i],
-          (measurement, tvPair) -> {
+          measurement,
+          (measurementName, tvPair) -> {
             if (tvPair.getTimestamp() <= 
timeValuePairs[finalI].getTimestamp()) {
               diff.addAndGet(getDiffSize(tvPair, timeValuePairs[finalI]));
               return timeValuePairs[finalI];
@@ -159,6 +172,21 @@ public class DeviceLastCache {
     return diff.get();
   }
 
+  @Nullable
+  private static String getRawMeasurement(
+      final @Nonnull String[] measurements,
+      final @Nullable IMeasurementSchema[] measurementSchemas,
+      final int index) {
+    if (Objects.isNull(measurements[index])) {
+      return null;
+    }
+    return Objects.nonNull(measurementSchemas)
+            && index < measurementSchemas.length
+            && Objects.nonNull(measurementSchemas[index])
+        ? measurementSchemas[index].getMeasurementId()
+        : measurements[index];
+  }
+
   @GuardedBy("DataRegionInsertLock#writeLock")
   int invalidate(final String measurement) {
     final AtomicInteger diff = new AtomicInteger();
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceNormalSchema.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceNormalSchema.java
index 6d50905bbca..fece095f54a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceNormalSchema.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceNormalSchema.java
@@ -66,11 +66,18 @@ public class DeviceNormalSchema implements IDeviceSchema {
     final int length = measurements.length;
 
     for (int i = 0; i < length; ++i) {
+      final String inputMeasurement = measurements[i];
+      if (Objects.isNull(inputMeasurement)) {
+        continue;
+      }
+      final IMeasurementSchema schema = i < schemas.length ? schemas[i] : null;
+      final String measurement =
+          Objects.nonNull(schema) ? schema.getMeasurementId() : 
inputMeasurement;
       // Skip this to avoid instance creation/gc for writing performance
-      if (measurements[i] == null || 
measurementMap.containsKey(measurements[i])) {
+      if (schema == null || measurementMap.containsKey(measurement)) {
         continue;
       }
-      diff += putEntry(measurements[i], schemas[i], null);
+      diff += putEntry(measurement, schema, null);
     }
     return diff;
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceSchemaCache.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceSchemaCache.java
index 9bcb020b72f..d9ce4982447 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceSchemaCache.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceSchemaCache.java
@@ -143,7 +143,7 @@ public class DeviceSchemaCache {
             : entry ->
                 entry.setMeasurementSchema(
                         database2Use, isAligned, measurements, 
measurementSchemas)
-                    + entry.tryUpdateLastCache(measurements, timeValuePairs),
+                    + entry.tryUpdateLastCache(measurements, 
measurementSchemas, timeValuePairs),
         Objects.isNull(timeValuePairs));
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertNode.java
index aee5cc1ec93..29651e9455c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertNode.java
@@ -399,13 +399,19 @@ public abstract class InsertNode extends SearchNode 
implements ComparableConsens
   public String[] getRawMeasurements() {
     String[] measurements = getMeasurements();
     MeasurementSchema[] measurementSchemas = getMeasurementSchemas();
-    String[] rawMeasurements = new String[measurements.length];
+    String[] rawMeasurements = measurements;
     for (int i = 0; i < measurements.length; i++) {
-      if (measurementSchemas[i] != null) {
+      if (measurementSchemas != null
+          && i < measurementSchemas.length
+          && measurementSchemas[i] != null) {
         // get raw measurement rather than alias
-        rawMeasurements[i] = measurementSchemas[i].getMeasurementId();
-      } else {
-        rawMeasurements[i] = measurements[i];
+        String rawMeasurement = measurementSchemas[i].getMeasurementId();
+        if (!Objects.equals(rawMeasurement, measurements[i])) {
+          if (rawMeasurements == measurements) {
+            rawMeasurements = Arrays.copyOf(measurements, measurements.length);
+          }
+          rawMeasurements[i] = rawMeasurement;
+        }
       }
     }
     return rawMeasurements;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java
index 23c17808d49..19d4ee6da0a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java
@@ -863,18 +863,12 @@ public class InsertRowNode extends InsertNode implements 
WALEntryValue {
   }
 
   public void updateLastCache(String databaseName) {
-    String[] rawMeasurements = getRawMeasurements();
-    TimeValuePair[] timeValuePairs = new TimeValuePair[rawMeasurements.length];
-    for (int i = 0; i < rawMeasurements.length; i++) {
+    TimeValuePair[] timeValuePairs = new TimeValuePair[measurements.length];
+    for (int i = 0; i < measurements.length; i++) {
       timeValuePairs[i] = composeTimeValuePair(i);
     }
     DataNodeSchemaCache.getInstance()
         .updateLastCacheIfExists(
-            databaseName,
-            devicePath,
-            rawMeasurements,
-            timeValuePairs,
-            isAligned,
-            measurementSchemas);
+            databaseName, devicePath, measurements, timeValuePairs, isAligned, 
measurementSchemas);
   }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
index 472c1e79d7e..9440baf580c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java
@@ -1191,18 +1191,12 @@ public class InsertTabletNode extends InsertNode 
implements WALEntryValue {
   }
 
   public void updateLastCache(final String databaseName, final TSStatus[] 
results) {
-    final String[] rawMeasurements = getRawMeasurements();
-    final TimeValuePair[] timeValuePairs = new 
TimeValuePair[rawMeasurements.length];
-    for (int i = 0; i < rawMeasurements.length; i++) {
+    final TimeValuePair[] timeValuePairs = new 
TimeValuePair[measurements.length];
+    for (int i = 0; i < measurements.length; i++) {
       timeValuePairs[i] = composeLastTimeValuePair(i, results, 0, rowCount);
     }
     DataNodeSchemaCache.getInstance()
         .updateLastCacheIfExists(
-            databaseName,
-            devicePath,
-            rawMeasurements,
-            timeValuePairs,
-            isAligned,
-            measurementSchemas);
+            databaseName, devicePath, measurements, timeValuePairs, isAligned, 
measurementSchemas);
   }
 }
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/cache/DataNodeSchemaCacheTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/cache/DataNodeSchemaCacheTest.java
index bf15d216e67..57d70853be3 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/cache/DataNodeSchemaCacheTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/cache/DataNodeSchemaCacheTest.java
@@ -27,6 +27,8 @@ import 
org.apache.iotdb.db.queryengine.common.schematree.ClusterSchemaTree;
 import org.apache.iotdb.db.queryengine.common.schematree.ISchemaTree;
 import 
org.apache.iotdb.db.queryengine.plan.analyze.cache.schema.DataNodeSchemaCache;
 import 
org.apache.iotdb.db.queryengine.plan.analyze.cache.schema.SchemaCacheEntry;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId;
+import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertRowNode;
 import org.apache.iotdb.db.schemaengine.template.ClusterTemplateManager;
 import org.apache.iotdb.db.schemaengine.template.Template;
 
@@ -267,6 +269,43 @@ public class DataNodeSchemaCacheTest {
     Assert.assertEquals(0, 
dataNodeSchemaCache.getDeviceSchemaCache().getMemoryUsage());
   }
 
+  @Test
+  public void testUpdateLastCacheWithAliasDoesNotCopyMeasurements() throws 
IllegalPathException {
+    final String database = "root.db";
+    final PartialPath device = new PartialPath("root.db.d_alias");
+    final MeasurementSchema s1 = new MeasurementSchema("s1", TSDataType.INT32);
+    final MeasurementPath s1Path = new 
MeasurementPath(device.concatNode("s1"), s1);
+
+    dataNodeSchemaCache.declareLastCache(database, s1Path);
+
+    final InsertRowNode insertRowNode =
+        new InsertRowNode(
+            new 
PlanNodeId("testUpdateLastCacheWithAliasDoesNotCopyMeasurements"),
+            device,
+            false,
+            new String[] {"alias"},
+            new TSDataType[] {TSDataType.INT32},
+            new MeasurementSchema[] {s1},
+            1L,
+            new Object[] {1},
+            false) {
+          @Override
+          public String[] getRawMeasurements() {
+            throw new AssertionError("Last cache update should not copy raw 
measurements");
+          }
+        };
+
+    insertRowNode.updateLastCache(database);
+
+    Assert.assertEquals(
+        new TimeValuePair(1L, new TsPrimitiveType.TsInt(1)),
+        dataNodeSchemaCache.getLastCache(new 
MeasurementPath(device.concatNode("s1"), s1)));
+    Assert.assertNull(
+        dataNodeSchemaCache.getLastCache(
+            new MeasurementPath(
+                device.concatNode("alias"), new MeasurementSchema("alias", 
TSDataType.INT32))));
+  }
+
   @Test
   public void testInvalidateLastCacheByWildcardDevicePath() throws 
IllegalPathException {
     final MeasurementSchema s0 = new MeasurementSchema("s0", TSDataType.INT32);

Reply via email to