Optimize TsTable with Copy-on-Write pattern for thread-safe concurrent access (#17069)
* Optimize TsTable with Copy-on-Write pattern for thread-safe concurrent access
- Change columnSchemaMap, tagColumnIndexMap, and idColumnIndexMap from final to volatile
- Implement Copy-on-Write in executeWrite method:
1. Create local copies of maps before modification
2. Execute write operations on local copies
3. Atomically update class fields after write completes
- Add WriteOperation functional interface to pass map copies to write operations
- Add executeWriteWithTransform for efficient single-pass transformation during copy
- Optimize renameColumnSchema to preserve column order with single-pass copy
- This ensures readers see either complete old data or complete new data, avoiding ConcurrentModificationException
* fix
* fix
* fix
* Revert "fix"
This reverts commit 2155558217aabe2a0dd7dc09e85c569597d38b9f.
* Revert "fix"
This reverts commit 7e798b1ba71365cc7ad8a76c5e83122ead6a3744.
* Revert "fix"
This reverts commit 9b221b192be5ecf73fb4bd23ec2a7d3009888bfd.
* Revert "Optimize TsTable with Copy-on-Write pattern for thread-safe concurrent access"
This reverts commit 3eeaf83f3dc3c32ee944daf3f7ff9b456e88b29e.
* fix
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java
index 9beab9b..64fa5f3 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java
@@ -288,13 +288,17 @@
try {
if (databaseTableMap.containsKey(database)
&& databaseTableMap.get(database).containsKey(tableName)) {
- databaseTableMap.get(database).get(tableName).removeColumnSchema(columnName);
+ final TsTable copyTable = new TsTable(databaseTableMap.get(database).get(tableName));
+ copyTable.removeColumnSchema(columnName);
+ databaseTableMap.get(database).put(tableName, copyTable);
}
if (preUpdateTableMap.containsKey(database)
&& preUpdateTableMap.get(database).containsKey(tableName)) {
final Pair<TsTable, Long> tableVersionPair = preUpdateTableMap.get(database).get(tableName);
if (Objects.nonNull(tableVersionPair.getLeft())) {
- tableVersionPair.getLeft().removeColumnSchema(columnName);
+ final TsTable copyTable = new TsTable(tableVersionPair.getLeft());
+ copyTable.removeColumnSchema(columnName);
+ tableVersionPair.setLeft(copyTable);
}
tableVersionPair.setRight(tableVersionPair.getRight() + 1);
}