jt2594838 commented on a change in pull request #2454:
URL: https://github.com/apache/iotdb/pull/2454#discussion_r554661270



##########
File path: 
cluster/src/main/java/org/apache/iotdb/cluster/log/applier/AsyncDataLogApplier.java
##########
@@ -131,7 +132,10 @@ private PartialPath getPlanKey(PhysicalPlan plan) throws 
StorageGroupNotSetExcep
 
   private PartialPath getPlanSG(PhysicalPlan plan) throws 
StorageGroupNotSetException {
     PartialPath sgPath = null;
-    if (plan instanceof InsertPlan) {
+    if (plan instanceof InsertMultiTabletPlan) {
+      PartialPath deviceId = ((InsertMultiTabletPlan) plan).getFirstDeviceId();
+      sgPath = IoTDB.metaManager.getStorageGroupPath(deviceId);
+    } else if (plan instanceof InsertPlan) {

Review comment:
       Applying InertMultiTabletPlan parallelly with other insertions is 
dangerous, for example:
   There are two plans, one InsertMultiTabletPlan and one InsertTabletPlan, and 
the InsertMultiTabletPlan contains 2 insertions: insert timestamp=0,value=0 to 
root.sg1.s0 and insert timestamp=0,value=0 to root.sg2.s0; while the 
InsertTabletPlan has only one insertion: insert timestamp=0,value=100 to 
root.sg2.s0. 
   Because the first deviceId is used as the plan key, the two plans may be 
executed in parallel, so the actual order is not guaranteed on different 
replicas, that is, on NodeA, InsertMultiTabletPlan may be executed lastly so 
root.sg2.s0 is 0 at timestamp=0, but on NodeB, InsertTabletPlan is executed 
later so root.sg2.s0 is 100 at timestamp=0, thus data becomes inconsistent.

##########
File path: 
cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanRouter.java
##########
@@ -155,6 +158,40 @@ private PartitionGroup routePlan(ShowChildPathsPlan plan) {
     return Collections.singletonMap(plan, partitionGroup);
   }
 
+  private Map<PhysicalPlan, PartitionGroup> 
splitAndRoutePlan(InsertMultiTabletPlan plan)
+      throws MetadataException {
+    Map<PartitionGroup, InsertMultiTabletPlan> pgInsertMultiTabletPlanMap = 
new HashMap<>();
+    for (int i = 0; i < plan.getInsertTabletPlanList().size(); i++) {
+      InsertTabletPlan insertTabletPlan = 
plan.getInsertTabletPlanList().get(i);
+      Map<PhysicalPlan, PartitionGroup> tmpResult = 
splitAndRoutePlan(insertTabletPlan);
+      for (Map.Entry<PhysicalPlan, PartitionGroup> entry : 
tmpResult.entrySet()) {
+        InsertTabletPlan tmpPlan = (InsertTabletPlan) entry.getKey();
+        PartitionGroup tmpPg = entry.getValue();
+
+        InsertMultiTabletPlan pgPlan = pgInsertMultiTabletPlanMap.get(tmpPg);
+        if (pgPlan == null) {
+          List<InsertTabletPlan> insertTabletPlanList = new ArrayList<>();
+          List<Integer> parentInsetTablePlanIndexList = new ArrayList<>();
+          insertTabletPlanList.add(tmpPlan);
+          parentInsetTablePlanIndexList.add(i);
+          InsertMultiTabletPlan insertMultiTabletPlan = new 
InsertMultiTabletPlan(
+              insertTabletPlanList, parentInsetTablePlanIndexList);
+          pgInsertMultiTabletPlanMap.put(tmpPg, insertMultiTabletPlan);
+        } else {
+          pgPlan.addInsertTabletPlan(tmpPlan, i);
+          pgInsertMultiTabletPlanMap.put(tmpPg, pgPlan);

Review comment:
       Is this `put` necessary?

##########
File path: server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
##########
@@ -1560,29 +1551,68 @@ public TSStatus insertTablets(TSInsertTabletsReq req) {
     }
   }
 
-  public List<TSStatus> insertTabletsInternal(TSInsertTabletsReq req) throws 
IllegalPathException {
-    List<TSStatus> statusList = new ArrayList<>();
+  private InsertTabletPlan constructInsertTabletPlan(TSInsertTabletsReq req, 
int i)
+      throws IllegalPathException {
+    InsertTabletPlan insertTabletPlan = new InsertTabletPlan(
+        new PartialPath(req.deviceIds.get(i)),
+        req.measurementsList.get(i));
+    insertTabletPlan.setTimes(
+        QueryDataSetUtils.readTimesFromBuffer(req.timestampsList.get(i), 
req.sizeList.get(i)));
+    insertTabletPlan.setColumns(
+        QueryDataSetUtils.readValuesFromBuffer(
+            req.valuesList.get(i), req.typesList.get(i), 
req.measurementsList.get(i).size(),
+            req.sizeList.get(i)));
+    insertTabletPlan.setRowCount(req.sizeList.get(i));
+    insertTabletPlan.setDataTypes(req.typesList.get(i));
+    return insertTabletPlan;
+  }
 
+  /**
+   * process the TSInsertTabletsReq by Split it into many InsertTabletPlan
+   */
+  public TSStatus insertTabletsInternalV1(TSInsertTabletsReq req) throws 
IllegalPathException {

Review comment:
       If v1 is used nowhere, it should be removed.

##########
File path: 
server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertMultiTabletPlan.java
##########
@@ -0,0 +1,324 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.db.qp.physical.crud;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeMap;
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
+import org.apache.iotdb.service.rpc.thrift.TSStatus;
+
+/**
+ * Mainly used in the distributed version, when multiple InsertTabletPlans 
belong to a raft
+ * replication group, we merge these InsertTabletPlans into one 
InsertMultiTabletPlan, which can
+ * reduce the number of raft logs. For details, please refer to 
https://issues.apache.org/jira/browse/IOTDB-1099
+ */
+public class InsertMultiTabletPlan extends InsertPlan {
+
+  /**
+   * the value is used to indict the parent InsertTabletPlan's index when the 
parent
+   * InsertTabletPlan is split to multi sub InsertTabletPlans. if the 
InsertTabletPlan have no
+   * parent plan, the value is -1;
+   * <p>
+   * suppose we original have 3 InsertTabletPlans contains 1 
InsertMultiTabletPlan, then the initial
+   * InsertMultiTabletPlan would have the following two attributes:

Review comment:
       original -> originally
   contains -> in

##########
File path: 
server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertMultiTabletPlan.java
##########
@@ -0,0 +1,324 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.db.qp.physical.crud;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeMap;
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
+import org.apache.iotdb.service.rpc.thrift.TSStatus;
+
+/**
+ * Mainly used in the distributed version, when multiple InsertTabletPlans 
belong to a raft
+ * replication group, we merge these InsertTabletPlans into one 
InsertMultiTabletPlan, which can
+ * reduce the number of raft logs. For details, please refer to 
https://issues.apache.org/jira/browse/IOTDB-1099
+ */
+public class InsertMultiTabletPlan extends InsertPlan {
+
+  /**
+   * the value is used to indict the parent InsertTabletPlan's index when the 
parent
+   * InsertTabletPlan is split to multi sub InsertTabletPlans. if the 
InsertTabletPlan have no
+   * parent plan, the value is -1;
+   * <p>
+   * suppose we original have 3 InsertTabletPlans contains 1 
InsertMultiTabletPlan, then the initial
+   * InsertMultiTabletPlan would have the following two attributes:
+   * <p>
+   * 
insertTabletPlanList={InsertTabletPlan_1,InsertTabletPlan_2,InsertTabletPlan_3}
+   * <p>
+   * parentInsetTablePlanIndexList={-1,-1,-1} both have three values.
+   *
+   * <p>
+   * if the InsertTabletPlan_1 is split into two sub InsertTabletPlan, 
InsertTabletPlan_2 is split
+   * into three sub InsertTabletPlan, InsertTabletPlan_3 is split into four 
sub InsertTabletPlan.
+   * <p>
+   * InsertTabletPlan_1={InsertTabletPlan_1_subPlan1, 
InsertTabletPlan_1_subPlan2}
+   *
+   * <p>
+   * InsertTabletPlan_2={InsertTabletPlan_2_subPlan1, 
InsertTabletPlan_2_subPlan2,
+   * InsertTabletPlan_2_subPlan3}
+   *
+   * <p>
+   * InsertTabletPlan_3={InsertTabletPlan_3_subPlan1, 
InsertTabletPlan_3_subPlan2,
+   * InsertTabletPlan_3_subPlan3, InsertTabletPlan_3_subPlan4}
+   * <p>
+   * those sub plans belongs to two different raft data group, so will 
generate two new
+   * InsertMultiTabletPlan
+   * <p>
+   * InsertMultiTabletPlant1.insertTabletPlanList={InsertTabletPlan_1_subPlan1,
+   * InsertTabletPlan_3_subPlan1, InsertTabletPlan_3_subPlan3, 
InsertTabletPlan_3_subPlan4}
+   * <p>
+   * InsertMultiTabletPlant1.parentInsetTablePlanIndexList={0,2,2,2}
+   *
+   * <p>
+   * InsertMultiTabletPlant2.insertTabletPlanList={InsertTabletPlan_1_subPlan2,
+   * InsertTabletPlan_2_subPlan1, InsertTabletPlan_2_subPlan2, 
InsertTabletPlan_2_subPlan3,
+   * InsertTabletPlan_3_subPlan2}
+   * <p>
+   * InsertMultiTabletPlant2.parentInsetTablePlanIndexList={0,1,1,1,2}
+   *
+   * <p>
+   * this is usually used to back-propagate exceptions to the parent plan 
without losing their
+   * proper positions.
+   */
+  List<Integer> parentInsetTablePlanIndexList;
+
+  /**
+   * the InsertTabletPlan list
+   */
+  List<InsertTabletPlan> insertTabletPlanList;
+
+  /**
+   * record the result of creation of time series
+   */
+  private Map<Integer, TSStatus> results = new TreeMap<>();
+
+
+  public InsertMultiTabletPlan() {
+    super(OperatorType.MULTI_BATCH_INSERT);
+    this.insertTabletPlanList = new ArrayList<>();
+    this.parentInsetTablePlanIndexList = new ArrayList<>();
+  }
+
+  public InsertMultiTabletPlan(List<InsertTabletPlan> insertTabletPlanList) {
+    super(OperatorType.MULTI_BATCH_INSERT);
+    this.insertTabletPlanList = insertTabletPlanList;
+    this.parentInsetTablePlanIndexList = new ArrayList<>();
+  }
+
+  public InsertMultiTabletPlan(List<InsertTabletPlan> insertTabletPlanList,
+      List<Integer> parentInsetTablePlanIndexList) {
+    super(OperatorType.MULTI_BATCH_INSERT);
+    this.insertTabletPlanList = insertTabletPlanList;
+    this.parentInsetTablePlanIndexList = parentInsetTablePlanIndexList;
+  }
+
+  public void addInsertTabletPlan(InsertTabletPlan plan, Integer parentIndex) {
+    insertTabletPlanList.add(plan);
+    parentInsetTablePlanIndexList.add(parentIndex);
+  }
+
+  public List<InsertTabletPlan> getInsertTabletPlanList() {
+    return insertTabletPlanList;
+  }
+
+  public List<Integer> getParentInsetTablePlanIndexList() {
+    return parentInsetTablePlanIndexList;
+  }
+
+
+  @Override
+  public List<PartialPath> getPaths() {
+    List<PartialPath> result = new ArrayList<>();
+    for (InsertTabletPlan insertTabletPlan : insertTabletPlanList) {
+      result.addAll(insertTabletPlan.getPaths());
+    }
+    return result;
+  }
+
+  @Override
+  public long getMinTime() {
+    long minTime = Long.MAX_VALUE;
+    for (InsertTabletPlan insertTabletPlan : insertTabletPlanList) {
+      if (minTime > insertTabletPlan.getMinTime()) {
+        minTime = insertTabletPlan.getMinTime();
+      }
+    }
+    return minTime;
+  }
+
+  public long getMaxTime() {
+    long maxTime = Long.MIN_VALUE;
+    for (InsertTabletPlan insertTabletPlan : insertTabletPlanList) {
+      if (maxTime < insertTabletPlan.getMinTime()) {
+        maxTime = insertTabletPlan.getMinTime();
+      }
+    }
+    return maxTime;
+  }
+
+  public int getTabletsSize() {
+    return insertTabletPlanList.size();
+  }
+
+  public Map<Integer, TSStatus> getResults() {
+    return results;
+  }
+
+  /**
+   * @return the total row of the whole InsertTabletPlan
+   */
+  public int getTotalRowCount() {
+    int rowCount = 0;
+    for (InsertTabletPlan insertTabletPlan : insertTabletPlanList) {
+      rowCount += insertTabletPlan.getRowCount();
+    }
+    return rowCount;
+  }
+
+  /**
+   * Gets the number of rows in the InsertTabletPlan of the index
+   *
+   * @param index the index of the insertTabletPlanList
+   * @return the total row count of the insertTabletPlanList.get(i)

Review comment:
       Supplement that 0 will be returned if the index is out of bound.

##########
File path: 
cluster/src/main/java/org/apache/iotdb/cluster/log/applier/AsyncDataLogApplier.java
##########
@@ -131,7 +132,7 @@ private PartialPath getPlanKey(PhysicalPlan plan) throws 
StorageGroupNotSetExcep
 
   private PartialPath getPlanSG(PhysicalPlan plan) throws 
StorageGroupNotSetException {
     PartialPath sgPath = null;
-    if (plan instanceof InsertPlan) {
+    if (plan instanceof InsertPlan && !(plan instanceof 
InsertMultiTabletPlan)) {

Review comment:
       This forces InsertMultiTabletPlan to be executed serially with other 
plans, converts the applying process to a synchronized one, and within one 
InsertMultiTabletPlan, tablets of different storage groups are executed one by 
one, so the parallelism is significantly reduced.
   I think we can add a limitation that each InsertMultiTabletPlan after 
splitting will only contain tablets of one storage group, so tablets of 
different storage groups can be inserted in parallel.

##########
File path: 
server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertMultiTabletPlan.java
##########
@@ -0,0 +1,324 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.db.qp.physical.crud;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeMap;
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
+import org.apache.iotdb.service.rpc.thrift.TSStatus;
+
+/**
+ * Mainly used in the distributed version, when multiple InsertTabletPlans 
belong to a raft
+ * replication group, we merge these InsertTabletPlans into one 
InsertMultiTabletPlan, which can
+ * reduce the number of raft logs. For details, please refer to 
https://issues.apache.org/jira/browse/IOTDB-1099
+ */
+public class InsertMultiTabletPlan extends InsertPlan {
+
+  /**
+   * the value is used to indict the parent InsertTabletPlan's index when the 
parent
+   * InsertTabletPlan is split to multi sub InsertTabletPlans. if the 
InsertTabletPlan have no
+   * parent plan, the value is -1;
+   * <p>
+   * suppose we original have 3 InsertTabletPlans contains 1 
InsertMultiTabletPlan, then the initial
+   * InsertMultiTabletPlan would have the following two attributes:
+   * <p>
+   * 
insertTabletPlanList={InsertTabletPlan_1,InsertTabletPlan_2,InsertTabletPlan_3}
+   * <p>
+   * parentInsetTablePlanIndexList={-1,-1,-1} both have three values.
+   *
+   * <p>
+   * if the InsertTabletPlan_1 is split into two sub InsertTabletPlan, 
InsertTabletPlan_2 is split
+   * into three sub InsertTabletPlan, InsertTabletPlan_3 is split into four 
sub InsertTabletPlan.
+   * <p>
+   * InsertTabletPlan_1={InsertTabletPlan_1_subPlan1, 
InsertTabletPlan_1_subPlan2}
+   *
+   * <p>
+   * InsertTabletPlan_2={InsertTabletPlan_2_subPlan1, 
InsertTabletPlan_2_subPlan2,
+   * InsertTabletPlan_2_subPlan3}
+   *
+   * <p>
+   * InsertTabletPlan_3={InsertTabletPlan_3_subPlan1, 
InsertTabletPlan_3_subPlan2,
+   * InsertTabletPlan_3_subPlan3, InsertTabletPlan_3_subPlan4}
+   * <p>
+   * those sub plans belongs to two different raft data group, so will 
generate two new
+   * InsertMultiTabletPlan
+   * <p>
+   * InsertMultiTabletPlant1.insertTabletPlanList={InsertTabletPlan_1_subPlan1,
+   * InsertTabletPlan_3_subPlan1, InsertTabletPlan_3_subPlan3, 
InsertTabletPlan_3_subPlan4}
+   * <p>
+   * InsertMultiTabletPlant1.parentInsetTablePlanIndexList={0,2,2,2}
+   *
+   * <p>
+   * InsertMultiTabletPlant2.insertTabletPlanList={InsertTabletPlan_1_subPlan2,
+   * InsertTabletPlan_2_subPlan1, InsertTabletPlan_2_subPlan2, 
InsertTabletPlan_2_subPlan3,
+   * InsertTabletPlan_3_subPlan2}
+   * <p>
+   * InsertMultiTabletPlant2.parentInsetTablePlanIndexList={0,1,1,1,2}
+   *
+   * <p>
+   * this is usually used to back-propagate exceptions to the parent plan 
without losing their
+   * proper positions.
+   */
+  List<Integer> parentInsetTablePlanIndexList;
+
+  /**
+   * the InsertTabletPlan list
+   */
+  List<InsertTabletPlan> insertTabletPlanList;
+
+  /**
+   * record the result of creation of time series
+   */
+  private Map<Integer, TSStatus> results = new TreeMap<>();
+
+
+  public InsertMultiTabletPlan() {
+    super(OperatorType.MULTI_BATCH_INSERT);
+    this.insertTabletPlanList = new ArrayList<>();
+    this.parentInsetTablePlanIndexList = new ArrayList<>();
+  }
+
+  public InsertMultiTabletPlan(List<InsertTabletPlan> insertTabletPlanList) {
+    super(OperatorType.MULTI_BATCH_INSERT);
+    this.insertTabletPlanList = insertTabletPlanList;
+    this.parentInsetTablePlanIndexList = new ArrayList<>();
+  }
+
+  public InsertMultiTabletPlan(List<InsertTabletPlan> insertTabletPlanList,
+      List<Integer> parentInsetTablePlanIndexList) {
+    super(OperatorType.MULTI_BATCH_INSERT);
+    this.insertTabletPlanList = insertTabletPlanList;
+    this.parentInsetTablePlanIndexList = parentInsetTablePlanIndexList;
+  }
+
+  public void addInsertTabletPlan(InsertTabletPlan plan, Integer parentIndex) {
+    insertTabletPlanList.add(plan);
+    parentInsetTablePlanIndexList.add(parentIndex);
+  }
+
+  public List<InsertTabletPlan> getInsertTabletPlanList() {
+    return insertTabletPlanList;
+  }
+
+  public List<Integer> getParentInsetTablePlanIndexList() {
+    return parentInsetTablePlanIndexList;
+  }
+
+
+  @Override
+  public List<PartialPath> getPaths() {
+    List<PartialPath> result = new ArrayList<>();
+    for (InsertTabletPlan insertTabletPlan : insertTabletPlanList) {
+      result.addAll(insertTabletPlan.getPaths());
+    }
+    return result;
+  }
+
+  @Override
+  public long getMinTime() {
+    long minTime = Long.MAX_VALUE;
+    for (InsertTabletPlan insertTabletPlan : insertTabletPlanList) {
+      if (minTime > insertTabletPlan.getMinTime()) {
+        minTime = insertTabletPlan.getMinTime();
+      }
+    }
+    return minTime;
+  }
+
+  public long getMaxTime() {
+    long maxTime = Long.MIN_VALUE;
+    for (InsertTabletPlan insertTabletPlan : insertTabletPlanList) {
+      if (maxTime < insertTabletPlan.getMinTime()) {
+        maxTime = insertTabletPlan.getMinTime();
+      }
+    }
+    return maxTime;
+  }
+
+  public int getTabletsSize() {
+    return insertTabletPlanList.size();
+  }
+
+  public Map<Integer, TSStatus> getResults() {
+    return results;
+  }
+
+  /**
+   * @return the total row of the whole InsertTabletPlan
+   */
+  public int getTotalRowCount() {
+    int rowCount = 0;
+    for (InsertTabletPlan insertTabletPlan : insertTabletPlanList) {
+      rowCount += insertTabletPlan.getRowCount();
+    }
+    return rowCount;
+  }
+
+  /**
+   * Gets the number of rows in the InsertTabletPlan of the index
+   *
+   * @param index the index of the insertTabletPlanList
+   * @return the total row count of the insertTabletPlanList.get(i)
+   */
+  public int getRowCount(int index) {
+    if (index >= insertTabletPlanList.size() || index < 0) {
+      return 0;
+    }
+    return insertTabletPlanList.get(index).getRowCount();
+  }
+
+  public PartialPath getFirstDeviceId() {
+    return insertTabletPlanList.get(0).getDeviceId();
+  }
+
+  public InsertTabletPlan getInsertTabletPlan(int index) {
+    if (index >= insertTabletPlanList.size() || index < 0) {
+      return null;
+    }
+    return insertTabletPlanList.get(index);
+  }
+
+  /**
+   * @param index the index of the sub plan in this InsertMultiTabletPlan
+   * @return the parent's index in the parent InsertMultiTabletPlan
+   */
+  public int getParentIndex(int index) {
+    if (index >= parentInsetTablePlanIndexList.size() || index < 0) {
+      return -1;
+    }
+    return parentInsetTablePlanIndexList.get(index);
+  }
+
+  @Override
+  public void checkIntegrity() throws QueryProcessException {
+    for (InsertTabletPlan insertTabletPlan : insertTabletPlanList) {
+      insertTabletPlan.checkIntegrity();
+    }
+  }
+
+  public void setParentInsetTablePlanIndexList(List<Integer> 
parentInsetTablePlanIndexList) {

Review comment:
       parentInsetTablePlanIndexList -> parentInsertTablePlanIndexList

##########
File path: 
server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertMultiTabletPlan.java
##########
@@ -0,0 +1,324 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.db.qp.physical.crud;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeMap;
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
+import org.apache.iotdb.service.rpc.thrift.TSStatus;
+
+/**
+ * Mainly used in the distributed version, when multiple InsertTabletPlans 
belong to a raft
+ * replication group, we merge these InsertTabletPlans into one 
InsertMultiTabletPlan, which can
+ * reduce the number of raft logs. For details, please refer to 
https://issues.apache.org/jira/browse/IOTDB-1099
+ */
+public class InsertMultiTabletPlan extends InsertPlan {
+
+  /**
+   * the value is used to indict the parent InsertTabletPlan's index when the 
parent
+   * InsertTabletPlan is split to multi sub InsertTabletPlans. if the 
InsertTabletPlan have no
+   * parent plan, the value is -1;
+   * <p>
+   * suppose we original have 3 InsertTabletPlans contains 1 
InsertMultiTabletPlan, then the initial
+   * InsertMultiTabletPlan would have the following two attributes:
+   * <p>
+   * 
insertTabletPlanList={InsertTabletPlan_1,InsertTabletPlan_2,InsertTabletPlan_3}
+   * <p>
+   * parentInsetTablePlanIndexList={-1,-1,-1} both have three values.
+   *
+   * <p>
+   * if the InsertTabletPlan_1 is split into two sub InsertTabletPlan, 
InsertTabletPlan_2 is split
+   * into three sub InsertTabletPlan, InsertTabletPlan_3 is split into four 
sub InsertTabletPlan.

Review comment:
       InsertTabletPlan -> InsertTabletPlans

##########
File path: 
server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertMultiTabletPlan.java
##########
@@ -0,0 +1,324 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.db.qp.physical.crud;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeMap;
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
+import org.apache.iotdb.service.rpc.thrift.TSStatus;
+
+/**
+ * Mainly used in the distributed version, when multiple InsertTabletPlans 
belong to a raft
+ * replication group, we merge these InsertTabletPlans into one 
InsertMultiTabletPlan, which can
+ * reduce the number of raft logs. For details, please refer to 
https://issues.apache.org/jira/browse/IOTDB-1099
+ */
+public class InsertMultiTabletPlan extends InsertPlan {
+
+  /**
+   * the value is used to indict the parent InsertTabletPlan's index when the 
parent
+   * InsertTabletPlan is split to multi sub InsertTabletPlans. if the 
InsertTabletPlan have no
+   * parent plan, the value is -1;
+   * <p>
+   * suppose we original have 3 InsertTabletPlans contains 1 
InsertMultiTabletPlan, then the initial
+   * InsertMultiTabletPlan would have the following two attributes:
+   * <p>
+   * 
insertTabletPlanList={InsertTabletPlan_1,InsertTabletPlan_2,InsertTabletPlan_3}
+   * <p>
+   * parentInsetTablePlanIndexList={-1,-1,-1} both have three values.
+   *
+   * <p>
+   * if the InsertTabletPlan_1 is split into two sub InsertTabletPlan, 
InsertTabletPlan_2 is split
+   * into three sub InsertTabletPlan, InsertTabletPlan_3 is split into four 
sub InsertTabletPlan.
+   * <p>
+   * InsertTabletPlan_1={InsertTabletPlan_1_subPlan1, 
InsertTabletPlan_1_subPlan2}
+   *
+   * <p>
+   * InsertTabletPlan_2={InsertTabletPlan_2_subPlan1, 
InsertTabletPlan_2_subPlan2,
+   * InsertTabletPlan_2_subPlan3}
+   *
+   * <p>
+   * InsertTabletPlan_3={InsertTabletPlan_3_subPlan1, 
InsertTabletPlan_3_subPlan2,
+   * InsertTabletPlan_3_subPlan3, InsertTabletPlan_3_subPlan4}
+   * <p>
+   * those sub plans belongs to two different raft data group, so will 
generate two new
+   * InsertMultiTabletPlan
+   * <p>
+   * InsertMultiTabletPlant1.insertTabletPlanList={InsertTabletPlan_1_subPlan1,
+   * InsertTabletPlan_3_subPlan1, InsertTabletPlan_3_subPlan3, 
InsertTabletPlan_3_subPlan4}
+   * <p>
+   * InsertMultiTabletPlant1.parentInsetTablePlanIndexList={0,2,2,2}
+   *
+   * <p>
+   * InsertMultiTabletPlant2.insertTabletPlanList={InsertTabletPlan_1_subPlan2,
+   * InsertTabletPlan_2_subPlan1, InsertTabletPlan_2_subPlan2, 
InsertTabletPlan_2_subPlan3,
+   * InsertTabletPlan_3_subPlan2}
+   * <p>
+   * InsertMultiTabletPlant2.parentInsetTablePlanIndexList={0,1,1,1,2}
+   *
+   * <p>
+   * this is usually used to back-propagate exceptions to the parent plan 
without losing their
+   * proper positions.
+   */
+  List<Integer> parentInsetTablePlanIndexList;
+
+  /**
+   * the InsertTabletPlan list
+   */
+  List<InsertTabletPlan> insertTabletPlanList;
+
+  /**
+   * record the result of creation of time series
+   */
+  private Map<Integer, TSStatus> results = new TreeMap<>();
+
+
+  public InsertMultiTabletPlan() {
+    super(OperatorType.MULTI_BATCH_INSERT);
+    this.insertTabletPlanList = new ArrayList<>();
+    this.parentInsetTablePlanIndexList = new ArrayList<>();
+  }
+
+  public InsertMultiTabletPlan(List<InsertTabletPlan> insertTabletPlanList) {
+    super(OperatorType.MULTI_BATCH_INSERT);
+    this.insertTabletPlanList = insertTabletPlanList;
+    this.parentInsetTablePlanIndexList = new ArrayList<>();
+  }
+
+  public InsertMultiTabletPlan(List<InsertTabletPlan> insertTabletPlanList,
+      List<Integer> parentInsetTablePlanIndexList) {
+    super(OperatorType.MULTI_BATCH_INSERT);
+    this.insertTabletPlanList = insertTabletPlanList;
+    this.parentInsetTablePlanIndexList = parentInsetTablePlanIndexList;
+  }
+
+  public void addInsertTabletPlan(InsertTabletPlan plan, Integer parentIndex) {
+    insertTabletPlanList.add(plan);
+    parentInsetTablePlanIndexList.add(parentIndex);
+  }
+
+  public List<InsertTabletPlan> getInsertTabletPlanList() {
+    return insertTabletPlanList;
+  }
+
+  public List<Integer> getParentInsetTablePlanIndexList() {
+    return parentInsetTablePlanIndexList;
+  }
+
+
+  @Override
+  public List<PartialPath> getPaths() {
+    List<PartialPath> result = new ArrayList<>();
+    for (InsertTabletPlan insertTabletPlan : insertTabletPlanList) {
+      result.addAll(insertTabletPlan.getPaths());
+    }
+    return result;
+  }
+
+  @Override
+  public long getMinTime() {
+    long minTime = Long.MAX_VALUE;
+    for (InsertTabletPlan insertTabletPlan : insertTabletPlanList) {
+      if (minTime > insertTabletPlan.getMinTime()) {
+        minTime = insertTabletPlan.getMinTime();
+      }
+    }
+    return minTime;
+  }
+
+  public long getMaxTime() {
+    long maxTime = Long.MIN_VALUE;
+    for (InsertTabletPlan insertTabletPlan : insertTabletPlanList) {
+      if (maxTime < insertTabletPlan.getMinTime()) {
+        maxTime = insertTabletPlan.getMinTime();

Review comment:
       insertTabletPlan.getMinTime() -> insertTabletPlan.getMaxTime()

##########
File path: 
server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertMultiTabletPlan.java
##########
@@ -0,0 +1,324 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.db.qp.physical.crud;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeMap;
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
+import org.apache.iotdb.service.rpc.thrift.TSStatus;
+
+/**
+ * Mainly used in the distributed version, when multiple InsertTabletPlans 
belong to a raft
+ * replication group, we merge these InsertTabletPlans into one 
InsertMultiTabletPlan, which can
+ * reduce the number of raft logs. For details, please refer to 
https://issues.apache.org/jira/browse/IOTDB-1099
+ */
+public class InsertMultiTabletPlan extends InsertPlan {
+
+  /**
+   * the value is used to indict the parent InsertTabletPlan's index when the 
parent
+   * InsertTabletPlan is split to multi sub InsertTabletPlans. if the 
InsertTabletPlan have no
+   * parent plan, the value is -1;
+   * <p>
+   * suppose we original have 3 InsertTabletPlans contains 1 
InsertMultiTabletPlan, then the initial
+   * InsertMultiTabletPlan would have the following two attributes:
+   * <p>
+   * 
insertTabletPlanList={InsertTabletPlan_1,InsertTabletPlan_2,InsertTabletPlan_3}
+   * <p>
+   * parentInsetTablePlanIndexList={-1,-1,-1} both have three values.
+   *
+   * <p>
+   * if the InsertTabletPlan_1 is split into two sub InsertTabletPlan, 
InsertTabletPlan_2 is split
+   * into three sub InsertTabletPlan, InsertTabletPlan_3 is split into four 
sub InsertTabletPlan.
+   * <p>
+   * InsertTabletPlan_1={InsertTabletPlan_1_subPlan1, 
InsertTabletPlan_1_subPlan2}
+   *
+   * <p>
+   * InsertTabletPlan_2={InsertTabletPlan_2_subPlan1, 
InsertTabletPlan_2_subPlan2,
+   * InsertTabletPlan_2_subPlan3}
+   *
+   * <p>
+   * InsertTabletPlan_3={InsertTabletPlan_3_subPlan1, 
InsertTabletPlan_3_subPlan2,
+   * InsertTabletPlan_3_subPlan3, InsertTabletPlan_3_subPlan4}
+   * <p>
+   * those sub plans belongs to two different raft data group, so will 
generate two new
+   * InsertMultiTabletPlan

Review comment:
       belongs -> belong
   group -> groups
   InsertMultiTabletPlan -> InsertMultiTabletPlans




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to