You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by qi...@apache.org on 2021/08/03 13:57:36 UTC
[iotdb] branch rel/0.12 updated: add Template Constraint (#3669)
This is an automated email from the ASF dual-hosted git repository.
qiaojialin pushed a commit to branch rel/0.12
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/rel/0.12 by this push:
new f26bc84 add Template Constraint (#3669)
f26bc84 is described below
commit f26bc847f5d190b6034bbebd8fb578920e92cf72
Author: zyk990424 <38...@users.noreply.github.com>
AuthorDate: Tue Aug 3 21:57:15 2021 +0800
add Template Constraint (#3669)
---
.../org/apache/iotdb/db/metadata/MManager.java | 33 +----
.../java/org/apache/iotdb/db/metadata/MTree.java | 36 +++++
.../iotdb/db/metadata/MManagerBasicTest.java | 160 ++++++++++-----------
3 files changed, 115 insertions(+), 114 deletions(-)
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
index b705684..9ce528a 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
@@ -2060,11 +2060,12 @@ public class MManager {
if (template == null) {
throw new UndefinedTemplateException(plan.getTemplateName());
}
-
+ PartialPath path = new PartialPath(plan.getPrefixPath());
// get mnode and update template should be atomic
synchronized (this) {
- Pair<MNode, Template> node =
- getDeviceNodeWithAutoCreate(new PartialPath(plan.getPrefixPath()));
+ mtree.checkTemplateOnPath(path);
+
+ Pair<MNode, Template> node = getDeviceNodeWithAutoCreate(path);
if (node.left.getDeviceTemplate() != null) {
if (node.left.getDeviceTemplate().equals(template)) {
@@ -2074,10 +2075,6 @@ public class MManager {
}
}
- if (!isTemplateCompatible(node.right, template)) {
- throw new MetadataException("Incompatible template");
- }
-
node.left.setDeviceTemplate(template);
}
@@ -2090,28 +2087,6 @@ public class MManager {
}
}
- public boolean isTemplateCompatible(Template upper, Template current) {
- if (upper == null) {
- return true;
- }
-
- Map<String, MeasurementSchema> upperMap = new HashMap<>(upper.getSchemaMap());
- Map<String, MeasurementSchema> currentMap = new HashMap<>(current.getSchemaMap());
-
- for (String name : currentMap.keySet()) {
- MeasurementSchema upperSchema = upperMap.remove(name);
- if (upperSchema != null) {
- MeasurementSchema currentSchema = currentMap.get(name);
- if (!upperSchema.equals(currentSchema)) {
- return false;
- }
- }
- }
-
- // current template must contains all measurements of upper template
- return upperMap.isEmpty();
- }
-
public void autoCreateDeviceMNode(AutoCreateDeviceMNodePlan plan) throws MetadataException {
mtree.getDeviceNodeWithAutoCreating(plan.getPath(), config.getDefaultStorageGroupLevel());
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
index b0ad69c..ab9629c 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
@@ -1712,4 +1712,40 @@ public class MTree implements Serializable {
}
}
}
+
+ /**
+ * check whether there is template on given path and the subTree has template return true,
+ * otherwise false
+ */
+ void checkTemplateOnPath(PartialPath path) throws MetadataException {
+ String[] nodeNames = path.getNodes();
+ MNode cur = root;
+ if (!nodeNames[0].equals(root.getName())) {
+ return;
+ }
+ if (cur.getDeviceTemplate() != null) {
+ throw new MetadataException("Template already exists on " + cur.getFullPath());
+ }
+ for (int i = 1; i < nodeNames.length; i++) {
+ if (!cur.hasChild(nodeNames[i])) {
+ return;
+ }
+ cur = cur.getChild(nodeNames[i]);
+ if (cur.getDeviceTemplate() != null) {
+ throw new MetadataException("Template already exists on " + cur.getFullPath());
+ }
+ }
+
+ checkTemplateOnSubtree(cur);
+ }
+
+ // traverse all the descendant of the given path node
+ private void checkTemplateOnSubtree(MNode node) throws MetadataException {
+ for (MNode child : node.getChildren().values()) {
+ if (child.getDeviceTemplate() != null) {
+ throw new MetadataException("Template already exists on " + child.getFullPath());
+ }
+ checkTemplateOnSubtree(child);
+ }
+ }
}
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 8be4fdc..a62c9a8 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
@@ -23,7 +23,6 @@ import org.apache.iotdb.db.exception.metadata.IllegalPathException;
import org.apache.iotdb.db.exception.metadata.MetadataException;
import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
import org.apache.iotdb.db.metadata.mnode.MNode;
-import org.apache.iotdb.db.metadata.template.Template;
import org.apache.iotdb.db.qp.physical.crud.CreateTemplatePlan;
import org.apache.iotdb.db.qp.physical.crud.SetDeviceTemplatePlan;
import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
@@ -800,7 +799,53 @@ public class MManagerBasicTest {
}
@Test
- public void testTemplateCompatibility() throws MetadataException {
+ public void testTemplateAndTimeSeriesCompatibility() throws MetadataException {
+ CreateTemplatePlan plan = getCreateTemplatePlan();
+ MManager manager = IoTDB.metaManager;
+ manager.createDeviceTemplate(plan);
+
+ // set device template
+ SetDeviceTemplatePlan setDeviceTemplatePlan =
+ new SetDeviceTemplatePlan("template1", "root.sg1.d1");
+
+ manager.setDeviceTemplate(setDeviceTemplatePlan);
+
+ CreateTimeSeriesPlan createTimeSeriesPlan =
+ new CreateTimeSeriesPlan(
+ new PartialPath("root.sg1.d1.s20"),
+ TSDataType.INT32,
+ TSEncoding.PLAIN,
+ CompressionType.GZIP,
+ null,
+ null,
+ null,
+ null);
+
+ manager.createTimeseries(createTimeSeriesPlan);
+
+ CreateTimeSeriesPlan createTimeSeriesPlan2 =
+ new CreateTimeSeriesPlan(
+ new PartialPath("root.sg1.d1.s11"),
+ TSDataType.INT32,
+ TSEncoding.PLAIN,
+ CompressionType.GZIP,
+ null,
+ null,
+ null,
+ null);
+
+ try {
+ manager.createTimeseries(createTimeSeriesPlan2);
+ fail();
+ } catch (Exception e) {
+ assertEquals(
+ "Path [root.sg1.d1.s11 ( which is incompatible with template )] already exist",
+ e.getMessage());
+ }
+ }
+
+ @Test
+ public void testSetDeviceTemplate() throws MetadataException {
List<List<String>> measurementList = new ArrayList<>();
measurementList.add(Collections.singletonList("s11"));
List<String> measurements = new ArrayList<>();
@@ -858,108 +903,53 @@ public class MManagerBasicTest {
new ArrayList<>(encodingList),
new ArrayList<>(compressionTypes));
- MManager manager = IoTDB.metaManager;
-
- assertTrue(manager.isTemplateCompatible(new Template(plan1), new Template(plan2)));
- assertFalse(manager.isTemplateCompatible(new Template(plan2), new Template(plan1)));
-
- System.out.println(measurementList);
measurementList.get(1).add("s13");
dataTypeList.get(1).add(TSDataType.INT64);
encodingList.get(1).add(TSEncoding.RLE);
- CreateTemplatePlan plan3 =
- new CreateTemplatePlan(
- "template3",
- new ArrayList<>(schemaNames),
- new ArrayList<>(measurementList),
- new ArrayList<>(dataTypeList),
- new ArrayList<>(encodingList),
- new ArrayList<>(compressionTypes));
-
- assertTrue(manager.isTemplateCompatible(new Template(plan1), new Template(plan3)));
-
- List<String> vectorList = new ArrayList<>(measurementList.get(1));
- vectorList.remove(0);
- List<TSDataType> vectorDataTypesList = new ArrayList<>(dataTypeList.get(1));
- vectorDataTypesList.remove(0);
- List<TSEncoding> vectorEncodingsList = new ArrayList<>(encodingList.get(1));
- vectorEncodingsList.remove(0);
+ SetDeviceTemplatePlan setPlan1 = new SetDeviceTemplatePlan("template1", "root.sg1");
+ SetDeviceTemplatePlan setPlan2 = new SetDeviceTemplatePlan("template2", "root.sg2.d1");
- measurementList.set(1, vectorList);
- dataTypeList.set(1, vectorDataTypesList);
- encodingList.set(1, vectorEncodingsList);
+ SetDeviceTemplatePlan setPlan3 = new SetDeviceTemplatePlan("template1", "root.sg1.d1");
+ SetDeviceTemplatePlan setPlan4 = new SetDeviceTemplatePlan("template2", "root.sg2");
- CreateTemplatePlan plan4 =
- new CreateTemplatePlan(
- "template4",
- new ArrayList<>(schemaNames),
- new ArrayList<>(measurementList),
- new ArrayList<>(dataTypeList),
- new ArrayList<>(encodingList),
- new ArrayList<>(compressionTypes));
+ SetDeviceTemplatePlan setPlan5 = new SetDeviceTemplatePlan("template2", "root.sg1.d1");
- assertFalse(manager.isTemplateCompatible(new Template(plan1), new Template(plan4)));
+ MManager manager = IoTDB.metaManager;
- // test manager
manager.createDeviceTemplate(plan1);
manager.createDeviceTemplate(plan2);
- manager.createDeviceTemplate(plan4);
- manager.setDeviceTemplate(new SetDeviceTemplatePlan("template1", "root.sg1.d1"));
+ manager.setStorageGroup(new PartialPath("root.sg1"));
+ manager.setStorageGroup(new PartialPath("root.sg2"));
+ manager.setStorageGroup(new PartialPath("root.sg3"));
+
try {
- manager.setDeviceTemplate(new SetDeviceTemplatePlan("template4", "root.sg1.d1.d2"));
- fail("These two templates are incompatible");
+ manager.setDeviceTemplate(setPlan1);
+ manager.setDeviceTemplate(setPlan2);
} catch (MetadataException e) {
- assertEquals("Incompatible template", e.getMessage());
+ fail();
}
- manager.setDeviceTemplate(new SetDeviceTemplatePlan("template2", "root.sg1.d1.d2"));
- }
-
- @Test
- public void testTemplateAndTimeSeriesCompatibility() throws MetadataException {
- CreateTemplatePlan plan = getCreateTemplatePlan();
- MManager manager = IoTDB.metaManager;
- manager.createDeviceTemplate(plan);
-
- // set device template
- SetDeviceTemplatePlan setDeviceTemplatePlan =
- new SetDeviceTemplatePlan("template1", "root.sg1.d1");
-
- manager.setDeviceTemplate(setDeviceTemplatePlan);
-
- CreateTimeSeriesPlan createTimeSeriesPlan =
- new CreateTimeSeriesPlan(
- new PartialPath("root.sg1.d1.s20"),
- TSDataType.INT32,
- TSEncoding.PLAIN,
- CompressionType.GZIP,
- null,
- null,
- null,
- null);
-
- manager.createTimeseries(createTimeSeriesPlan);
+ try {
+ manager.setDeviceTemplate(setPlan3);
+ fail();
+ } catch (MetadataException e) {
+ assertEquals("Template already exists on root.sg1", e.getMessage());
+ }
- CreateTimeSeriesPlan createTimeSeriesPlan2 =
- new CreateTimeSeriesPlan(
- new PartialPath("root.sg1.d1.s11"),
- TSDataType.INT32,
- TSEncoding.PLAIN,
- CompressionType.GZIP,
- null,
- null,
- null,
- null);
+ try {
+ manager.setDeviceTemplate(setPlan4);
+ fail();
+ } catch (MetadataException e) {
+ assertEquals("Template already exists on root.sg2.d1", e.getMessage());
+ }
try {
- manager.createTimeseries(createTimeSeriesPlan2);
+ manager.setDeviceTemplate(setPlan5);
fail();
- } catch (Exception e) {
- assertEquals(
- "Path [root.sg1.d1.s11 ( which is incompatible with template )] already exist",
- e.getMessage());
+ } catch (MetadataException e) {
+ assertEquals("Template already exists on root.sg1", e.getMessage());
}
}