Skip to content

Commit a653aee

Browse files
authored
Avoid copying measurements when updating last cache (#18059) (#18071)
* Avoid copying measurements when updating last cache * spotless (cherry picked from commit aabf552)
1 parent c0f674c commit a653aee

8 files changed

Lines changed: 117 additions & 31 deletions

File tree

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceCacheEntry.java‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.tsfile.write.schema.IMeasurementSchema;
2727

2828
import javax.annotation.Nonnull;
29+
import javax.annotation.Nullable;
2930
import javax.annotation.concurrent.ThreadSafe;
3031

3132
import java.util.Map;
@@ -115,16 +116,33 @@ int initOrInvalidateLastCache(final String[] measurements, final boolean isInval
115116

116117
int tryUpdateLastCache(
117118
final String[] measurements, final TimeValuePair[] timeValuePairs, boolean invalidateNull) {
119+
return tryUpdateLastCache(measurements, null, timeValuePairs, invalidateNull);
120+
}
121+
122+
int tryUpdateLastCache(
123+
final String[] measurements,
124+
final @Nullable IMeasurementSchema[] measurementSchemas,
125+
final TimeValuePair[] timeValuePairs,
126+
boolean invalidateNull) {
118127
final DeviceLastCache cache = lastCache.get();
119128
final int result =
120-
Objects.nonNull(cache) ? cache.tryUpdate(measurements, timeValuePairs, invalidateNull) : 0;
129+
Objects.nonNull(cache)
130+
? cache.tryUpdate(measurements, measurementSchemas, timeValuePairs, invalidateNull)
131+
: 0;
121132
return Objects.nonNull(lastCache.get()) ? result : 0;
122133
}
123134

124135
int tryUpdateLastCache(final String[] measurements, final TimeValuePair[] timeValuePairs) {
125136
return tryUpdateLastCache(measurements, timeValuePairs, false);
126137
}
127138

139+
int tryUpdateLastCache(
140+
final String[] measurements,
141+
final @Nullable IMeasurementSchema[] measurementSchemas,
142+
final TimeValuePair[] timeValuePairs) {
143+
return tryUpdateLastCache(measurements, measurementSchemas, timeValuePairs, false);
144+
}
145+
128146
int invalidateLastCache(final String measurement) {
129147
final DeviceLastCache cache = lastCache.get();
130148
final int result = Objects.nonNull(cache) ? cache.invalidate(measurement) : 0;

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceLastCache.java‎

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.tsfile.read.TimeValuePair;
2424
import org.apache.tsfile.utils.RamUsageEstimator;
2525
import org.apache.tsfile.utils.TsPrimitiveType;
26+
import org.apache.tsfile.write.schema.IMeasurementSchema;
2627

2728
import javax.annotation.Nonnull;
2829
import javax.annotation.Nullable;
@@ -122,15 +123,27 @@ int tryUpdate(
122123
final @Nonnull String[] measurements,
123124
final @Nonnull TimeValuePair[] timeValuePairs,
124125
final boolean invalidateNull) {
126+
return tryUpdate(measurements, null, timeValuePairs, invalidateNull);
127+
}
128+
129+
int tryUpdate(
130+
final @Nonnull String[] measurements,
131+
final @Nullable IMeasurementSchema[] measurementSchemas,
132+
final @Nonnull TimeValuePair[] timeValuePairs,
133+
final boolean invalidateNull) {
125134
final AtomicInteger diff = new AtomicInteger(0);
126135
long lastTime = Long.MIN_VALUE;
127136

128137
for (int i = 0; i < measurements.length; ++i) {
138+
final String measurement = getRawMeasurement(measurements, measurementSchemas, i);
139+
if (Objects.isNull(measurement)) {
140+
continue;
141+
}
129142
if (Objects.isNull(timeValuePairs[i])) {
130143
if (invalidateNull) {
131144
diff.addAndGet(
132-
-((int) RamUsageEstimator.sizeOf(measurements[i])
133-
+ getTvPairEntrySize(measurement2CachedLastMap.remove(measurements[i]))));
145+
-((int) RamUsageEstimator.sizeOf(measurement)
146+
+ getTvPairEntrySize(measurement2CachedLastMap.remove(measurement))));
134147
}
135148
continue;
136149
}
@@ -140,8 +153,8 @@ int tryUpdate(
140153
lastTime = timeValuePairs[i].getTimestamp();
141154
}
142155
measurement2CachedLastMap.computeIfPresent(
143-
measurements[i],
144-
(measurement, tvPair) -> {
156+
measurement,
157+
(measurementName, tvPair) -> {
145158
if (tvPair.getTimestamp() <= timeValuePairs[finalI].getTimestamp()) {
146159
diff.addAndGet(getDiffSize(tvPair, timeValuePairs[finalI]));
147160
return timeValuePairs[finalI];
@@ -159,6 +172,21 @@ int tryUpdate(
159172
return diff.get();
160173
}
161174

175+
@Nullable
176+
private static String getRawMeasurement(
177+
final @Nonnull String[] measurements,
178+
final @Nullable IMeasurementSchema[] measurementSchemas,
179+
final int index) {
180+
if (Objects.isNull(measurements[index])) {
181+
return null;
182+
}
183+
return Objects.nonNull(measurementSchemas)
184+
&& index < measurementSchemas.length
185+
&& Objects.nonNull(measurementSchemas[index])
186+
? measurementSchemas[index].getMeasurementId()
187+
: measurements[index];
188+
}
189+
162190
@GuardedBy("DataRegionInsertLock#writeLock")
163191
int invalidate(final String measurement) {
164192
final AtomicInteger diff = new AtomicInteger();

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceNormalSchema.java‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,18 @@ public int update(final String[] measurements, final IMeasurementSchema[] schema
6666
final int length = measurements.length;
6767

6868
for (int i = 0; i < length; ++i) {
69+
final String inputMeasurement = measurements[i];
70+
if (Objects.isNull(inputMeasurement)) {
71+
continue;
72+
}
73+
final IMeasurementSchema schema = i < schemas.length ? schemas[i] : null;
74+
final String measurement =
75+
Objects.nonNull(schema) ? schema.getMeasurementId() : inputMeasurement;
6976
// Skip this to avoid instance creation/gc for writing performance
70-
if (measurements[i] == null || measurementMap.containsKey(measurements[i])) {
77+
if (schema == null || measurementMap.containsKey(measurement)) {
7178
continue;
7279
}
73-
diff += putEntry(measurements[i], schemas[i], null);
80+
diff += putEntry(measurement, schema, null);
7481
}
7582
return diff;
7683
}

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/cache/schema/DeviceSchemaCache.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ void updateLastCache(
143143
: entry ->
144144
entry.setMeasurementSchema(
145145
database2Use, isAligned, measurements, measurementSchemas)
146-
+ entry.tryUpdateLastCache(measurements, timeValuePairs),
146+
+ entry.tryUpdateLastCache(measurements, measurementSchemas, timeValuePairs),
147147
Objects.isNull(timeValuePairs));
148148
}
149149

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertNode.java‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -399,13 +399,19 @@ public boolean allMeasurementFailed() {
399399
public String[] getRawMeasurements() {
400400
String[] measurements = getMeasurements();
401401
MeasurementSchema[] measurementSchemas = getMeasurementSchemas();
402-
String[] rawMeasurements = new String[measurements.length];
402+
String[] rawMeasurements = measurements;
403403
for (int i = 0; i < measurements.length; i++) {
404-
if (measurementSchemas[i] != null) {
404+
if (measurementSchemas != null
405+
&& i < measurementSchemas.length
406+
&& measurementSchemas[i] != null) {
405407
// get raw measurement rather than alias
406-
rawMeasurements[i] = measurementSchemas[i].getMeasurementId();
407-
} else {
408-
rawMeasurements[i] = measurements[i];
408+
String rawMeasurement = measurementSchemas[i].getMeasurementId();
409+
if (!Objects.equals(rawMeasurement, measurements[i])) {
410+
if (rawMeasurements == measurements) {
411+
rawMeasurements = Arrays.copyOf(measurements, measurements.length);
412+
}
413+
rawMeasurements[i] = rawMeasurement;
414+
}
409415
}
410416
}
411417
return rawMeasurements;

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java‎

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -863,18 +863,12 @@ public TimeValuePair composeTimeValuePair(int columnIndex) {
863863
}
864864

865865
public void updateLastCache(String databaseName) {
866-
String[] rawMeasurements = getRawMeasurements();
867-
TimeValuePair[] timeValuePairs = new TimeValuePair[rawMeasurements.length];
868-
for (int i = 0; i < rawMeasurements.length; i++) {
866+
TimeValuePair[] timeValuePairs = new TimeValuePair[measurements.length];
867+
for (int i = 0; i < measurements.length; i++) {
869868
timeValuePairs[i] = composeTimeValuePair(i);
870869
}
871870
DataNodeSchemaCache.getInstance()
872871
.updateLastCacheIfExists(
873-
databaseName,
874-
devicePath,
875-
rawMeasurements,
876-
timeValuePairs,
877-
isAligned,
878-
measurementSchemas);
872+
databaseName, devicePath, measurements, timeValuePairs, isAligned, measurementSchemas);
879873
}
880874
}

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java‎

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,18 +1191,12 @@ public void updateLastCache(final String databaseName) {
11911191
}
11921192

11931193
public void updateLastCache(final String databaseName, final TSStatus[] results) {
1194-
final String[] rawMeasurements = getRawMeasurements();
1195-
final TimeValuePair[] timeValuePairs = new TimeValuePair[rawMeasurements.length];
1196-
for (int i = 0; i < rawMeasurements.length; i++) {
1194+
final TimeValuePair[] timeValuePairs = new TimeValuePair[measurements.length];
1195+
for (int i = 0; i < measurements.length; i++) {
11971196
timeValuePairs[i] = composeLastTimeValuePair(i, results, 0, rowCount);
11981197
}
11991198
DataNodeSchemaCache.getInstance()
12001199
.updateLastCacheIfExists(
1201-
databaseName,
1202-
devicePath,
1203-
rawMeasurements,
1204-
timeValuePairs,
1205-
isAligned,
1206-
measurementSchemas);
1200+
databaseName, devicePath, measurements, timeValuePairs, isAligned, measurementSchemas);
12071201
}
12081202
}

‎iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/cache/DataNodeSchemaCacheTest.java‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import org.apache.iotdb.db.queryengine.common.schematree.ISchemaTree;
2828
import org.apache.iotdb.db.queryengine.plan.analyze.cache.schema.DataNodeSchemaCache;
2929
import org.apache.iotdb.db.queryengine.plan.analyze.cache.schema.SchemaCacheEntry;
30+
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId;
31+
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertRowNode;
3032
import org.apache.iotdb.db.schemaengine.template.ClusterTemplateManager;
3133
import org.apache.iotdb.db.schemaengine.template.Template;
3234

@@ -267,6 +269,43 @@ public void testUpdateLastCache() throws IllegalPathException {
267269
Assert.assertEquals(0, dataNodeSchemaCache.getDeviceSchemaCache().getMemoryUsage());
268270
}
269271

272+
@Test
273+
public void testUpdateLastCacheWithAliasDoesNotCopyMeasurements() throws IllegalPathException {
274+
final String database = "root.db";
275+
final PartialPath device = new PartialPath("root.db.d_alias");
276+
final MeasurementSchema s1 = new MeasurementSchema("s1", TSDataType.INT32);
277+
final MeasurementPath s1Path = new MeasurementPath(device.concatNode("s1"), s1);
278+
279+
dataNodeSchemaCache.declareLastCache(database, s1Path);
280+
281+
final InsertRowNode insertRowNode =
282+
new InsertRowNode(
283+
new PlanNodeId("testUpdateLastCacheWithAliasDoesNotCopyMeasurements"),
284+
device,
285+
false,
286+
new String[] {"alias"},
287+
new TSDataType[] {TSDataType.INT32},
288+
new MeasurementSchema[] {s1},
289+
1L,
290+
new Object[] {1},
291+
false) {
292+
@Override
293+
public String[] getRawMeasurements() {
294+
throw new AssertionError("Last cache update should not copy raw measurements");
295+
}
296+
};
297+
298+
insertRowNode.updateLastCache(database);
299+
300+
Assert.assertEquals(
301+
new TimeValuePair(1L, new TsPrimitiveType.TsInt(1)),
302+
dataNodeSchemaCache.getLastCache(new MeasurementPath(device.concatNode("s1"), s1)));
303+
Assert.assertNull(
304+
dataNodeSchemaCache.getLastCache(
305+
new MeasurementPath(
306+
device.concatNode("alias"), new MeasurementSchema("alias", TSDataType.INT32))));
307+
}
308+
270309
@Test
271310
public void testInvalidateLastCacheByWildcardDevicePath() throws IllegalPathException {
272311
final MeasurementSchema s0 = new MeasurementSchema("s0", TSDataType.INT32);

0 commit comments

Comments
 (0)