[IOTDB-1511] Implement EntityMNode (#3650)
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 b1c33ee..472c347 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
@@ -452,6 +452,9 @@
plan.getProps(),
plan.getAlias());
+ // the cached mNode may be replaced by new entityMNode in mtree
+ mNodeCache.removeObject(path.getDevicePath());
+
// update tag index
if (plan.getTags() != null) {
// tag key, tag value
@@ -554,6 +557,9 @@
mtree.createAlignedTimeseries(
prefixPath, measurements, plan.getDataTypes(), plan.getEncodings(), plan.getCompressor());
+ // the cached mNode may be replaced by new entityMNode in mtree
+ mNodeCache.removeObject(prefixPath.getDevicePath());
+
// update statistics and schemaDataTypeNumMap
totalSeriesNumber.addAndGet(measurements.size());
if (totalSeriesNumber.get() * ESTIMATED_SERIES_SIZE >= MTREE_SIZE_THRESHOLD) {
@@ -588,7 +594,7 @@
// for not support deleting part of aligned timeseies
// should be removed after partial deletion is supported
IMNode lastNode = getNodeByPath(allTimeseries.get(0));
- if (lastNode instanceof MeasurementMNode) {
+ if (lastNode.isMeasurement()) {
IMeasurementSchema schema = ((IMeasurementMNode) lastNode).getSchema();
if (schema instanceof VectorMeasurementSchema) {
if (schema.getValueMeasurementIdList().size() != allTimeseries.size()) {
@@ -1246,14 +1252,14 @@
}
}
node = mtree.getDeviceNodeWithAutoCreating(path, sgLevel);
- if (!(node.left instanceof StorageGroupMNode)) {
+ if (!(node.left.isStorageGroup())) {
logWriter.autoCreateDeviceMNode(new AutoCreateDeviceMNodePlan(node.left.getPartialPath()));
}
return node;
} catch (StorageGroupAlreadySetException e) {
// ignore set storage group concurrently
node = mtree.getDeviceNodeWithAutoCreating(path, sgLevel);
- if (!(node.left instanceof StorageGroupMNode)) {
+ if (!(node.left.isStorageGroup())) {
logWriter.autoCreateDeviceMNode(new AutoCreateDeviceMNodePlan(node.left.getPartialPath()));
}
return node;
@@ -1389,7 +1395,7 @@
PartialPath fullPath)
throws MetadataException, IOException {
IMNode IMNode = mtree.getNodeByPath(fullPath);
- if (!(IMNode instanceof MeasurementMNode)) {
+ if (!(IMNode.isMeasurement())) {
throw new PathNotExistException(fullPath.getFullPath());
}
IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
@@ -1439,7 +1445,7 @@
public void addAttributes(Map<String, String> attributesMap, PartialPath fullPath)
throws MetadataException, IOException {
IMNode IMNode = mtree.getNodeByPath(fullPath);
- if (!(IMNode instanceof MeasurementMNode)) {
+ if (!(IMNode.isMeasurement())) {
throw new PathNotExistException(fullPath.getFullPath());
}
IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
@@ -1463,7 +1469,7 @@
public void addTags(Map<String, String> tagsMap, PartialPath fullPath)
throws MetadataException, IOException {
IMNode IMNode = mtree.getNodeByPath(fullPath);
- if (!(IMNode instanceof MeasurementMNode)) {
+ if (!(IMNode.isMeasurement())) {
throw new PathNotExistException(fullPath.getFullPath());
}
IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
@@ -1490,7 +1496,7 @@
public void dropTagsOrAttributes(Set<String> keySet, PartialPath fullPath)
throws MetadataException, IOException {
IMNode IMNode = mtree.getNodeByPath(fullPath);
- if (!(IMNode instanceof MeasurementMNode)) {
+ if (!(IMNode.isMeasurement())) {
throw new PathNotExistException(fullPath.getFullPath());
}
IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
@@ -1511,7 +1517,7 @@
public void setTagsOrAttributesValue(Map<String, String> alterMap, PartialPath fullPath)
throws MetadataException, IOException {
IMNode IMNode = mtree.getNodeByPath(fullPath);
- if (!(IMNode instanceof MeasurementMNode)) {
+ if (!(IMNode.isMeasurement())) {
throw new PathNotExistException(fullPath.getFullPath());
}
IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
@@ -1535,7 +1541,7 @@
public void renameTagOrAttributeKey(String oldKey, String newKey, PartialPath fullPath)
throws MetadataException, IOException {
IMNode IMNode = mtree.getNodeByPath(fullPath);
- if (!(IMNode instanceof MeasurementMNode)) {
+ if (!(IMNode.isMeasurement())) {
throw new PathNotExistException(fullPath.getFullPath());
}
IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
@@ -1573,7 +1579,7 @@
nodeDeque.addLast(startingNode);
while (!nodeDeque.isEmpty()) {
IMNode node = nodeDeque.removeFirst();
- if (node instanceof MeasurementMNode) {
+ if (node.isMeasurement()) {
IMeasurementSchema nodeSchema = ((IMeasurementMNode) node).getSchema();
timeseriesSchemas.add(
new TimeseriesSchema(
@@ -1598,7 +1604,7 @@
nodeDeque.addLast(startingNode);
while (!nodeDeque.isEmpty()) {
IMNode node = nodeDeque.removeFirst();
- if (node instanceof MeasurementMNode) {
+ if (node.isMeasurement()) {
IMeasurementSchema nodeSchema = ((IMeasurementMNode) node).getSchema();
measurementSchemas.add(nodeSchema);
} else if (!node.getChildren().isEmpty()) {
@@ -1703,13 +1709,12 @@
// 1. get device node
Pair<IMNode, Template> deviceMNode = getDeviceNodeWithAutoCreate(deviceId);
- if (!(deviceMNode.left instanceof MeasurementMNode)
- && deviceMNode.left.getDeviceTemplate() != null) {
+ if (!(deviceMNode.left.isMeasurement()) && deviceMNode.left.getDeviceTemplate() != null) {
deviceMNode.right = deviceMNode.left.getDeviceTemplate();
}
// check insert non-aligned InsertPlan for aligned timeseries
- if (deviceMNode.left instanceof MeasurementMNode
+ if (deviceMNode.left.isMeasurement()
&& ((IMeasurementMNode) deviceMNode.left).getSchema() instanceof VectorMeasurementSchema
&& !plan.isAligned()) {
throw new MetadataException(
@@ -1720,7 +1725,7 @@
// check insert aligned InsertPlan for non-aligned timeseries
else if (plan.isAligned()
&& deviceMNode.left.getChild(vectorId) != null
- && !(deviceMNode.left.getChild(vectorId) instanceof MeasurementMNode)) {
+ && !(deviceMNode.left.getChild(vectorId).isMeasurement())) {
throw new MetadataException(
String.format(
"Path [%s] is not an aligned timeseries, please set InsertPlan.isAligned() = false",
@@ -1734,9 +1739,9 @@
try {
String measurement = measurementList[i];
IMNode child = getMNode(deviceMNode.left, plan.isAligned() ? vectorId : measurement);
- if (child instanceof MeasurementMNode) {
+ if (child != null && child.isMeasurement()) {
measurementMNode = (IMeasurementMNode) child;
- } else if (child instanceof StorageGroupMNode) {
+ } else if (child != null && child.isStorageGroup()) {
throw new PathAlreadyExistException(deviceId + PATH_SEPARATOR + measurement);
} else if ((measurementMNode = findTemplate(deviceMNode, measurement, vectorId)) != null) {
// empty
@@ -1748,10 +1753,14 @@
if (!plan.isAligned()) {
internalCreateTimeseries(
prefixPath.concatNode(measurement), plan.getDataTypes()[i]);
+ // after creating timeseries, the deviceMNode has been replaced by a new entityMNode
+ deviceMNode.left = mtree.getNodeByPath(deviceId);
measurementMNode = (IMeasurementMNode) deviceMNode.left.getChild(measurement);
} else {
internalAlignedCreateTimeseries(
prefixPath, Arrays.asList(measurementList), Arrays.asList(plan.getDataTypes()));
+ // after creating timeseries, the deviceMNode has been replaced by a new entityMNode
+ deviceMNode.left = mtree.getNodeByPath(deviceId);
measurementMNode = (IMeasurementMNode) deviceMNode.left.getChild(vectorId);
}
} else {
@@ -1876,7 +1885,7 @@
String schemaName = vectorId != null ? vectorId : measurement;
IMeasurementSchema schema = curTemplateMap.get(schemaName);
if (!deviceMNode.left.isUseTemplate()) {
- deviceMNode.left.setUseTemplate(true);
+ deviceMNode.left = setUsingDeviceTemplate(deviceMNode.left);
try {
logWriter.setUsingDeviceTemplate(deviceMNode.left.getPartialPath());
} catch (IOException e) {
@@ -1975,16 +1984,27 @@
private void setUsingDeviceTemplate(SetUsingDeviceTemplatePlan plan) throws MetadataException {
try {
- getDeviceNode(plan.getPrefixPath()).setUseTemplate(true);
+ setUsingDeviceTemplate(getDeviceNode(plan.getPrefixPath()));
} catch (PathNotExistException e) {
// the order of SetUsingDeviceTemplatePlan and AutoCreateDeviceMNodePlan cannot be guaranteed
// when writing concurrently, so we need a auto-create mechanism here
mtree.getDeviceNodeWithAutoCreating(
plan.getPrefixPath(), config.getDefaultStorageGroupLevel());
- getDeviceNode(plan.getPrefixPath()).setUseTemplate(true);
+ setUsingDeviceTemplate(getDeviceNode(plan.getPrefixPath()));
}
}
+ IEntityMNode setUsingDeviceTemplate(IMNode node) {
+ // this operation may change mtree structure and node type
+ // invoke mnode.setUseTemplate is invalid
+ IEntityMNode entityMNode = mtree.setToEntity(node);
+ entityMNode.setUseTemplate(true);
+ if (node != entityMNode) {
+ mNodeCache.removeObject(entityMNode.getPartialPath());
+ }
+ return entityMNode;
+ }
+
public long getTotalSeriesNumber() {
return totalSeriesNumber.get();
}
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 8fa19fa..d70a4eb 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
@@ -34,6 +34,7 @@
import org.apache.iotdb.db.metadata.MManager.StorageGroupFilter;
import org.apache.iotdb.db.metadata.logfile.MLogReader;
import org.apache.iotdb.db.metadata.logfile.MLogWriter;
+import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
@@ -290,10 +291,10 @@
Template upperTemplate = cur.getDeviceTemplate();
// e.g, path = root.sg.d1.s1, create internal nodes and set cur to d1 node
for (int i = 1; i < nodeNames.length - 1; i++) {
- if (cur instanceof MeasurementMNode) {
+ if (cur.isMeasurement()) {
throw new PathAlreadyExistException(cur.getFullPath());
}
- if (cur instanceof StorageGroupMNode) {
+ if (cur.isStorageGroup()) {
hasSetStorageGroup = true;
}
String childName = nodeNames[i];
@@ -314,7 +315,7 @@
}
}
- if (cur instanceof MeasurementMNode) {
+ if (cur.isMeasurement()) {
throw new PathAlreadyExistException(cur.getFullPath());
}
@@ -340,12 +341,14 @@
throw new AliasAlreadyExistException(path.getFullPath(), alias);
}
+ IEntityMNode entityMNode = IEntityMNode.setToEntity(cur);
+
IMeasurementMNode measurementMNode =
- new MeasurementMNode(cur, leafName, alias, dataType, encoding, compressor, props);
- cur.addChild(leafName, measurementMNode);
+ new MeasurementMNode(entityMNode, leafName, alias, dataType, encoding, compressor, props);
+ entityMNode.addChild(leafName, measurementMNode);
// link alias to LeafMNode
if (alias != null) {
- cur.addAlias(alias, measurementMNode);
+ entityMNode.addAlias(alias, measurementMNode);
}
return measurementMNode;
}
@@ -380,10 +383,10 @@
boolean hasSetStorageGroup = false;
// e.g, devicePath = root.sg.d1, create internal nodes and set cur to d1 node
for (int i = 1; i < deviceNodeNames.length - 1; i++) {
- if (cur instanceof MeasurementMNode) {
+ if (cur.isMeasurement()) {
throw new PathAlreadyExistException(cur.getFullPath());
}
- if (cur instanceof StorageGroupMNode) {
+ if (cur.isStorageGroup()) {
hasSetStorageGroup = true;
}
String nodeName = deviceNodeNames[i];
@@ -396,7 +399,7 @@
cur = cur.getChild(nodeName);
}
- if (cur instanceof MeasurementMNode) {
+ if (cur.isMeasurement()) {
throw new PathAlreadyExistException(cur.getFullPath());
}
@@ -409,12 +412,14 @@
throw new PathAlreadyExistException(devicePath.getFullPath() + "." + leafName);
}
+ IEntityMNode entityMNode = IEntityMNode.setToEntity(cur);
+
int measurementsSize = measurements.size();
// this measurementMNode could be a leaf or not.
IMeasurementMNode measurementMNode =
new MeasurementMNode(
- cur,
+ entityMNode,
leafName,
new VectorMeasurementSchema(
leafName,
@@ -423,7 +428,7 @@
encodings.toArray(new TSEncoding[measurementsSize]),
compressor),
null);
- cur.addChild(leafName, measurementMNode);
+ entityMNode.addChild(leafName, measurementMNode);
}
}
@@ -535,7 +540,7 @@
return cur.isUseTemplate() && upperTemplate.hasSchema(nodeNames[i]);
}
cur = cur.getChild(nodeNames[i]);
- if (cur instanceof MeasurementMNode) {
+ if (cur.isMeasurement()) {
if (i == nodeNames.length - 1) {
return true;
}
@@ -574,7 +579,7 @@
cur.getPartialPath().concatNode(nodeNames[i]).getFullPath());
}
cur.addChild(nodeNames[i], new InternalMNode(cur, nodeNames[i]));
- } else if (temp instanceof StorageGroupMNode) {
+ } else if (temp.isStorageGroup()) {
// before set storage group, check whether the exists or not
throw new StorageGroupAlreadySetException(temp.getFullPath());
}
@@ -588,7 +593,7 @@
synchronized (this) {
if (cur.hasChild(nodeNames[i])) {
// node b has child sg
- if (cur.getChild(nodeNames[i]) instanceof StorageGroupMNode) {
+ if (cur.getChild(nodeNames[i]).isStorageGroup()) {
throw new StorageGroupAlreadySetException(path.getFullPath());
} else {
throw new StorageGroupAlreadySetException(path.getFullPath(), true);
@@ -618,7 +623,7 @@
/** Delete a storage group */
List<IMeasurementMNode> deleteStorageGroup(PartialPath path) throws MetadataException {
IMNode cur = getNodeByPath(path);
- if (!(cur instanceof StorageGroupMNode)) {
+ if (!(cur.isStorageGroup())) {
throw new StorageGroupNotSetException(path.getFullPath());
}
// Suppose current system has root.a.b.sg1, root.a.sg2, and delete root.a.b.sg1
@@ -632,7 +637,7 @@
while (!queue.isEmpty()) {
IMNode node = queue.poll();
for (IMNode child : node.getChildren().values()) {
- if (child instanceof MeasurementMNode) {
+ if (child.isMeasurement()) {
leafMNodes.add((IMeasurementMNode) child);
} else {
queue.add(child);
@@ -667,13 +672,13 @@
int i = 1;
while (i < nodeNames.length - 1) {
cur = cur.getChild(nodeNames[i]);
- if (cur == null || cur instanceof StorageGroupMNode) {
+ if (cur == null || cur.isStorageGroup()) {
return false;
}
i++;
}
cur = cur.getChild(nodeNames[i]);
- return cur instanceof StorageGroupMNode;
+ return cur != null && cur.isStorageGroup();
}
/**
@@ -684,7 +689,7 @@
Pair<PartialPath, IMeasurementMNode> deleteTimeseriesAndReturnEmptyStorageGroup(PartialPath path)
throws MetadataException {
IMNode curNode = getNodeByPath(path);
- if (!(curNode instanceof MeasurementMNode)) {
+ if (!(curNode.isMeasurement())) {
throw new PathNotExistException(path.getFullPath());
}
String[] nodes = path.getNodes();
@@ -697,15 +702,15 @@
// delete the last node of path
curNode.getParent().deleteChild(path.getMeasurement());
if (deletedNode.getAlias() != null) {
- curNode.getParent().deleteAliasChild(((IMeasurementMNode) curNode).getAlias());
+ deletedNode.getParent().deleteAliasChild(((IMeasurementMNode) curNode).getAlias());
}
curNode = curNode.getParent();
// delete all empty ancestors except storage group and MeasurementMNode
while (!IoTDBConstant.PATH_ROOT.equals(curNode.getName())
- && !(curNode instanceof MeasurementMNode)
+ && !(curNode.isMeasurement())
&& curNode.getChildren().size() == 0) {
// if current storage group has no time series, return the storage group name
- if (curNode instanceof StorageGroupMNode) {
+ if (curNode.isStorageGroup()) {
return new Pair<>(curNode.getPartialPath(), deletedNode);
}
curNode.getParent().deleteChild(curNode.getName());
@@ -748,7 +753,7 @@
throw new PathNotExistException(path.getFullPath());
}
- if (cur instanceof StorageGroupMNode) {
+ if (cur.isStorageGroup()) {
storageGroupChecked = true;
}
}
@@ -767,7 +772,7 @@
IStorageGroupMNode getStorageGroupNodeByStorageGroupPath(PartialPath path)
throws MetadataException {
IMNode node = getNodeByPath(path);
- if (node instanceof StorageGroupMNode) {
+ if (node.isStorageGroup()) {
return (IStorageGroupMNode) node;
} else {
throw new StorageGroupNotSetException(path.getFullPath(), true);
@@ -786,11 +791,11 @@
}
IMNode cur = root;
for (int i = 1; i < nodes.length; i++) {
+ cur = cur.getChild(nodes[i]);
if (cur == null) {
break;
}
- cur = cur.getChild(nodes[i]);
- if (cur instanceof StorageGroupMNode) {
+ if (cur.isStorageGroup()) {
return (IStorageGroupMNode) cur;
}
}
@@ -811,7 +816,7 @@
Template upperTemplate = cur.getDeviceTemplate();
for (int i = 1; i < nodes.length; i++) {
- if (cur instanceof MeasurementMNode) {
+ if (cur.isMeasurement()) {
if (i == nodes.length - 1
|| ((IMeasurementMNode) cur).getSchema() instanceof VectorMeasurementSchema) {
return cur;
@@ -863,7 +868,7 @@
*/
private void findStorageGroup(
IMNode node, String[] nodes, int idx, String parent, List<String> storageGroupNames) {
- if (node instanceof StorageGroupMNode) {
+ if (node.isStorageGroup()) {
storageGroupNames.add(node.getFullPath());
return;
}
@@ -893,7 +898,7 @@
nodeStack.add(root);
while (!nodeStack.isEmpty()) {
IMNode current = nodeStack.pop();
- if (current instanceof StorageGroupMNode) {
+ if (current.isStorageGroup()) {
res.add(current.getPartialPath());
} else {
nodeStack.addAll(current.getChildren().values());
@@ -957,7 +962,7 @@
String parent,
List<PartialPath> storageGroupPaths,
boolean prefixOnly) {
- if (node instanceof StorageGroupMNode && (!prefixOnly || idx >= nodes.length)) {
+ if (node.isStorageGroup() && (!prefixOnly || idx >= nodes.length)) {
storageGroupPaths.add(node.getPartialPath());
return;
}
@@ -993,7 +998,7 @@
nodeStack.add(root);
while (!nodeStack.isEmpty()) {
IMNode current = nodeStack.pop();
- if (current instanceof StorageGroupMNode) {
+ if (current.isStorageGroup()) {
ret.add((IStorageGroupMNode) current);
} else {
nodeStack.addAll(current.getChildren().values());
@@ -1014,10 +1019,10 @@
IMNode cur = root;
for (int i = 1; i < nodes.length; i++) {
cur = cur.getChild(nodes[i]);
- if (cur instanceof StorageGroupMNode) {
- return cur.getPartialPath();
- } else if (cur == null) {
+ if (cur == null) {
throw new StorageGroupNotSetException(path.getFullPath());
+ } else if (cur.isStorageGroup()) {
+ return cur.getPartialPath();
}
}
throw new StorageGroupNotSetException(path.getFullPath());
@@ -1031,7 +1036,7 @@
cur = cur.getChild(nodes[i]);
if (cur == null) {
return false;
- } else if (cur instanceof StorageGroupMNode) {
+ } else if (cur.isStorageGroup()) {
return true;
}
}
@@ -1104,7 +1109,7 @@
/** Traverse the MTree to get the count of timeseries. */
private int getCount(IMNode node, String[] nodes, int idx, boolean wildcard)
throws PathNotExistException {
- if (node instanceof MeasurementMNode) {
+ if (node.isMeasurement()) {
if (idx < nodes.length) {
if (((IMeasurementMNode) node).getSchema().isCompatible(nodes[idx])) {
return 1;
@@ -1208,7 +1213,7 @@
if (!(PATH_WILDCARD).equals(nodeReg)) {
IMNode next = node.getChild(nodeReg);
if (next != null) {
- if (next instanceof MeasurementMNode && idx >= nodes.length && !curIsDevice) {
+ if (next.isMeasurement() && idx >= nodes.length && !curIsDevice) {
cnt++;
} else {
cnt += getDevicesCount(node.getChild(nodeReg), nodes, idx + 1);
@@ -1216,7 +1221,7 @@
}
} else {
for (IMNode child : node.getChildren().values()) {
- if (child instanceof MeasurementMNode && !curIsDevice && idx >= nodes.length) {
+ if (child.isMeasurement() && !curIsDevice && idx >= nodes.length) {
cnt++;
curIsDevice = true;
}
@@ -1229,7 +1234,7 @@
/** Traverse the MTree to get the count of storage group. */
private int getStorageGroupCount(IMNode node, String[] nodes, int idx, String parent) {
int cnt = 0;
- if (node instanceof StorageGroupMNode && idx >= nodes.length) {
+ if (node.isStorageGroup() && idx >= nodes.length) {
cnt++;
return cnt;
}
@@ -1345,7 +1350,7 @@
QueryContext queryContext,
Template upperTemplate)
throws MetadataException {
- if (node instanceof MeasurementMNode) {
+ if (node.isMeasurement()) {
if ((nodes.length <= idx
|| ((IMeasurementMNode) node).getSchema() instanceof VectorMeasurementSchema)) {
if (hasLimit) {
@@ -1742,7 +1747,7 @@
if (!nodeReg.contains(PATH_WILDCARD)) {
IMNode next = node.getChild(nodeReg);
if (next != null) {
- if (next instanceof MeasurementMNode) {
+ if (next.isMeasurement()) {
if (idx >= nodes.length) {
if (hasLimit) {
curOffset.set(curOffset.get() + 1);
@@ -1772,7 +1777,7 @@
if (!Pattern.matches(nodeReg.replace("*", ".*"), child.getName())) {
continue;
}
- if (child instanceof MeasurementMNode) {
+ if (child.isMeasurement()) {
if (!deviceAdded && idx >= nodes.length) {
if (hasLimit) {
curOffset.set(curOffset.get() + 1);
@@ -1809,9 +1814,7 @@
for (int i = 1; i < nodes.length; i++) {
if (node.getChild(nodes[i]) != null) {
node = node.getChild(nodes[i]);
- if (node instanceof StorageGroupMNode
- && filter != null
- && !filter.satisfy(node.getFullPath())) {
+ if (node.isStorageGroup() && filter != null && !filter.satisfy(node.getFullPath())) {
return res;
}
} else {
@@ -1834,9 +1837,7 @@
int targetLevel,
StorageGroupFilter filter) {
if (node == null
- || node instanceof StorageGroupMNode
- && filter != null
- && !filter.satisfy(node.getFullPath())) {
+ || node.isStorageGroup() && filter != null && !filter.satisfy(node.getFullPath())) {
return;
}
if (targetLevel == 0) {
@@ -1895,14 +1896,17 @@
ConcurrentHashMap<String, IMNode> childrenMap = new ConcurrentHashMap<>();
for (int i = 0; i < childrenSize; i++) {
IMNode child = nodeStack.removeFirst();
- child.setParent(node);
childrenMap.put(child.getName(), child);
- if (child instanceof MeasurementMNode) {
+ if (child.isMeasurement()) {
+ if (!node.isEntity()) {
+ node = IEntityMNode.setToEntity(node);
+ }
String alias = ((IMeasurementMNode) child).getAlias();
if (alias != null) {
- node.addAlias(alias, child);
+ ((IEntityMNode) node).addAlias(alias, (IMeasurementMNode) child);
}
}
+ child.setParent(node);
}
node.setChildren(childrenMap);
}
@@ -1930,13 +1934,13 @@
private JsonObject mNodeToJSON(IMNode node, String storageGroupName) {
JsonObject jsonObject = new JsonObject();
if (node.getChildren().size() > 0) {
- if (node instanceof StorageGroupMNode) {
+ if (node.isStorageGroup()) {
storageGroupName = node.getFullPath();
}
for (IMNode child : node.getChildren().values()) {
jsonObject.add(child.getName(), mNodeToJSON(child, storageGroupName));
}
- } else if (node instanceof MeasurementMNode) {
+ } else if (node.isMeasurement()) {
IMeasurementMNode leafMNode = (IMeasurementMNode) node;
jsonObject.add("DataType", GSON.toJsonTree(leafMNode.getSchema().getType()));
jsonObject.add("Encoding", GSON.toJsonTree(leafMNode.getSchema().getEncodingType()));
@@ -1991,7 +1995,7 @@
}
// this child is desired
IMNode child = entry.getValue();
- if (child instanceof StorageGroupMNode) {
+ if (child.isStorageGroup()) {
// we have found one storage group, record it
String sgName = child.getFullPath();
// concat the remaining path with the storage group name
@@ -2012,4 +2016,12 @@
}
}
}
+
+ IEntityMNode setToEntity(IMNode node) {
+ // synchronize check and replace, we need replaceChild become atomic operation
+ // only write on mtree will be synchronized
+ synchronized (this) {
+ return IEntityMNode.setToEntity(node);
+ }
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/EntityMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/EntityMNode.java
new file mode 100644
index 0000000..93c3791
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/EntityMNode.java
@@ -0,0 +1,117 @@
+/*
+ * 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.mnode;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class EntityMNode extends InternalMNode implements IEntityMNode {
+
+ /**
+ * suppress warnings reason: volatile for double synchronized check
+ *
+ * <p>This will be a ConcurrentHashMap instance
+ */
+ @SuppressWarnings("squid:S3077")
+ private transient volatile Map<String, IMeasurementMNode> aliasChildren = null;
+
+ private volatile boolean useTemplate = false;
+
+ /**
+ * Constructor of MNode.
+ *
+ * @param parent
+ * @param name
+ */
+ public EntityMNode(IMNode parent, String name) {
+ super(parent, name);
+ }
+
+ /** check whether the MNode has a child with the name */
+ @Override
+ public boolean hasChild(String name) {
+ return (children != null && children.containsKey(name))
+ || (aliasChildren != null && aliasChildren.containsKey(name));
+ }
+
+ /** get the child with the name */
+ @Override
+ public IMNode getChild(String name) {
+ IMNode child = null;
+ if (children != null) {
+ child = children.get(name);
+ }
+ if (child != null) {
+ return child;
+ }
+ return aliasChildren == null ? null : aliasChildren.get(name);
+ }
+
+ /** add an alias */
+ @Override
+ public boolean addAlias(String alias, IMeasurementMNode child) {
+ if (aliasChildren == null) {
+ // double check, alias children volatile
+ synchronized (this) {
+ if (aliasChildren == null) {
+ aliasChildren = new ConcurrentHashMap<>();
+ }
+ }
+ }
+
+ return aliasChildren.computeIfAbsent(alias, aliasName -> child) == child;
+ }
+
+ /** delete the alias of a child */
+ @Override
+ public void deleteAliasChild(String alias) {
+ if (aliasChildren != null) {
+ aliasChildren.remove(alias);
+ }
+ }
+
+ @Override
+ public Map<String, IMeasurementMNode> getAliasChildren() {
+ if (aliasChildren == null) {
+ return Collections.emptyMap();
+ }
+ return aliasChildren;
+ }
+
+ @Override
+ public void setAliasChildren(Map<String, IMeasurementMNode> aliasChildren) {
+ this.aliasChildren = aliasChildren;
+ }
+
+ @Override
+ public boolean isUseTemplate() {
+ return useTemplate;
+ }
+
+ @Override
+ public void setUseTemplate(boolean useTemplate) {
+ this.useTemplate = useTemplate;
+ }
+
+ @Override
+ public boolean isEntity() {
+ return true;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IEntityMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IEntityMNode.java
new file mode 100644
index 0000000..5b1369a
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IEntityMNode.java
@@ -0,0 +1,55 @@
+/*
+ * 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.mnode;
+
+import java.util.Map;
+
+public interface IEntityMNode extends IMNode {
+
+ boolean addAlias(String alias, IMeasurementMNode child);
+
+ void deleteAliasChild(String alias);
+
+ Map<String, IMeasurementMNode> getAliasChildren();
+
+ void setAliasChildren(Map<String, IMeasurementMNode> aliasChildren);
+
+ boolean isUseTemplate();
+
+ void setUseTemplate(boolean useTemplate);
+
+ static IEntityMNode setToEntity(IMNode node) {
+ IEntityMNode entityMNode;
+ if (node.isEntity()) {
+ entityMNode = (IEntityMNode) node;
+ } else {
+ if (node.isStorageGroup()) {
+ entityMNode =
+ new StorageGroupEntityMNode(
+ node.getParent(), node.getName(), ((StorageGroupMNode) node).getDataTTL());
+ } else {
+ entityMNode = new EntityMNode(node.getParent(), node.getName());
+ }
+ if (node.getParent() != null) {
+ node.getParent().replaceChild(node.getName(), entityMNode);
+ }
+ }
+ return entityMNode;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMNode.java
index 4b874b2..181a83c 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMNode.java
@@ -52,28 +52,18 @@
IMNode addChild(IMNode child);
- boolean addAlias(String alias, IMNode child);
-
void deleteChild(String name);
- void deleteAliasChild(String alias);
-
- void replaceChild(String measurement, IMNode newChildNode);
+ void replaceChild(String oldChildName, IMNode newChildNode);
IMNode getChildOfAlignedTimeseries(String name) throws MetadataException;
Map<String, IMNode> getChildren();
- Map<String, IMNode> getAliasChildren();
-
void setChildren(Map<String, IMNode> children);
- void setAliasChildren(Map<String, IMNode> aliasChildren);
-
boolean isUseTemplate();
- void setUseTemplate(boolean useTemplate);
-
Template getUpperTemplate();
Template getDeviceTemplate();
@@ -82,5 +72,11 @@
int getMeasurementMNodeCount();
+ boolean isStorageGroup();
+
+ boolean isEntity();
+
+ boolean isMeasurement();
+
void serializeTo(MLogWriter logWriter) throws IOException;
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMeasurementMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMeasurementMNode.java
index 904f4dd..6a4d9f0 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMeasurementMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMeasurementMNode.java
@@ -25,30 +25,34 @@
/** This interface defines a MeasurementMNode's operation interfaces. */
public interface IMeasurementMNode extends IMNode {
- int getMeasurementCount();
+
+ @Override
+ IEntityMNode getParent();
IMeasurementSchema getSchema();
+ void setSchema(IMeasurementSchema schema);
+
+ TSDataType getDataType(String measurementId);
+
+ int getMeasurementCount();
+
+ String getAlias();
+
+ void setAlias(String alias);
+
+ long getOffset();
+
+ void setOffset(long offset);
+
+ TriggerExecutor getTriggerExecutor();
+
+ void setTriggerExecutor(TriggerExecutor triggerExecutor);
+
TimeValuePair getCachedLast();
void updateCachedLast(
TimeValuePair timeValuePair, boolean highPriorityUpdate, Long latestFlushedTime);
void resetCache();
-
- long getOffset();
-
- void setOffset(long offset);
-
- String getAlias();
-
- TriggerExecutor getTriggerExecutor();
-
- void setAlias(String alias);
-
- void setSchema(IMeasurementSchema schema);
-
- void setTriggerExecutor(TriggerExecutor triggerExecutor);
-
- TSDataType getDataType(String measurementId);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IStorageGroupMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IStorageGroupMNode.java
index 131ab2c..c6d28c8 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IStorageGroupMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IStorageGroupMNode.java
@@ -20,6 +20,7 @@
/** This interface defines a StorageGroupMNode's operation interfaces. */
public interface IStorageGroupMNode extends IMNode {
+
long getDataTTL();
void setDataTTL(long dataTTL);
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/InternalMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/InternalMNode.java
index 75c6487..479e5bd 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/InternalMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/InternalMNode.java
@@ -50,19 +50,9 @@
@SuppressWarnings("squid:S3077")
protected transient volatile Map<String, IMNode> children = null;
- /**
- * suppress warnings reason: volatile for double synchronized check
- *
- * <p>This will be a ConcurrentHashMap instance
- */
- @SuppressWarnings("squid:S3077")
- private transient volatile Map<String, IMNode> aliasChildren = null;
-
// device template
protected Template deviceTemplate = null;
- private volatile boolean useTemplate = false;
-
/** Constructor of MNode. */
public InternalMNode(IMNode parent, String name) {
super(parent, name);
@@ -71,8 +61,17 @@
/** check whether the MNode has a child with the name */
@Override
public boolean hasChild(String name) {
- return (children != null && children.containsKey(name))
- || (aliasChildren != null && aliasChildren.containsKey(name));
+ return (children != null && children.containsKey(name));
+ }
+
+ /** get the child with the name */
+ @Override
+ public IMNode getChild(String name) {
+ IMNode child = null;
+ if (children != null) {
+ child = children.get(name);
+ }
+ return child;
}
/**
@@ -137,35 +136,44 @@
}
}
- /** delete the alias of a child */
+ /**
+ * replace a child of this mnode
+ *
+ * @param oldChildName measurement name
+ * @param newChildNode new child node
+ */
@Override
- public void deleteAliasChild(String alias) {
- if (aliasChildren != null) {
- aliasChildren.remove(alias);
+ public void replaceChild(String oldChildName, IMNode newChildNode) {
+ IMNode oldChildNode = this.getChild(oldChildName);
+ if (oldChildNode == null) {
+ return;
}
- }
- @Override
- public Template getDeviceTemplate() {
- return deviceTemplate;
- }
-
- @Override
- public void setDeviceTemplate(Template deviceTemplate) {
- this.deviceTemplate = deviceTemplate;
- }
-
- /** get the child with the name */
- @Override
- public IMNode getChild(String name) {
- IMNode child = null;
- if (children != null) {
- child = children.get(name);
+ // newChildNode builds parent-child relationship
+ Map<String, IMNode> grandChildren = oldChildNode.getChildren();
+ if (!grandChildren.isEmpty()) {
+ newChildNode.setChildren(grandChildren);
+ grandChildren.forEach(
+ (grandChildName, grandChildNode) -> grandChildNode.setParent(newChildNode));
}
- if (child != null) {
- return child;
+
+ if (newChildNode.isEntity() && oldChildNode.isEntity()) {
+ Map<String, IMeasurementMNode> grandAliasChildren =
+ ((IEntityMNode) oldChildNode).getAliasChildren();
+ if (!grandAliasChildren.isEmpty()) {
+ ((IEntityMNode) newChildNode).setAliasChildren(grandAliasChildren);
+ grandAliasChildren.forEach(
+ (grandAliasChildName, grandAliasChild) -> grandAliasChild.setParent(newChildNode));
+ }
+ ((IEntityMNode) newChildNode).setUseTemplate(oldChildNode.isUseTemplate());
}
- return aliasChildren == null ? null : aliasChildren.get(name);
+
+ newChildNode.setDeviceTemplate(oldChildNode.getDeviceTemplate());
+
+ newChildNode.setParent(this);
+
+ this.deleteChild(oldChildName);
+ this.addChild(newChildNode.getName(), newChildNode);
}
@Override
@@ -187,34 +195,6 @@
return node;
}
- /** get the count of all MeasurementMNode whose ancestor is current node */
- @Override
- public int getMeasurementMNodeCount() {
- if (children == null) {
- return 0;
- }
- int measurementMNodeCount = 0;
- for (IMNode child : children.values()) {
- measurementMNodeCount += child.getMeasurementMNodeCount();
- }
- return measurementMNodeCount;
- }
-
- /** add an alias */
- @Override
- public boolean addAlias(String alias, IMNode child) {
- if (aliasChildren == null) {
- // double check, alias children volatile
- synchronized (this) {
- if (aliasChildren == null) {
- aliasChildren = new ConcurrentHashMap<>();
- }
- }
- }
-
- return aliasChildren.computeIfAbsent(alias, aliasName -> child) == child;
- }
-
@Override
public Map<String, IMNode> getChildren() {
if (children == null) {
@@ -224,72 +204,10 @@
}
@Override
- public Map<String, IMNode> getAliasChildren() {
- if (aliasChildren == null) {
- return Collections.emptyMap();
- }
- return aliasChildren;
- }
-
- @Override
public void setChildren(Map<String, IMNode> children) {
this.children = children;
}
- public void setAliasChildren(Map<String, IMNode> aliasChildren) {
- this.aliasChildren = aliasChildren;
- }
-
- @Override
- public void serializeTo(MLogWriter logWriter) throws IOException {
- serializeChildren(logWriter);
-
- logWriter.serializeMNode(this);
- }
-
- void serializeChildren(MLogWriter logWriter) throws IOException {
- if (children == null) {
- return;
- }
- for (Entry<String, IMNode> entry : children.entrySet()) {
- entry.getValue().serializeTo(logWriter);
- }
- }
-
- public static InternalMNode deserializeFrom(MNodePlan plan) {
- return new InternalMNode(null, plan.getName());
- }
-
- /**
- * replace a child of this mnode
- *
- * @param measurement measurement name
- * @param newChildNode new child node
- */
- @Override
- public void replaceChild(String measurement, IMNode newChildNode) {
- IMNode oldChildNode = this.getChild(measurement);
- if (oldChildNode == null) {
- return;
- }
-
- // newChildNode builds parent-child relationship
- Map<String, IMNode> grandChildren = oldChildNode.getChildren();
- newChildNode.setChildren(grandChildren);
- grandChildren.forEach(
- (grandChildName, grandChildNode) -> grandChildNode.setParent(newChildNode));
-
- Map<String, IMNode> grandAliasChildren = oldChildNode.getAliasChildren();
- newChildNode.setAliasChildren(grandAliasChildren);
- grandAliasChildren.forEach(
- (grandAliasChildName, grandAliasChild) -> grandAliasChild.setParent(newChildNode));
-
- newChildNode.setParent(this);
-
- this.deleteChild(measurement);
- this.addChild(newChildNode.getName(), newChildNode);
- }
-
/**
* get upper template of this node, remember we get nearest template alone this node to root
*
@@ -309,12 +227,45 @@
}
@Override
- public boolean isUseTemplate() {
- return useTemplate;
+ public Template getDeviceTemplate() {
+ return deviceTemplate;
}
@Override
- public void setUseTemplate(boolean useTemplate) {
- this.useTemplate = useTemplate;
+ public void setDeviceTemplate(Template deviceTemplate) {
+ this.deviceTemplate = deviceTemplate;
+ }
+
+ /** get the count of all MeasurementMNode whose ancestor is current node */
+ @Override
+ public int getMeasurementMNodeCount() {
+ if (children == null) {
+ return 0;
+ }
+ int measurementMNodeCount = 0;
+ for (IMNode child : children.values()) {
+ measurementMNodeCount += child.getMeasurementMNodeCount();
+ }
+ return measurementMNodeCount;
+ }
+
+ @Override
+ public void serializeTo(MLogWriter logWriter) throws IOException {
+ serializeChildren(logWriter);
+
+ logWriter.serializeMNode(this);
+ }
+
+ void serializeChildren(MLogWriter logWriter) throws IOException {
+ if (children == null) {
+ return;
+ }
+ for (Entry<String, IMNode> entry : children.entrySet()) {
+ entry.getValue().serializeTo(logWriter);
+ }
+ }
+
+ public static InternalMNode deserializeFrom(MNodePlan plan) {
+ return new InternalMNode(null, plan.getName());
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MNode.java
index 4cd7df1..9a778a1 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MNode.java
@@ -114,6 +114,26 @@
}
@Override
+ public boolean isUseTemplate() {
+ return false;
+ }
+
+ @Override
+ public boolean isStorageGroup() {
+ return false;
+ }
+
+ @Override
+ public boolean isEntity() {
+ return false;
+ }
+
+ @Override
+ public boolean isMeasurement() {
+ return false;
+ }
+
+ @Override
public boolean equals(Object o) {
if (this == o) {
return true;
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
index a833307..4d2f49c 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
@@ -82,6 +82,21 @@
}
@Override
+ public IEntityMNode getParent() {
+ return (IEntityMNode) parent;
+ }
+
+ @Override
+ public IMeasurementSchema getSchema() {
+ return schema;
+ }
+
+ @Override
+ public void setSchema(IMeasurementSchema schema) {
+ this.schema = schema;
+ }
+
+ @Override
public int getMeasurementMNodeCount() {
return 1;
}
@@ -91,9 +106,50 @@
return schema.getMeasurementCount();
}
+ /**
+ * get data type
+ *
+ * @param measurementId if it's a vector schema, we need sensor name of it
+ * @return measurement data type
+ */
@Override
- public IMeasurementSchema getSchema() {
- return schema;
+ public TSDataType getDataType(String measurementId) {
+ if (schema instanceof MeasurementSchema) {
+ return schema.getType();
+ } else {
+ int index = schema.getMeasurementIdColumnIndex(measurementId);
+ return schema.getValueTSDataTypeList().get(index);
+ }
+ }
+
+ @Override
+ public long getOffset() {
+ return offset;
+ }
+
+ @Override
+ public void setOffset(long offset) {
+ this.offset = offset;
+ }
+
+ @Override
+ public String getAlias() {
+ return alias;
+ }
+
+ @Override
+ public void setAlias(String alias) {
+ this.alias = alias;
+ }
+
+ @Override
+ public TriggerExecutor getTriggerExecutor() {
+ return triggerExecutor;
+ }
+
+ @Override
+ public void setTriggerExecutor(TriggerExecutor triggerExecutor) {
+ this.triggerExecutor = triggerExecutor;
}
@Override
@@ -131,51 +187,11 @@
}
@Override
- public String getFullPath() {
- return concatFullPath();
- }
-
- @Override
public void resetCache() {
cachedLastValuePair = null;
}
@Override
- public long getOffset() {
- return offset;
- }
-
- @Override
- public void setOffset(long offset) {
- this.offset = offset;
- }
-
- @Override
- public String getAlias() {
- return alias;
- }
-
- @Override
- public TriggerExecutor getTriggerExecutor() {
- return triggerExecutor;
- }
-
- @Override
- public void setAlias(String alias) {
- this.alias = alias;
- }
-
- @Override
- public void setSchema(IMeasurementSchema schema) {
- this.schema = schema;
- }
-
- @Override
- public void setTriggerExecutor(TriggerExecutor triggerExecutor) {
- this.triggerExecutor = triggerExecutor;
- }
-
- @Override
public void serializeTo(MLogWriter logWriter) throws IOException {
logWriter.serializeMeasurementMNode(this);
}
@@ -218,20 +234,9 @@
return node;
}
- /**
- * get data type
- *
- * @param measurementId if it's a vector schema, we need sensor name of it
- * @return measurement data type
- */
@Override
- public TSDataType getDataType(String measurementId) {
- if (schema instanceof MeasurementSchema) {
- return schema.getType();
- } else {
- int index = schema.getMeasurementIdColumnIndex(measurementId);
- return schema.getValueTSDataTypeList().get(index);
- }
+ public String getFullPath() {
+ return concatFullPath();
}
@Override
@@ -240,6 +245,14 @@
}
@Override
+ public IMNode getChild(String name) {
+ logger.warn("current node {} is a MeasurementMNode, can not get child {}", super.name, name);
+ throw new RuntimeException(
+ String.format(
+ "current node %s is a MeasurementMNode, can not get child %s", super.name, name));
+ }
+
+ @Override
public void addChild(String name, IMNode child) {
// Do nothing
}
@@ -255,17 +268,7 @@
}
@Override
- public void deleteAliasChild(String alias) {
- // Do nothing
- }
-
- @Override
- public IMNode getChild(String name) {
- logger.warn("current node {} is a MeasurementMNode, can not get child {}", super.name, name);
- throw new RuntimeException(
- String.format(
- "current node %s is a MeasurementMNode, can not get child %s", super.name, name));
- }
+ public void replaceChild(String oldChildName, IMNode newChildNode) {}
@Override
public IMNode getChildOfAlignedTimeseries(String name) throws MetadataException {
@@ -273,41 +276,21 @@
}
@Override
- public boolean addAlias(String alias, IMNode child) {
- return false;
- }
-
- @Override
public Map<String, IMNode> getChildren() {
return Collections.emptyMap();
}
@Override
- public Map<String, IMNode> getAliasChildren() {
- return null;
- }
-
public void setChildren(Map<String, IMNode> children) {
// Do nothing
}
@Override
- public void setAliasChildren(Map<String, IMNode> aliasChildren) {}
-
- @Override
- public void replaceChild(String measurement, IMNode newChildNode) {}
-
- @Override
public Template getUpperTemplate() {
return parent.getUpperTemplate();
}
@Override
- public boolean isUseTemplate() {
- return false;
- }
-
- @Override
public Template getDeviceTemplate() {
logger.warn("current node {} is a MeasurementMNode, can not get Device Template", name);
throw new RuntimeException(
@@ -318,5 +301,7 @@
public void setDeviceTemplate(Template deviceTemplate) {}
@Override
- public void setUseTemplate(boolean useTemplate) {}
+ public boolean isMeasurement() {
+ return true;
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/StorageGroupEntityMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/StorageGroupEntityMNode.java
new file mode 100644
index 0000000..f5b0a9c
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/StorageGroupEntityMNode.java
@@ -0,0 +1,58 @@
+/*
+ * 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.mnode;
+
+import org.apache.iotdb.db.metadata.logfile.MLogWriter;
+
+import java.io.IOException;
+
+public class StorageGroupEntityMNode extends EntityMNode implements IStorageGroupMNode {
+ /**
+ * when the data file in a storage group is older than dataTTL, it is considered invalid and will
+ * be eventually deleted.
+ */
+ private long dataTTL;
+
+ public StorageGroupEntityMNode(IMNode parent, String name, long dataTTL) {
+ super(parent, name);
+ this.dataTTL = dataTTL;
+ }
+
+ @Override
+ public long getDataTTL() {
+ return dataTTL;
+ }
+
+ @Override
+ public void setDataTTL(long dataTTL) {
+ this.dataTTL = dataTTL;
+ }
+
+ @Override
+ public boolean isStorageGroup() {
+ return true;
+ }
+
+ @Override
+ public void serializeTo(MLogWriter logWriter) throws IOException {
+ serializeChildren(logWriter);
+
+ logWriter.serializeStorageGroupMNode(this);
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/StorageGroupMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/StorageGroupMNode.java
index 8acd920..f0622c1 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/StorageGroupMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/StorageGroupMNode.java
@@ -49,6 +49,11 @@
}
@Override
+ public boolean isStorageGroup() {
+ return true;
+ }
+
+ @Override
public void serializeTo(MLogWriter logWriter) throws IOException {
serializeChildren(logWriter);
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 74c3032..543840e 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
@@ -862,7 +862,7 @@
manager.setDeviceTemplate(setDeviceTemplatePlan);
IMNode node = manager.getDeviceNode(new PartialPath("root.sg1.d1"));
- node.setUseTemplate(true);
+ node = manager.setUsingDeviceTemplate(node);
MeasurementSchema s11 =
new MeasurementSchema("s11", TSDataType.INT64, TSEncoding.RLE, CompressionType.SNAPPY);
@@ -1264,7 +1264,7 @@
SetDeviceTemplatePlan setDeviceTemplatePlan =
new SetDeviceTemplatePlan("template1", "root.laptop.d1");
manager.setDeviceTemplate(setDeviceTemplatePlan);
- manager.getDeviceNode(new PartialPath("root.laptop.d1")).setUseTemplate(true);
+ manager.setUsingDeviceTemplate(manager.getDeviceNode(new PartialPath("root.laptop.d1")));
// show timeseries root.laptop.d1.s0
ShowTimeSeriesPlan showTimeSeriesPlan =
@@ -1357,7 +1357,7 @@
SetDeviceTemplatePlan setDeviceTemplatePlan =
new SetDeviceTemplatePlan("template1", "root.laptop.d1");
manager.setDeviceTemplate(setDeviceTemplatePlan);
- manager.getDeviceNode(new PartialPath("root.laptop.d1")).setUseTemplate(true);
+ manager.setUsingDeviceTemplate(manager.getDeviceNode(new PartialPath("root.laptop.d1")));
manager.createTimeseries(
new PartialPath("root.computer.d1.s2"),
@@ -1368,7 +1368,7 @@
setDeviceTemplatePlan = new SetDeviceTemplatePlan("template1", "root.computer");
manager.setDeviceTemplate(setDeviceTemplatePlan);
- manager.getDeviceNode(new PartialPath("root.computer.d1")).setUseTemplate(true);
+ manager.setUsingDeviceTemplate(manager.getDeviceNode(new PartialPath("root.computer.d1")));
Assert.assertEquals(2, manager.getAllTimeseriesCount(new PartialPath("root.laptop.d1")));
Assert.assertEquals(1, manager.getAllTimeseriesCount(new PartialPath("root.laptop.d1.s1")));
@@ -1423,7 +1423,7 @@
SetDeviceTemplatePlan setDeviceTemplatePlan =
new SetDeviceTemplatePlan("template1", "root.laptop.d1");
manager.setDeviceTemplate(setDeviceTemplatePlan);
- manager.getDeviceNode(new PartialPath("root.laptop.d1")).setUseTemplate(true);
+ manager.setUsingDeviceTemplate(manager.getDeviceNode(new PartialPath("root.laptop.d1")));
manager.createTimeseries(
new PartialPath("root.laptop.d2.s1"),
diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/mnode/MNodeTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/mnode/MNodeTest.java
index 7d89312..1a32b95 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/mnode/MNodeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/mnode/MNodeTest.java
@@ -47,16 +47,17 @@
// after replacing a with c, the timeseries root.a.b becomes root.c.b
InternalMNode rootNode = new InternalMNode(null, "root");
- InternalMNode aNode = new InternalMNode(rootNode, "a");
+ IEntityMNode aNode = new EntityMNode(rootNode, "a");
rootNode.addChild(aNode.getName(), aNode);
- InternalMNode bNode = new InternalMNode(aNode, "b");
+ MeasurementMNode bNode = new MeasurementMNode(aNode, "b", null, null);
+
aNode.addChild(bNode.getName(), bNode);
aNode.addAlias("aliasOfb", bNode);
for (int i = 0; i < 500; i++) {
service.submit(
- new Thread(() -> rootNode.replaceChild(aNode.getName(), new InternalMNode(null, "c"))));
+ new Thread(() -> rootNode.replaceChild(aNode.getName(), new EntityMNode(null, "c"))));
}
if (!service.isShutdown()) {