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

qiaojialin 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 973157a  Adapt serialization/deserialization in CreateTemplatePlan 
with former template structure (#4355)
973157a is described below

commit 973157af1e0091975e066552ea4d8dabd612440b
Author: ZhaoXin <[email protected]>
AuthorDate: Fri Nov 12 17:53:50 2021 +0800

    Adapt serialization/deserialization in CreateTemplatePlan with former 
template structure (#4355)
---
 .../iotdb/db/metadata/template/Template.java       |  56 +++--
 .../db/qp/physical/crud/CreateTemplatePlan.java    | 103 ++++++++-
 .../iotdb/db/metadata/MManagerBasicTest.java       | 132 +----------
 .../org/apache/iotdb/db/metadata/TemplateTest.java | 254 +++++++++++++++++++++
 .../iotdb/db/metadata/mlog/MLogUpgraderTest.java   |  72 ++++++
 5 files changed, 450 insertions(+), 167 deletions(-)

diff --git 
a/server/src/main/java/org/apache/iotdb/db/metadata/template/Template.java 
b/server/src/main/java/org/apache/iotdb/db/metadata/template/Template.java
index e3d4f3b..5866e32 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/template/Template.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/template/Template.java
@@ -19,6 +19,8 @@
 package org.apache.iotdb.db.metadata.template;
 
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.exception.metadata.MetadataException;
+import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.metadata.mnode.EntityMNode;
 import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
@@ -228,13 +230,13 @@ public class Template {
         // find the parent and add nodes to template
         if (prefix.equals("")) {
           leafNode =
-              MeasurementMNode.getMeasurementMNode(null, 
measurementNames.get(i), schemas[i], "");
+              MeasurementMNode.getMeasurementMNode(null, 
measurementNames.get(i), schemas[i], null);
           directNodes.put(leafNode.getName(), leafNode);
         } else {
           commonPar = (IEntityMNode) constructEntityPath(alignedPaths[0]);
           leafNode =
               MeasurementMNode.getMeasurementMNode(
-                  commonPar, measurementNames.get(i), schemas[i], "");
+                  commonPar, measurementNames.get(i), schemas[i], null);
           commonPar.addChild(leafNode);
         }
         schemaMap.put(getFullPathWithoutTemplateName(leafNode), schemas[i]);
@@ -255,7 +257,7 @@ public class Template {
     synchronized (this) {
       IMeasurementMNode leafNode =
           MeasurementMNode.getMeasurementMNode(
-              (IEntityMNode) cur, pathNode[pathNode.length - 1], schema, "");
+              (IEntityMNode) cur, pathNode[pathNode.length - 1], schema, null);
       if (cur == null) {
         directNodes.put(leafNode.getName(), leafNode);
       } else {
@@ -316,31 +318,27 @@ public class Template {
     return new ArrayList<>(schemaMap.keySet());
   }
 
-  public List<String> getMeasurementsUnderPath(String path) {
+  public List<String> getMeasurementsUnderPath(String path) throws 
MetadataException {
     if (path.equals("")) {
       return getAllMeasurementsPaths();
     }
     List<String> res = new ArrayList<>();
-    try {
-      IMNode cur = getPathNodeInTemplate(path);
-      if (cur == null) {
-        throw new IllegalPathException(path, "Path not exists.");
-      }
+    IMNode cur = getPathNodeInTemplate(path);
+    if (cur == null) {
+      throw new PathNotExistException(path);
+    }
+    if (cur.isMeasurement()) {
+      return Collections.singletonList(getFullPathWithoutTemplateName(cur));
+    }
+    Deque<IMNode> stack = new ArrayDeque<>();
+    stack.push(cur);
+    while (stack.size() != 0) {
+      cur = stack.pop();
       if (cur.isMeasurement()) {
-        return Collections.singletonList(getFullPathWithoutTemplateName(cur));
-      }
-      Deque<IMNode> stack = new ArrayDeque<>();
-      stack.push(cur);
-      while (stack.size() != 0) {
-        cur = stack.pop();
-        if (cur.isMeasurement()) {
-          res.add(getFullPathWithoutTemplateName(cur));
-        } else {
-          for (IMNode child : cur.getChildren().values()) stack.push(child);
-        }
+        res.add(getFullPathWithoutTemplateName(cur));
+      } else {
+        for (IMNode child : cur.getChildren().values()) stack.push(child);
       }
-    } catch (IllegalPathException e) {
-      e.printStackTrace();
     }
     return res;
   }
@@ -388,17 +386,17 @@ public class Template {
     return directNodes.containsKey(nodeName);
   }
 
-  public boolean isPathMeasurement(String path) throws IllegalPathException {
+  public boolean isPathMeasurement(String path) throws MetadataException {
     String[] pathNodes = MetaUtils.splitPathToDetachedPath(path);
     if (!directNodes.containsKey(pathNodes[0])) {
-      throw new IllegalPathException(path, "Path does not exist.");
+      throw new PathNotExistException(path);
     }
     IMNode cur = directNodes.get(pathNodes[0]);
     for (int i = 1; i < pathNodes.length; i++) {
       if (cur.hasChild(pathNodes[i])) {
         cur = cur.getChild(pathNodes[i]);
       } else {
-        throw new IllegalPathException(path, "Path does not exist.");
+        throw new PathNotExistException(path);
       }
     }
     return cur.isMeasurement();
@@ -539,10 +537,10 @@ public class Template {
 
   // region deduction of template
 
-  public void deleteMeasurements(String path) throws IllegalPathException {
+  public void deleteMeasurements(String path) throws MetadataException {
     IMNode cur = getPathNodeInTemplate(path);
     if (cur == null) {
-      throw new IllegalPathException(path, "Path does not exist");
+      throw new PathNotExistException(path);
     }
     if (!cur.isMeasurement()) {
       throw new IllegalPathException(path, "Path is not pointed to a 
measurement node.");
@@ -558,12 +556,12 @@ public class Template {
     measurementsCount--;
   }
 
-  public void deleteSeriesCascade(String path) throws IllegalPathException {
+  public void deleteSeriesCascade(String path) throws MetadataException {
     IMNode cur = getPathNodeInTemplate(path);
     IMNode par;
 
     if (cur == null) {
-      throw new IllegalPathException(path, "Path not exists.");
+      throw new PathNotExistException(path);
     }
     par = cur.getParent();
     if (par == null) {
diff --git 
a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/CreateTemplatePlan.java
 
b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/CreateTemplatePlan.java
index 028b39f..da7e7b3 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/CreateTemplatePlan.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/CreateTemplatePlan.java
@@ -23,6 +23,7 @@ import 
org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
+import org.apache.iotdb.db.utils.TestOnly;
 import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -50,6 +51,8 @@ public class CreateTemplatePlan extends PhysicalPlan {
   TSDataType[][] dataTypes;
   TSEncoding[][] encodings;
   CompressionType[][] compressors;
+  // constant to help resolve serialized sequence
+  private static final int NEW_PLAN = -1;
 
   public CreateTemplatePlan() {
     super(false, OperatorType.CREATE_TEMPLATE);
@@ -284,6 +287,10 @@ public class CreateTemplatePlan extends PhysicalPlan {
 
     ReadWriteIOUtils.write(name, buffer);
 
+    // write NEW_PLAN as flag to note that there is no schemaNames and new 
nested list for
+    // compressors
+    ReadWriteIOUtils.write(NEW_PLAN, buffer);
+
     // measurements
     ReadWriteIOUtils.write(measurements.length, buffer);
     for (String[] measurementList : measurements) {
@@ -326,10 +333,24 @@ public class CreateTemplatePlan extends PhysicalPlan {
   @Override
   @SuppressWarnings("Duplicates")
   public void deserialize(ByteBuffer buffer) {
+    boolean isFormerSerialized;
     name = ReadWriteIOUtils.readString(buffer);
 
-    // measurements
     int size = ReadWriteIOUtils.readInt(buffer);
+
+    if (size == NEW_PLAN) {
+      isFormerSerialized = false;
+    } else {
+      // deserialize schemaNames
+      isFormerSerialized = true;
+      schemaNames = new String[size];
+      for (int i = 0; i < size; i++) {
+        schemaNames[i] = ReadWriteIOUtils.readString(buffer);
+      }
+    }
+
+    // measurements
+    size = ReadWriteIOUtils.readInt(buffer);
     measurements = new String[size][];
     for (int i = 0; i < size; i++) {
       int listSize = ReadWriteIOUtils.readInt(buffer);
@@ -363,12 +384,27 @@ public class CreateTemplatePlan extends PhysicalPlan {
 
     // compressor
     size = ReadWriteIOUtils.readInt(buffer);
-    compressors = new CompressionType[size][];
-    for (int i = 0; i < size; i++) {
-      int listSize = ReadWriteIOUtils.readInt(buffer);
-      compressors[i] = new CompressionType[listSize];
-      for (int j = 0; j < listSize; j++) {
-        compressors[i][j] = 
CompressionType.values()[ReadWriteIOUtils.readInt(buffer)];
+    if (!isFormerSerialized) {
+      // there is a nested list, where each measurement may has different 
compressor
+      compressors = new CompressionType[size][];
+      for (int i = 0; i < size; i++) {
+        int listSize = ReadWriteIOUtils.readInt(buffer);
+        compressors[i] = new CompressionType[listSize];
+        for (int j = 0; j < listSize; j++) {
+          compressors[i][j] = 
CompressionType.values()[ReadWriteIOUtils.readInt(buffer)];
+        }
+      }
+    } else {
+      // a flat list where aligned measurements have same compressor, 
serialize as a nested list
+      compressors = new CompressionType[size][];
+      for (int i = 0; i < size; i++) {
+        int listSize = measurements[i].length;
+        compressors[i] = new CompressionType[listSize];
+        CompressionType alignedCompressionType =
+            CompressionType.values()[ReadWriteIOUtils.readInt(buffer)];
+        for (int j = 0; j < listSize; j++) {
+          compressors[i][j] = alignedCompressionType;
+        }
       }
     }
 
@@ -381,6 +417,10 @@ public class CreateTemplatePlan extends PhysicalPlan {
 
     ReadWriteIOUtils.write(name, stream);
 
+    // write NEW_PLAN as flag to note that there is no schemaNames and new 
nested list for
+    // compressors
+    ReadWriteIOUtils.write(NEW_PLAN, stream);
+
     // measurements
     ReadWriteIOUtils.write(measurements.length, stream);
     for (String[] measurementList : measurements) {
@@ -420,6 +460,55 @@ public class CreateTemplatePlan extends PhysicalPlan {
     stream.writeLong(index);
   }
 
+  // added and modified for test adaptation of CreateSchemaTemplate 
serialization.
+  @TestOnly
+  public void formerSerialize(DataOutputStream stream) throws IOException {
+    stream.writeByte((byte) PhysicalPlanType.CREATE_TEMPLATE.ordinal());
+
+    ReadWriteIOUtils.write(name, stream);
+
+    // schema names
+    ReadWriteIOUtils.write(schemaNames.length, stream);
+    for (String schemaName : schemaNames) {
+      ReadWriteIOUtils.write(schemaName, stream);
+    }
+
+    // measurements
+    ReadWriteIOUtils.write(measurements.length, stream);
+    for (String[] measurementList : measurements) {
+      ReadWriteIOUtils.write(measurementList.length, stream);
+      for (String measurement : measurementList) {
+        ReadWriteIOUtils.write(measurement, stream);
+      }
+    }
+
+    // datatype
+    ReadWriteIOUtils.write(dataTypes.length, stream);
+    for (TSDataType[] dataTypesList : dataTypes) {
+      ReadWriteIOUtils.write(dataTypesList.length, stream);
+      for (TSDataType dataType : dataTypesList) {
+        ReadWriteIOUtils.write(dataType.ordinal(), stream);
+      }
+    }
+
+    // encoding
+    ReadWriteIOUtils.write(encodings.length, stream);
+    for (TSEncoding[] encodingList : encodings) {
+      ReadWriteIOUtils.write(encodingList.length, stream);
+      for (TSEncoding encoding : encodingList) {
+        ReadWriteIOUtils.write(encoding.ordinal(), stream);
+      }
+    }
+
+    // compressor
+    ReadWriteIOUtils.write(compressors.length, stream);
+    for (CompressionType[] compressionType : compressors) {
+      ReadWriteIOUtils.write(compressionType[0].ordinal(), stream);
+    }
+
+    stream.writeLong(index);
+  }
+
   @Override
   public List<PartialPath> getPaths() {
     return null;
diff --git 
a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java 
b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
index d6e72ad..8549589 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
@@ -21,11 +21,9 @@ package org.apache.iotdb.db.metadata;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
-import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
 import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
-import org.apache.iotdb.db.metadata.template.Template;
 import org.apache.iotdb.db.metadata.utils.MetaUtils;
 import org.apache.iotdb.db.qp.physical.crud.CreateTemplatePlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertPlan;
@@ -41,8 +39,6 @@ import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
 import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
-import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
-import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
 
 import org.junit.After;
 import org.junit.Assert;
@@ -60,7 +56,6 @@ import java.util.stream.Collectors;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -863,132 +858,7 @@ public class MManagerBasicTest {
     }
   }
 
-  @Test
-  public void testTemplate() throws MetadataException {
-    CreateTemplatePlan plan = getCreateTemplatePlan();
-
-    MManager manager = IoTDB.metaManager;
-    manager.createSchemaTemplate(plan);
-
-    // set device template
-    SetSchemaTemplatePlan setSchemaTemplatePlan =
-        new SetSchemaTemplatePlan("template1", "root.sg1.d1");
-
-    manager.setSchemaTemplate(setSchemaTemplatePlan);
-
-    IMNode node = manager.getDeviceNode(new PartialPath("root.sg1.d1"));
-    node = manager.setUsingSchemaTemplate(node);
-
-    UnaryMeasurementSchema s11 =
-        new UnaryMeasurementSchema("s11", TSDataType.INT64, TSEncoding.RLE, 
CompressionType.SNAPPY);
-    assertNotNull(node.getSchemaTemplate());
-
-    Set<IMeasurementSchema> allSchema =
-        new HashSet<>(node.getSchemaTemplate().getSchemaMap().values());
-    for (IMeasurementSchema schema :
-        manager.getAllMeasurementByDevicePath(new PartialPath("root.sg1.d1"))) 
{
-      allSchema.remove(schema);
-    }
-
-    assertTrue(allSchema.isEmpty());
-
-    IMeasurementMNode mNode = manager.getMeasurementMNode(new 
PartialPath("root.sg1.d1.s11"));
-    IMeasurementMNode mNode2 =
-        manager.getMeasurementMNode(new PartialPath("root.sg1.d1.vector.s2"));
-    assertNotNull(mNode);
-    assertEquals(mNode.getSchema(), s11);
-    assertNotNull(mNode2);
-    assertEquals(
-        mNode2.getSchema(), 
manager.getTemplate("template1").getSchemaMap().get("vector.s2"));
-
-    try {
-      manager.getMeasurementMNode(new PartialPath("root.sg1.d1.s100"));
-      fail();
-    } catch (PathNotExistException e) {
-      assertEquals("Path [root.sg1.d1.s100] does not exist", e.getMessage());
-    }
-  }
-
-  @Test
-  public void testTemplateInnerTree() {
-    CreateTemplatePlan plan = getTreeTemplatePlan();
-    Template template;
-    MManager manager = IoTDB.metaManager;
-
-    try {
-      manager.createSchemaTemplate(plan);
-      template = manager.getTemplate("treeTemplate");
-      assertEquals(4, template.getMeasurementsCount());
-      assertEquals("d1", template.getPathNodeInTemplate("d1").getName());
-      assertEquals(null, template.getPathNodeInTemplate("notExists"));
-      assertEquals("[GPS]", template.getAllAlignedPrefix().toString());
-
-      String[] alignedMeasurements = {"to.be.prefix.s1", "to.be.prefix.s2"};
-      TSDataType[] dataTypes = {TSDataType.INT32, TSDataType.INT32};
-      TSEncoding[] encodings = {TSEncoding.RLE, TSEncoding.RLE};
-      CompressionType[] compressionTypes = {CompressionType.SNAPPY, 
CompressionType.SNAPPY};
-      template.addAlignedMeasurements(alignedMeasurements, dataTypes, 
encodings, compressionTypes);
-
-      assertEquals("[GPS, to.be.prefix]", 
template.getAllAlignedPrefix().toString());
-      assertEquals("[s1, s2]", 
template.getAlignedMeasurements("to.be.prefix").toString());
-
-      template.deleteAlignedPrefix("to.be.prefix");
-
-      assertEquals("[GPS]", template.getAllAlignedPrefix().toString());
-      assertEquals(null, template.getDirectNode("prefix"));
-      assertEquals("to", template.getDirectNode("to").getName());
-
-      try {
-        template.deleteMeasurements("a.single");
-        fail();
-      } catch (IllegalPathException e) {
-        assertEquals("a.single is not a legal path, because Path does not 
exist", e.getMessage());
-      }
-      assertEquals(
-          "[d1.s1, GPS.x, to.be.prefix.s2, GPS.y, to.be.prefix.s1, s2]",
-          template.getAllMeasurementsPaths().toString());
-
-      template.deleteSeriesCascade("to");
-
-      assertEquals("[d1.s1, GPS.x, GPS.y, s2]", 
template.getAllMeasurementsPaths().toString());
-
-    } catch (MetadataException e) {
-      e.printStackTrace();
-    }
-  }
-
-  private CreateTemplatePlan getTreeTemplatePlan() {
-    /**
-     * Construct a template like: create schema template treeTemplate ( (d1.s1 
INT32 GORILLA
-     * SNAPPY), (s2 INT32 GORILLA SNAPPY), (GPS.x FLOAT RLE SNAPPY), (GPS.y 
FLOAT RLE SNAPPY), )with
-     * aligned (GPS)
-     *
-     * <p>Check aligned path whether with same prefix? Construct tree
-     */
-    List<List<String>> measurementList = new ArrayList<>();
-    measurementList.add(Collections.singletonList("d1.s1"));
-    measurementList.add(Collections.singletonList("s2"));
-    measurementList.add(Arrays.asList("GPS.x", "GPS.y"));
-
-    List<List<TSDataType>> dataTypeList = new ArrayList<>();
-    dataTypeList.add(Collections.singletonList(TSDataType.INT32));
-    dataTypeList.add(Collections.singletonList(TSDataType.INT32));
-    dataTypeList.add(Arrays.asList(TSDataType.FLOAT, TSDataType.FLOAT));
-
-    List<List<TSEncoding>> encodingList = new ArrayList<>();
-    encodingList.add(Collections.singletonList(TSEncoding.GORILLA));
-    encodingList.add(Collections.singletonList(TSEncoding.GORILLA));
-    encodingList.add(Arrays.asList(TSEncoding.RLE, TSEncoding.RLE));
-
-    List<List<CompressionType>> compressionTypes = new ArrayList<>();
-    compressionTypes.add(Collections.singletonList(CompressionType.SDT));
-    compressionTypes.add(Collections.singletonList(CompressionType.SNAPPY));
-    compressionTypes.add(Arrays.asList(CompressionType.SNAPPY, 
CompressionType.SNAPPY));
-
-    return new CreateTemplatePlan(
-        "treeTemplate", measurementList, dataTypeList, encodingList, 
compressionTypes);
-  }
-
+  @SuppressWarnings("Duplicates")
   private CreateTemplatePlan getCreateTemplatePlan() {
     List<List<String>> measurementList = new ArrayList<>();
     measurementList.add(Collections.singletonList("s11"));
diff --git 
a/server/src/test/java/org/apache/iotdb/db/metadata/TemplateTest.java 
b/server/src/test/java/org/apache/iotdb/db/metadata/TemplateTest.java
new file mode 100644
index 0000000..dd28156
--- /dev/null
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/TemplateTest.java
@@ -0,0 +1,254 @@
+/*
+ * 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.metadata;
+
+import org.apache.iotdb.db.exception.metadata.MetadataException;
+import org.apache.iotdb.db.exception.metadata.PathNotExistException;
+import org.apache.iotdb.db.metadata.mnode.IMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.template.Template;
+import org.apache.iotdb.db.qp.physical.PhysicalPlan;
+import org.apache.iotdb.db.qp.physical.crud.CreateTemplatePlan;
+import org.apache.iotdb.db.qp.physical.crud.SetSchemaTemplatePlan;
+import org.apache.iotdb.db.service.IoTDB;
+import org.apache.iotdb.db.utils.EnvironmentUtils;
+import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
+import org.apache.iotdb.tsfile.write.schema.UnaryMeasurementSchema;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class TemplateTest {
+  @Before
+  public void setUp() {
+    EnvironmentUtils.envSetUp();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    EnvironmentUtils.cleanEnv();
+  }
+
+  @Test
+  public void testTemplate() throws MetadataException {
+    CreateTemplatePlan plan = getCreateTemplatePlan();
+
+    MManager manager = IoTDB.metaManager;
+    manager.createSchemaTemplate(plan);
+
+    // set device template
+    SetSchemaTemplatePlan setSchemaTemplatePlan =
+        new SetSchemaTemplatePlan("template1", "root.sg1.d1");
+
+    manager.setSchemaTemplate(setSchemaTemplatePlan);
+
+    IMNode node = manager.getDeviceNode(new PartialPath("root.sg1.d1"));
+    node = manager.setUsingSchemaTemplate(node);
+
+    UnaryMeasurementSchema s11 =
+        new UnaryMeasurementSchema("s11", TSDataType.INT64, TSEncoding.RLE, 
CompressionType.SNAPPY);
+    assertNotNull(node.getSchemaTemplate());
+
+    Set<IMeasurementSchema> allSchema =
+        new HashSet<>(node.getSchemaTemplate().getSchemaMap().values());
+    for (IMeasurementSchema schema :
+        manager.getAllMeasurementByDevicePath(new PartialPath("root.sg1.d1"))) 
{
+      allSchema.remove(schema);
+    }
+
+    assertTrue(allSchema.isEmpty());
+
+    IMeasurementMNode mNode = manager.getMeasurementMNode(new 
PartialPath("root.sg1.d1.s11"));
+    IMeasurementMNode mNode2 =
+        manager.getMeasurementMNode(new PartialPath("root.sg1.d1.vector.s2"));
+    assertNotNull(mNode);
+    assertEquals(mNode.getSchema(), s11);
+    assertNotNull(mNode2);
+    assertEquals(
+        mNode2.getSchema(), 
manager.getTemplate("template1").getSchemaMap().get("vector.s2"));
+
+    try {
+      manager.getMeasurementMNode(new PartialPath("root.sg1.d1.s100"));
+      fail();
+    } catch (PathNotExistException e) {
+      assertEquals("Path [root.sg1.d1.s100] does not exist", e.getMessage());
+    }
+  }
+
+  @Test
+  public void testTemplateInnerTree() {
+    CreateTemplatePlan plan = getTreeTemplatePlan();
+    Template template;
+    MManager manager = IoTDB.metaManager;
+
+    try {
+      manager.createSchemaTemplate(plan);
+      template = manager.getTemplate("treeTemplate");
+      assertEquals(4, template.getMeasurementsCount());
+      assertEquals("d1", template.getPathNodeInTemplate("d1").getName());
+      assertEquals(null, template.getPathNodeInTemplate("notExists"));
+      assertEquals("[GPS]", template.getAllAlignedPrefix().toString());
+
+      String[] alignedMeasurements = {"to.be.prefix.s1", "to.be.prefix.s2"};
+      TSDataType[] dataTypes = {TSDataType.INT32, TSDataType.INT32};
+      TSEncoding[] encodings = {TSEncoding.RLE, TSEncoding.RLE};
+      CompressionType[] compressionTypes = {CompressionType.SNAPPY, 
CompressionType.SNAPPY};
+      template.addAlignedMeasurements(alignedMeasurements, dataTypes, 
encodings, compressionTypes);
+
+      assertEquals("[GPS, to.be.prefix]", 
template.getAllAlignedPrefix().toString());
+      assertEquals("[s1, s2]", 
template.getAlignedMeasurements("to.be.prefix").toString());
+
+      template.deleteAlignedPrefix("to.be.prefix");
+
+      assertEquals("[GPS]", template.getAllAlignedPrefix().toString());
+      assertEquals(null, template.getDirectNode("prefix"));
+      assertEquals("to", template.getDirectNode("to").getName());
+
+      try {
+        template.deleteMeasurements("a.single");
+        fail();
+      } catch (MetadataException e) {
+        assertEquals("Path [a.single] does not exist", e.getMessage());
+      }
+      assertEquals(
+          "[d1.s1, GPS.x, to.be.prefix.s2, GPS.y, to.be.prefix.s1, s2]",
+          template.getAllMeasurementsPaths().toString());
+
+      template.deleteSeriesCascade("to");
+
+      assertEquals("[d1.s1, GPS.x, GPS.y, s2]", 
template.getAllMeasurementsPaths().toString());
+
+    } catch (MetadataException e) {
+      e.printStackTrace();
+    }
+  }
+
+  @Test
+  public void testCreateSchemaTemplateSerialization() throws IOException {
+    CreateTemplatePlan plan = getTreeTemplatePlan();
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    DataOutputStream dos = new DataOutputStream(baos);
+    plan.serialize(dos);
+    byte[] byteArray = baos.toByteArray();
+    ByteBuffer buffer = ByteBuffer.wrap(byteArray);
+
+    assertEquals(PhysicalPlan.PhysicalPlanType.CREATE_TEMPLATE.ordinal(), 
buffer.get());
+
+    CreateTemplatePlan deserializedPlan = new CreateTemplatePlan();
+    deserializedPlan.deserialize(buffer);
+
+    assertEquals(
+        plan.getCompressors().get(0).get(0), 
deserializedPlan.getCompressors().get(0).get(0));
+    assertEquals(plan.getMeasurements().size(), 
deserializedPlan.getMeasurements().size());
+    assertEquals(plan.getName(), deserializedPlan.getName());
+  }
+
+  private CreateTemplatePlan getTreeTemplatePlan() {
+    /**
+     * Construct a template like: create schema template treeTemplate ( (d1.s1 
INT32 GORILLA
+     * SNAPPY), (s2 INT32 GORILLA SNAPPY), (GPS.x FLOAT RLE SNAPPY), (GPS.y 
FLOAT RLE SNAPPY), )with
+     * aligned (GPS)
+     *
+     * <p>Check aligned path whether with same prefix? Construct tree
+     */
+    List<List<String>> measurementList = new ArrayList<>();
+    measurementList.add(Collections.singletonList("d1.s1"));
+    measurementList.add(Collections.singletonList("s2"));
+    measurementList.add(Arrays.asList("GPS.x", "GPS.y"));
+
+    List<List<TSDataType>> dataTypeList = new ArrayList<>();
+    dataTypeList.add(Collections.singletonList(TSDataType.INT32));
+    dataTypeList.add(Collections.singletonList(TSDataType.INT32));
+    dataTypeList.add(Arrays.asList(TSDataType.FLOAT, TSDataType.FLOAT));
+
+    List<List<TSEncoding>> encodingList = new ArrayList<>();
+    encodingList.add(Collections.singletonList(TSEncoding.GORILLA));
+    encodingList.add(Collections.singletonList(TSEncoding.GORILLA));
+    encodingList.add(Arrays.asList(TSEncoding.RLE, TSEncoding.RLE));
+
+    List<List<CompressionType>> compressionTypes = new ArrayList<>();
+    compressionTypes.add(Collections.singletonList(CompressionType.SDT));
+    compressionTypes.add(Collections.singletonList(CompressionType.SNAPPY));
+    compressionTypes.add(Arrays.asList(CompressionType.SNAPPY, 
CompressionType.SNAPPY));
+
+    return new CreateTemplatePlan(
+        "treeTemplate", measurementList, dataTypeList, encodingList, 
compressionTypes);
+  }
+
+  private CreateTemplatePlan getCreateTemplatePlan() {
+    List<List<String>> measurementList = new ArrayList<>();
+    measurementList.add(Collections.singletonList("s11"));
+    List<String> measurements = new ArrayList<>();
+    for (int i = 0; i < 10; i++) {
+      measurements.add("vector.s" + i);
+    }
+    measurementList.add(measurements);
+
+    List<List<TSDataType>> dataTypeList = new ArrayList<>();
+    dataTypeList.add(Collections.singletonList(TSDataType.INT64));
+    List<TSDataType> dataTypes = new ArrayList<>();
+    for (int i = 0; i < 10; i++) {
+      dataTypes.add(TSDataType.INT64);
+    }
+    dataTypeList.add(dataTypes);
+
+    List<List<TSEncoding>> encodingList = new ArrayList<>();
+    encodingList.add(Collections.singletonList(TSEncoding.RLE));
+    List<TSEncoding> encodings = new ArrayList<>();
+    for (int i = 0; i < 10; i++) {
+      encodings.add(TSEncoding.RLE);
+    }
+    encodingList.add(encodings);
+
+    List<List<CompressionType>> compressionTypes = new ArrayList<>();
+    List<CompressionType> compressorList = new ArrayList<>();
+    for (int i = 0; i < 10; i++) {
+      compressorList.add(CompressionType.SNAPPY);
+    }
+    compressionTypes.add(Collections.singletonList(CompressionType.SNAPPY));
+    compressionTypes.add(compressorList);
+
+    List<String> schemaNames = new ArrayList<>();
+    schemaNames.add("s21");
+    schemaNames.add("vector");
+
+    return new CreateTemplatePlan(
+        "template1", schemaNames, measurementList, dataTypeList, encodingList, 
compressionTypes);
+  }
+}
diff --git 
a/server/src/test/java/org/apache/iotdb/db/metadata/mlog/MLogUpgraderTest.java 
b/server/src/test/java/org/apache/iotdb/db/metadata/mlog/MLogUpgraderTest.java
index dee2721..e0b59c9 100644
--- 
a/server/src/test/java/org/apache/iotdb/db/metadata/mlog/MLogUpgraderTest.java
+++ 
b/server/src/test/java/org/apache/iotdb/db/metadata/mlog/MLogUpgraderTest.java
@@ -26,6 +26,8 @@ import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.logfile.MLogTxtWriter;
 import org.apache.iotdb.db.metadata.logfile.MLogUpgrader;
 import org.apache.iotdb.db.metadata.tag.TagLogFile;
+import org.apache.iotdb.db.qp.physical.PhysicalPlan;
+import org.apache.iotdb.db.qp.physical.crud.CreateTemplatePlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan;
 import org.apache.iotdb.db.query.dataset.ShowTimeSeriesResult;
@@ -40,11 +42,19 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
 import java.io.File;
 import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
+import static org.junit.Assert.assertEquals;
+
 public class MLogUpgraderTest {
 
   @Before
@@ -101,4 +111,66 @@ public class MLogUpgraderTest {
     Assert.assertEquals(tags, result.getTag());
     Assert.assertEquals(attributes, result.getAttribute());
   }
+
+  @Test
+  public void testCreateSchemaTemplateSerializationAdaptation() throws 
IOException {
+    CreateTemplatePlan plan = getCreateTemplatePlan();
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    DataOutputStream dos = new DataOutputStream(baos);
+    plan.formerSerialize(dos);
+    byte[] byteArray = baos.toByteArray();
+    ByteBuffer buffer = ByteBuffer.wrap(byteArray);
+
+    assertEquals(PhysicalPlan.PhysicalPlanType.CREATE_TEMPLATE.ordinal(), 
buffer.get());
+
+    CreateTemplatePlan deserializedPlan = new CreateTemplatePlan();
+    deserializedPlan.deserialize(buffer);
+
+    assertEquals(plan.getCompressors().size(), 
deserializedPlan.getCompressors().size());
+    assertEquals(
+        plan.getMeasurements().get(0).get(0), 
deserializedPlan.getMeasurements().get(0).get(0));
+    assertEquals(plan.getDataTypes().size(), 
deserializedPlan.getDataTypes().size());
+  }
+
+  @SuppressWarnings("Duplicates")
+  private CreateTemplatePlan getCreateTemplatePlan() {
+    List<List<String>> measurementList = new ArrayList<>();
+    measurementList.add(Collections.singletonList("s11"));
+    List<String> measurements = new ArrayList<>();
+    for (int i = 0; i < 10; i++) {
+      measurements.add("vector.s" + i);
+    }
+    measurementList.add(measurements);
+
+    List<List<TSDataType>> dataTypeList = new ArrayList<>();
+    dataTypeList.add(Collections.singletonList(TSDataType.INT64));
+    List<TSDataType> dataTypes = new ArrayList<>();
+    for (int i = 0; i < 10; i++) {
+      dataTypes.add(TSDataType.INT64);
+    }
+    dataTypeList.add(dataTypes);
+
+    List<List<TSEncoding>> encodingList = new ArrayList<>();
+    encodingList.add(Collections.singletonList(TSEncoding.RLE));
+    List<TSEncoding> encodings = new ArrayList<>();
+    for (int i = 0; i < 10; i++) {
+      encodings.add(TSEncoding.RLE);
+    }
+    encodingList.add(encodings);
+
+    List<List<CompressionType>> compressionTypes = new ArrayList<>();
+    List<CompressionType> compressorList = new ArrayList<>();
+    for (int i = 0; i < 10; i++) {
+      compressorList.add(CompressionType.SNAPPY);
+    }
+    compressionTypes.add(Collections.singletonList(CompressionType.SNAPPY));
+    compressionTypes.add(compressorList);
+
+    List<String> schemaNames = new ArrayList<>();
+    schemaNames.add("s21");
+    schemaNames.add("vector");
+
+    return new CreateTemplatePlan(
+        "template1", schemaNames, measurementList, dataTypeList, encodingList, 
compressionTypes);
+  }
 }

Reply via email to