You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by zy...@apache.org on 2023/01/09 07:53:12 UTC
[iotdb] branch master updated: [IOTDB-4982] Replace recursion algorithm in Traverser with iteration algorithm (#8765)
This is an automated email from the ASF dual-hosted git repository.
zyk 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 cea3c5ce21 [IOTDB-4982] Replace recursion algorithm in Traverser with iteration algorithm (#8765)
cea3c5ce21 is described below
commit cea3c5ce21515cb9a7e830f45c7409b8c97ab7e1
Author: Chen YZ <43...@users.noreply.github.com>
AuthorDate: Mon Jan 9 15:53:06 2023 +0800
[IOTDB-4982] Replace recursion algorithm in Traverser with iteration algorithm (#8765)
[IOTDB-4982] Replace recursion algorithm in Traverser with iteration algorithm (#8765)
---
.../persistence/schema/ClusterSchemaInfo.java | 14 -
.../commons/schema/tree/AbstractTreeVisitor.java | 92 ++++-
.../iotdb/commons/schema/tree/ITreeNode.java | 4 +-
.../schemaregion/rocksdb/RSchemaRegion.java | 2 +-
.../schemaregion/rocksdb/mnode/RMNode.java | 5 +
.../idtable/entry/InsertMeasurementMNode.java | 5 +
.../db/metadata/mnode/AboveDatabaseMNode.java | 20 +-
.../org/apache/iotdb/db/metadata/mnode/IMNode.java | 7 +-
.../iotdb/db/metadata/mnode/InternalMNode.java | 5 +
.../iotdb/db/metadata/mnode/MeasurementMNode.java | 5 +
.../mnode/iterator/AbstractTraverserIterator.java | 115 ++++++
.../iterator/CachedTraverserIterator.java} | 27 +-
.../iterator/MemoryTraverserIterator.java} | 22 +-
.../iotdb/db/metadata/mtree/ConfigMTree.java | 229 +++++------
.../iotdb/db/metadata/mtree/IMTreeBelowSG.java | 46 ++-
.../db/metadata/mtree/MTreeBelowSGCachedImpl.java | 315 +++++++-------
.../db/metadata/mtree/MTreeBelowSGMemoryImpl.java | 366 ++++++++++-------
.../db/metadata/mtree/store/CachedMTreeStore.java | 18 +
.../iotdb/db/metadata/mtree/store/IMTreeStore.java | 6 +
.../db/metadata/mtree/store/MemMTreeStore.java | 19 +
.../db/metadata/mtree/traverser/Traverser.java | 452 ++-------------------
.../traverser/TraverserWithLimitOffsetWrapper.java | 122 ++++++
.../DatabaseTraverser.java} | 49 ++-
.../EntityTraverser.java} | 60 ++-
.../mtree/traverser/basic/MNodeTraverser.java | 103 +++++
.../MeasurementTraverser.java} | 41 +-
.../traverser/collector/CollectorTraverser.java | 96 -----
...eGroupCollector.java => DatabaseCollector.java} | 38 +-
.../mtree/traverser/collector/EntityCollector.java | 48 +--
.../traverser/collector/MNodeAboveSGCollector.java | 25 +-
.../mtree/traverser/collector/MNodeCollector.java | 58 +--
.../traverser/collector/MeasurementCollector.java | 58 +--
.../metadata/mtree/traverser/counter/Counter.java | 8 +-
...orageGroupCounter.java => DatabaseCounter.java} | 31 +-
...StorageGroupCounter.java => EntityCounter.java} | 29 +-
.../mtree/traverser/updater/EntityUpdater.java | 65 +++
.../traverser/updater/MeasurementUpdater.java | 66 +++
.../metadata/mtree/traverser/updater/Updater.java | 11 +-
.../schemaregion/SchemaRegionMemoryImpl.java | 107 ++---
.../schemaregion/SchemaRegionSchemaFileImpl.java | 43 +-
.../visitor/SchemaTreeDeviceVisitor.java | 2 +-
.../visitor/SchemaTreeMeasurementVisitor.java | 3 +-
.../iotdb/db/metadata/mtree/ConfigMTreeTest.java | 25 --
.../schemaRegion/SchemaRegionBasicTest.java | 13 +-
.../schemaRegion/SchemaRegionTemplateTest.java | 62 +++
45 files changed, 1535 insertions(+), 1402 deletions(-)
diff --git a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
index 573e1b05a5..29c1ed7bb8 100644
--- a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
+++ b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
@@ -553,20 +553,6 @@ public class ClusterSchemaInfo implements SnapshotProcessor {
return matchedPathsInNextLevel;
}
- public Pair<Set<String>, Set<PartialPath>> getChildNodeNameInNextLevel(PartialPath partialPath) {
- Pair<Set<String>, Set<PartialPath>> matchedNamesInNextLevel =
- new Pair<>(new HashSet<>(), new HashSet<>());
- storageGroupReadWriteLock.readLock().lock();
- try {
- matchedNamesInNextLevel = mTree.getChildNodeNameInNextLevel(partialPath);
- } catch (MetadataException e) {
- LOGGER.error("Error get matched names in next level.", e);
- } finally {
- storageGroupReadWriteLock.readLock().unlock();
- }
- return matchedNamesInNextLevel;
- }
-
public TSStatus createSchemaTemplate(CreateSchemaTemplatePlan createSchemaTemplatePlan) {
try {
Template template = createSchemaTemplatePlan.getTemplate();
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/AbstractTreeVisitor.java b/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/AbstractTreeVisitor.java
index b752728af7..0255db8180 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/AbstractTreeVisitor.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/AbstractTreeVisitor.java
@@ -66,7 +66,7 @@ public abstract class AbstractTreeVisitor<N extends ITreeNode, R>
implements Iterator<R>, AutoCloseable {
// command parameters
- protected final N root;
+ protected N root;
// finite automation constructed from given path pattern or pattern tree
protected final IPatternFA patternFA;
@@ -136,14 +136,6 @@ public abstract class AbstractTreeVisitor<N extends ITreeNode, R>
ancestorStack.add(new AncestorStackEntry(root, currentStateMatchInfo));
}
- public boolean isSuccess() {
- return throwable != null;
- }
-
- public Throwable getThrowable() {
- return throwable;
- }
-
public void reset() {
close();
visitorStack.clear();
@@ -274,7 +266,16 @@ public abstract class AbstractTreeVisitor<N extends ITreeNode, R>
}
}
- protected final String[] generateFullPathNodes() {
+ /**
+ * Get full path of parent of current node. This method should be used in {@linkplain
+ * AbstractTreeVisitor#acceptInternalMatchedNode}, {@linkplain
+ * AbstractTreeVisitor#acceptFullMatchedNode},{@linkplain
+ * AbstractTreeVisitor#shouldVisitSubtreeOfInternalMatchedNode} or {@linkplain
+ * AbstractTreeVisitor#shouldVisitSubtreeOfFullMatchedNode}.
+ *
+ * @return full path from traverse start node to the parent of current node
+ */
+ protected PartialPath getParentPartialPath() {
List<String> nodeNames = new ArrayList<>();
Iterator<AncestorStackEntry> iterator = ancestorStack.iterator();
for (int i = 0, size = shouldVisitSubtree ? ancestorStack.size() - 1 : ancestorStack.size();
@@ -284,10 +285,41 @@ public abstract class AbstractTreeVisitor<N extends ITreeNode, R>
nodeNames.add(iterator.next().node.getName());
}
}
- nodeNames.add(nextMatchedNode.getName());
+ return new PartialPath(nodeNames.toArray(new String[0]));
+ }
+
+ /**
+ * Get partial path from root to node.
+ *
+ * @param node node must be concluded in ancestorStack or nextMatchedNode
+ * @return partial path from traverse start node to the specified node
+ */
+ protected final PartialPath getPartialPathFromRootToNode(N node) {
+ return new PartialPath(getFullPathFromRootToNode(node));
+ }
+
+ /**
+ * Get full path from root to node.
+ *
+ * @param node node must be concluded in ancestorStack or nextMatchedNode
+ * @return full path from traverse start node to the specified node
+ */
+ protected final String[] getFullPathFromRootToNode(N node) {
+ List<String> nodeNames = new ArrayList<>();
+ for (AncestorStackEntry entry : ancestorStack) {
+ nodeNames.add(entry.node.getName());
+ if (entry.node == node) {
+ return nodeNames.toArray(new String[0]);
+ }
+ }
+ nodeNames.add(node.getName());
return nodeNames.toArray(new String[0]);
}
+ protected final N getAncestorNodeByLevel(int level) {
+ return ancestorStack.get(level).node;
+ }
+
protected final N getParentOfNextMatchedNode() {
if (shouldVisitSubtree) {
return ancestorStack.get(ancestorStack.size() - 2).node;
@@ -296,10 +328,36 @@ public abstract class AbstractTreeVisitor<N extends ITreeNode, R>
}
}
+ /**
+ * Get level from root to NextMatchedNode. Level of root is 0. For example, root.sg.d1.s1,
+ * NextMatchedNode is s1, then return 3.
+ *
+ * @return level from root to NextMatchedNode
+ */
+ protected final int getLevelOfNextMatchedNode() {
+ if (shouldVisitSubtree) {
+ return ancestorStack.size() - 1;
+ } else {
+ return ancestorStack.size();
+ }
+ }
+
+ protected final int getSizeOfAncestor() {
+ return ancestorStack.size();
+ }
+
protected void setFailure(Throwable e) {
this.throwable = e;
}
+ protected Throwable getFailure() {
+ return throwable;
+ }
+
+ public boolean isSuccess() {
+ return throwable == null;
+ }
+
// Get a child with the given childName.
protected abstract N getChild(N parent, String childName) throws Exception;
@@ -479,7 +537,9 @@ public abstract class AbstractTreeVisitor<N extends ITreeNode, R>
@Override
protected void close() {
super.close();
- releaseNodeIterator(childrenIterator);
+ if (childrenIterator != null) {
+ releaseNodeIterator(childrenIterator);
+ }
}
}
@@ -550,7 +610,9 @@ public abstract class AbstractTreeVisitor<N extends ITreeNode, R>
@Override
protected void close() {
super.close();
- releaseNodeIterator(iterator);
+ if (iterator != null) {
+ releaseNodeIterator(iterator);
+ }
}
}
@@ -736,7 +798,9 @@ public abstract class AbstractTreeVisitor<N extends ITreeNode, R>
@Override
protected void close() {
super.close();
- releaseNodeIterator(iterator);
+ if (iterator != null) {
+ releaseNodeIterator(iterator);
+ }
}
}
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/ITreeNode.java b/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/ITreeNode.java
index 900e943fbd..71537bc303 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/ITreeNode.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/ITreeNode.java
@@ -19,7 +19,9 @@
package org.apache.iotdb.commons.schema.tree;
-public interface ITreeNode {
+import java.io.Serializable;
+
+public interface ITreeNode extends Serializable {
String getName();
}
diff --git a/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/RSchemaRegion.java b/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/RSchemaRegion.java
index 4e9f225fa6..04d55df60f 100644
--- a/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/RSchemaRegion.java
+++ b/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/RSchemaRegion.java
@@ -873,7 +873,7 @@ public class RSchemaRegion implements ISchemaRegion {
}
public List<PartialPath> getNodesListInGivenLevel(
- PartialPath pathPattern, int nodeLevel, boolean isPrefixMatch) throws MetadataException {
+ PartialPath pathPattern, int nodeLevel, boolean isPrefixMatch) {
if (pathPattern.getFullPath().contains(IoTDBConstant.ONE_LEVEL_PATH_WILDCARD)) {
throw new UnsupportedOperationException(
formatNotSupportInfo(Thread.currentThread().getStackTrace()[1].getMethodName()));
diff --git a/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/mnode/RMNode.java b/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/mnode/RMNode.java
index 749997ddd6..2dbad227c9 100644
--- a/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/mnode/RMNode.java
+++ b/schema-engine-rocksdb/src/main/java/org/apache/iotdb/db/metadata/schemaregion/rocksdb/mnode/RMNode.java
@@ -183,6 +183,11 @@ public abstract class RMNode implements IMNode {
throw new UnsupportedOperationException();
}
+ @Override
+ public boolean isAboveDatabase() {
+ return false;
+ }
+
@Override
public boolean isStorageGroup() {
return false;
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/idtable/entry/InsertMeasurementMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/idtable/entry/InsertMeasurementMNode.java
index 245eef7841..1b376d4c51 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/idtable/entry/InsertMeasurementMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/idtable/entry/InsertMeasurementMNode.java
@@ -205,6 +205,11 @@ public class InsertMeasurementMNode implements IMeasurementMNode {
throw new UnsupportedOperationException("insert measurement mnode doesn't support this method");
}
+ @Override
+ public boolean isAboveDatabase() {
+ return false;
+ }
+
@Override
public boolean isStorageGroup() {
throw new UnsupportedOperationException("insert measurement mnode doesn't support this method");
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/ITreeNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/AboveDatabaseMNode.java
similarity index 66%
copy from node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/ITreeNode.java
copy to server/src/main/java/org/apache/iotdb/db/metadata/mnode/AboveDatabaseMNode.java
index 900e943fbd..9b2251d40f 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/ITreeNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/AboveDatabaseMNode.java
@@ -16,10 +16,22 @@
* specific language governing permissions and limitations
* under the License.
*/
+package org.apache.iotdb.db.metadata.mnode;
-package org.apache.iotdb.commons.schema.tree;
+/** Used to fill the link list of MNode above database in IMTreeBelowSG */
+public class AboveDatabaseMNode extends InternalMNode {
+ /**
+ * Constructor of MNode.
+ *
+ * @param parent
+ * @param name
+ */
+ public AboveDatabaseMNode(IMNode parent, String name) {
+ super(parent, name);
+ }
-public interface ITreeNode {
-
- String getName();
+ @Override
+ public boolean isAboveDatabase() {
+ return true;
+ }
}
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 847d5d8bc7..b7b2e452e8 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
@@ -19,14 +19,13 @@
package org.apache.iotdb.db.metadata.mnode;
import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.schema.tree.ITreeNode;
import org.apache.iotdb.db.metadata.mnode.container.IMNodeContainer;
import org.apache.iotdb.db.metadata.mnode.visitor.MNodeVisitor;
import org.apache.iotdb.db.metadata.mtree.store.disk.cache.CacheEntry;
-import java.io.Serializable;
-
/** This interface defines a MNode's operation interfaces. */
-public interface IMNode extends Serializable {
+public interface IMNode extends ITreeNode {
String getName();
@@ -83,6 +82,8 @@ public interface IMNode extends Serializable {
void unsetSchemaTemplate();
+ boolean isAboveDatabase();
+
boolean isStorageGroup();
boolean isEntity();
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 11c501fe1f..47e95f0b9c 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
@@ -232,6 +232,11 @@ public class InternalMNode extends MNode {
this.schemaTemplateId = -1;
}
+ @Override
+ public boolean isAboveDatabase() {
+ return false;
+ }
+
@Override
public MNodeType getMNodeType(Boolean isConfig) {
return isConfig ? MNodeType.SG_INTERNAL : MNodeType.INTERNAL;
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 4ecf573fb8..2151a170c0 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
@@ -213,6 +213,11 @@ public class MeasurementMNode extends MNode implements IMeasurementMNode {
@Override
public void unsetSchemaTemplate() {}
+ @Override
+ public boolean isAboveDatabase() {
+ return false;
+ }
+
@Override
public void setUseTemplate(boolean useTemplate) {}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/iterator/AbstractTraverserIterator.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/iterator/AbstractTraverserIterator.java
new file mode 100644
index 0000000000..821c901de5
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/iterator/AbstractTraverserIterator.java
@@ -0,0 +1,115 @@
+/*
+ * 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.iterator;
+
+import org.apache.iotdb.commons.exception.MetadataException;
+import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
+import org.apache.iotdb.db.metadata.mnode.IMNode;
+import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
+import org.apache.iotdb.db.metadata.template.Template;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import static org.apache.iotdb.db.metadata.MetadataConstant.NON_TEMPLATE;
+
+/**
+ * TraverserIterator for traversing device node. The iterator returns the filtered child nodes in
+ * the mtree and the child nodes in the template.
+ */
+public abstract class AbstractTraverserIterator implements IMNodeIterator {
+ private final IMNodeIterator directChildrenIterator;
+ private Iterator<IMNode> templateChildrenIterator;
+ protected IMNode nextMatchedNode;
+ protected boolean usingDirectChildrenIterator = true;
+ // if true, the pre deleted measurement or pre deactivated template won't be processed
+ private boolean skipPreDeletedSchema = false;
+
+ protected AbstractTraverserIterator(
+ IMTreeStore store, IEntityMNode parent, Map<Integer, Template> templateMap)
+ throws MetadataException {
+ this.directChildrenIterator = store.getChildrenIterator(parent);
+ if (templateMap != null && parent.isUseTemplate()) {
+ Template template = getActivatedSchemaTemplate(parent, templateMap);
+ if (template != null) {
+ templateChildrenIterator = template.getDirectNodes().iterator();
+ }
+ }
+ }
+
+ public void setSkipPreDeletedSchema(boolean skipPreDeletedSchema) {
+ this.skipPreDeletedSchema = skipPreDeletedSchema;
+ }
+
+ private Template getActivatedSchemaTemplate(
+ IEntityMNode node, Map<Integer, Template> templateMap) {
+ // new cluster, the used template is directly recorded as template id in device mnode
+ if (node.getSchemaTemplateId() != NON_TEMPLATE) {
+ if (skipPreDeletedSchema && node.getAsEntityMNode().isPreDeactivateTemplate()) {
+ // skip this pre deactivated template, the invoker will skip this
+ return null;
+ }
+ return templateMap.get(node.getSchemaTemplateId());
+ }
+ // if the node is usingTemplate, the upperTemplate won't be null or the upperTemplateId won't be
+ // NON_TEMPLATE.
+ throw new IllegalStateException(
+ String.format(
+ "There should be a template mounted on any ancestor of the node [%s] usingTemplate.",
+ node.getFullPath()));
+ }
+
+ @Override
+ public boolean hasNext() {
+ while (nextMatchedNode == null) {
+ if (directChildrenIterator.hasNext()) {
+ nextMatchedNode = directChildrenIterator.next();
+ usingDirectChildrenIterator = true;
+ } else if (templateChildrenIterator != null && templateChildrenIterator.hasNext()) {
+ nextMatchedNode = templateChildrenIterator.next();
+ usingDirectChildrenIterator = false;
+ } else {
+ return false;
+ }
+ if (skipPreDeletedSchema
+ && nextMatchedNode.isMeasurement()
+ && nextMatchedNode.getAsMeasurementMNode().isPreDeleted()) {
+ nextMatchedNode = null;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public IMNode next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ IMNode result = nextMatchedNode;
+ nextMatchedNode = null;
+ return result;
+ }
+
+ @Override
+ public void close() {
+ directChildrenIterator.close();
+ templateChildrenIterator = null;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/CounterTraverser.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/iterator/CachedTraverserIterator.java
similarity index 60%
copy from server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/CounterTraverser.java
copy to server/src/main/java/org/apache/iotdb/db/metadata/mnode/iterator/CachedTraverserIterator.java
index b1312cfb58..501f748315 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/CounterTraverser.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/iterator/CachedTraverserIterator.java
@@ -16,25 +16,30 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.iotdb.db.metadata.mtree.traverser.counter;
+package org.apache.iotdb.db.metadata.mnode.iterator;
import org.apache.iotdb.commons.exception.MetadataException;
-import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.IMNode;
+import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
-import org.apache.iotdb.db.metadata.mtree.traverser.Traverser;
+import org.apache.iotdb.db.metadata.template.Template;
-// This class define the count as traversal result.
-public abstract class CounterTraverser extends Traverser {
+import java.util.Map;
- protected long count;
+public class CachedTraverserIterator extends AbstractTraverserIterator {
+ private final IMTreeStore store;
- protected CounterTraverser(IMNode startNode, PartialPath path, IMTreeStore store)
+ public CachedTraverserIterator(
+ IMTreeStore store, IEntityMNode parent, Map<Integer, Template> templateMap)
throws MetadataException {
- super(startNode, path, store);
+ super(store, parent, templateMap);
+ this.store = store;
}
- public long getCount() {
- return count;
+ @Override
+ public void close() {
+ if (nextMatchedNode != null && usingDirectChildrenIterator) {
+ store.unPin(nextMatchedNode);
+ }
+ super.close();
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/CounterTraverser.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/iterator/MemoryTraverserIterator.java
similarity index 64%
copy from server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/CounterTraverser.java
copy to server/src/main/java/org/apache/iotdb/db/metadata/mnode/iterator/MemoryTraverserIterator.java
index b1312cfb58..9a8d9be7bc 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/CounterTraverser.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/iterator/MemoryTraverserIterator.java
@@ -16,25 +16,19 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.iotdb.db.metadata.mtree.traverser.counter;
+package org.apache.iotdb.db.metadata.mnode.iterator;
import org.apache.iotdb.commons.exception.MetadataException;
-import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.IMNode;
+import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
-import org.apache.iotdb.db.metadata.mtree.traverser.Traverser;
+import org.apache.iotdb.db.metadata.template.Template;
-// This class define the count as traversal result.
-public abstract class CounterTraverser extends Traverser {
+import java.util.Map;
- protected long count;
-
- protected CounterTraverser(IMNode startNode, PartialPath path, IMTreeStore store)
+public class MemoryTraverserIterator extends AbstractTraverserIterator {
+ public MemoryTraverserIterator(
+ IMTreeStore store, IEntityMNode parent, Map<Integer, Template> templateMap)
throws MetadataException {
- super(startNode, path, store);
- }
-
- public long getCount() {
- return count;
+ super(store, parent, templateMap);
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/ConfigMTree.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/ConfigMTree.java
index 98830a2ac6..fd43420803 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/ConfigMTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/ConfigMTree.java
@@ -34,11 +34,10 @@ import org.apache.iotdb.db.metadata.mnode.InternalMNode;
import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
import org.apache.iotdb.db.metadata.mnode.iterator.IMNodeIterator;
import org.apache.iotdb.db.metadata.mtree.store.MemMTreeStore;
-import org.apache.iotdb.db.metadata.mtree.traverser.collector.CollectorTraverser;
+import org.apache.iotdb.db.metadata.mtree.traverser.collector.DatabaseCollector;
import org.apache.iotdb.db.metadata.mtree.traverser.collector.MNodeAboveSGCollector;
-import org.apache.iotdb.db.metadata.mtree.traverser.collector.StorageGroupCollector;
-import org.apache.iotdb.db.metadata.mtree.traverser.counter.CounterTraverser;
-import org.apache.iotdb.db.metadata.mtree.traverser.counter.StorageGroupCounter;
+import org.apache.iotdb.db.metadata.mtree.traverser.collector.MNodeCollector;
+import org.apache.iotdb.db.metadata.mtree.traverser.counter.DatabaseCounter;
import org.apache.iotdb.db.metadata.utils.MetaFormatUtils;
import org.apache.iotdb.tsfile.utils.Pair;
import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils;
@@ -212,16 +211,16 @@ public class ConfigMTree {
PartialPath pathPattern, boolean isPrefixMatch, boolean collectInternal)
throws MetadataException {
List<PartialPath> result = new LinkedList<>();
- StorageGroupCollector<List<PartialPath>> collector =
- new StorageGroupCollector<List<PartialPath>>(root, pathPattern, store) {
+ try (DatabaseCollector<List<PartialPath>> collector =
+ new DatabaseCollector<List<PartialPath>>(root, pathPattern, store, isPrefixMatch) {
@Override
- protected void collectStorageGroup(IStorageGroupMNode node) {
+ protected void collectDatabase(IStorageGroupMNode node) {
result.add(node.getPartialPath());
}
- };
- collector.setCollectInternal(collectInternal);
- collector.setPrefixMatch(isPrefixMatch);
- collector.traverse();
+ }) {
+ collector.setCollectInternal(collectInternal);
+ collector.traverse();
+ }
return result;
}
@@ -254,10 +253,9 @@ public class ConfigMTree {
*/
public int getStorageGroupNum(PartialPath pathPattern, boolean isPrefixMatch)
throws MetadataException {
- CounterTraverser counter = new StorageGroupCounter(root, pathPattern, store);
- counter.setPrefixMatch(isPrefixMatch);
- counter.traverse();
- return (int) counter.getCount();
+ try (DatabaseCounter counter = new DatabaseCounter(root, pathPattern, store, isPrefixMatch)) {
+ return (int) counter.count();
+ }
}
/**
@@ -394,19 +392,20 @@ public class ConfigMTree {
*/
public Pair<List<PartialPath>, Set<PartialPath>> getNodesListInGivenLevel(
PartialPath pathPattern, int nodeLevel, boolean isPrefixMatch) throws MetadataException {
- MNodeAboveSGCollector<List<PartialPath>> collector =
- new MNodeAboveSGCollector<List<PartialPath>>(root, pathPattern, store) {
+ List<PartialPath> result = new LinkedList<>();
+ try (MNodeAboveSGCollector<?> collector =
+ new MNodeAboveSGCollector<Void>(root, pathPattern, store, isPrefixMatch) {
@Override
- protected void transferToResult(IMNode node) {
- resultSet.add(getCurrentPartialPath(node));
+ protected Void collectMNode(IMNode node) {
+ result.add(getPartialPathFromRootToNode(node));
+ return null;
}
- };
- collector.setResultSet(new LinkedList<>());
- collector.setTargetLevel(nodeLevel);
- collector.setPrefixMatch(isPrefixMatch);
- collector.traverse();
+ }) {
- return new Pair<>(collector.getResult(), collector.getInvolvedStorageGroupMNodes());
+ collector.setTargetLevel(nodeLevel);
+ collector.traverse();
+ return new Pair<>(result, collector.getInvolvedStorageGroupMNodes());
+ }
}
/**
@@ -424,55 +423,21 @@ public class ConfigMTree {
*/
public Pair<Set<TSchemaNode>, Set<PartialPath>> getChildNodePathInNextLevel(
PartialPath pathPattern) throws MetadataException {
- try {
- MNodeAboveSGCollector<Set<TSchemaNode>> collector =
- new MNodeAboveSGCollector<Set<TSchemaNode>>(
- root, pathPattern.concatNode(ONE_LEVEL_PATH_WILDCARD), store) {
- @Override
- protected void transferToResult(IMNode node) {
- resultSet.add(
- new TSchemaNode(
- getCurrentPartialPath(node).getFullPath(),
- node.getMNodeType(true).getNodeType()));
- }
- };
- collector.setResultSet(new TreeSet<>());
- collector.traverse();
-
- return new Pair<>(collector.getResult(), collector.getInvolvedStorageGroupMNodes());
- } catch (IllegalPathException e) {
- throw new IllegalPathException(pathPattern.getFullPath());
- }
- }
-
- /**
- * Get child node path in the next level of the given path pattern. This method only count in
- * nodes above database. Nodes below database, including database node will be counted by certain
- * MTreeBelowSG.
- *
- * <p>give pathPattern and the child nodes is those matching pathPattern.*
- *
- * <p>e.g., MTree has [root.a.sg1.d1.s1, root.b.sg1.d1.s2, root.c.sg1.d2.s1] given path = root
- * return [a, b]
- *
- * @param pathPattern The given path
- * @return All child nodes' seriesPath(s) of given seriesPath.
- */
- public Pair<Set<String>, Set<PartialPath>> getChildNodeNameInNextLevel(PartialPath pathPattern)
- throws MetadataException {
- try {
- MNodeAboveSGCollector<Set<String>> collector =
- new MNodeAboveSGCollector<Set<String>>(
- root, pathPattern.concatNode(ONE_LEVEL_PATH_WILDCARD), store) {
- @Override
- protected void transferToResult(IMNode node) {
- resultSet.add(node.getName());
- }
- };
- collector.setResultSet(new TreeSet<>());
+ Set<TSchemaNode> result = new TreeSet<>();
+ try (MNodeAboveSGCollector<?> collector =
+ new MNodeAboveSGCollector<Void>(
+ root, pathPattern.concatNode(ONE_LEVEL_PATH_WILDCARD), store, false) {
+ @Override
+ protected Void collectMNode(IMNode node) {
+ result.add(
+ new TSchemaNode(
+ getPartialPathFromRootToNode(node).getFullPath(),
+ node.getMNodeType(true).getNodeType()));
+ return null;
+ }
+ }) {
collector.traverse();
-
- return new Pair<>(collector.getResult(), collector.getInvolvedStorageGroupMNodes());
+ return new Pair<>(result, collector.getInvolvedStorageGroupMNodes());
} catch (IllegalPathException e) {
throw new IllegalPathException(pathPattern.getFullPath());
}
@@ -535,39 +500,46 @@ public class ConfigMTree {
public List<String> getPathsSetOnTemplate(int templateId, boolean filterPreUnset)
throws MetadataException {
List<String> resSet = new ArrayList<>();
- CollectorTraverser<Set<String>> setTemplatePaths =
- new CollectorTraverser<Set<String>>(root, new PartialPath(ALL_RESULT_NODES), store) {
+ try (MNodeCollector<?> collector =
+ new MNodeCollector<Void>(root, new PartialPath(ALL_RESULT_NODES), store, false) {
@Override
- protected boolean processInternalMatchedMNode(IMNode node, int idx, int level) {
- // will never get here, implement for placeholder
+ protected boolean acceptFullMatchedNode(IMNode node) {
+ if (super.acceptFullMatchedNode(node)) {
+ // if node not set template, go on traversing
+ if (node.getSchemaTemplateId() != NON_TEMPLATE) {
+ if (filterPreUnset && node.isSchemaTemplatePreUnset()) {
+ // filter the pre unset template
+ return false;
+ }
+ // if set template, and equals to target or target for all, add to result
+ return templateId == ALL_TEMPLATE || templateId == node.getSchemaTemplateId();
+ }
+ }
return false;
}
@Override
- protected boolean processFullMatchedMNode(IMNode node, int idx, int level)
- throws MetadataException {
- // shall not traverse nodes inside template
- if (!node.getPartialPath().equals(getCurrentPartialPath(node))) {
- return true;
- }
+ protected Void collectMNode(IMNode node) {
+ resSet.add(node.getFullPath());
+ return null;
+ }
- // if node not set template, go on traversing
- if (node.getSchemaTemplateId() != NON_TEMPLATE) {
- if (filterPreUnset && node.isSchemaTemplatePreUnset()) {
- // filter the pre unset template
- return true;
- }
- // if set template, and equals to target or target for all, add to result
- if (templateId == ALL_TEMPLATE || templateId == node.getSchemaTemplateId()) {
- resSet.add(node.getFullPath());
- }
- // descendants of the node cannot set another template, exit from this branch
- return true;
- }
- return false;
+ @Override
+ protected boolean shouldVisitSubtreeOfFullMatchedNode(IMNode node) {
+ // descendants of the node cannot set another template, exit from this branch
+ return (node.getSchemaTemplateId() == NON_TEMPLATE)
+ && super.shouldVisitSubtreeOfFullMatchedNode(node);
}
- };
- setTemplatePaths.traverse();
+
+ @Override
+ protected boolean shouldVisitSubtreeOfInternalMatchedNode(IMNode node) {
+ // descendants of the node cannot set another template, exit from this branch
+ return (node.getSchemaTemplateId() == NON_TEMPLATE)
+ && super.shouldVisitSubtreeOfFullMatchedNode(node);
+ }
+ }) {
+ collector.traverse();
+ }
return resSet;
}
@@ -575,37 +547,44 @@ public class ConfigMTree {
public Map<Integer, Set<PartialPath>> getTemplateSetInfo(PartialPath pathPattern)
throws MetadataException {
Map<Integer, Set<PartialPath>> result = new HashMap<>();
- CollectorTraverser<List<Integer>> collector =
- new CollectorTraverser<List<Integer>>(root, pathPattern, store) {
+ try (MNodeCollector<?> collector =
+ new MNodeCollector<Void>(root, pathPattern, store, false) {
@Override
- protected boolean processInternalMatchedMNode(IMNode node, int idx, int level)
- throws MetadataException {
- if (node.getSchemaTemplateId() != NON_TEMPLATE) {
- // node set template
- result
- .computeIfAbsent(node.getSchemaTemplateId(), k -> new HashSet<>())
- .add(getCurrentPartialPath(node));
- // descendants of the node cannot set another template, exit from this branch
- return true;
- }
- return false;
+ protected boolean acceptFullMatchedNode(IMNode node) {
+ return (node.getSchemaTemplateId() != NON_TEMPLATE)
+ || super.acceptFullMatchedNode(node);
}
@Override
- protected boolean processFullMatchedMNode(IMNode node, int idx, int level)
- throws MetadataException {
- if (node.getSchemaTemplateId() != NON_TEMPLATE) {
- // node set template
- result
- .computeIfAbsent(node.getSchemaTemplateId(), k -> new HashSet<>())
- .add(getCurrentPartialPath(node));
- // descendants of the node cannot set another template, exit from this branch
- return true;
- }
- return false;
+ protected boolean acceptInternalMatchedNode(IMNode node) {
+ return (node.getSchemaTemplateId() != NON_TEMPLATE)
+ || super.acceptInternalMatchedNode(node);
}
- };
- collector.traverse();
+
+ @Override
+ protected Void collectMNode(IMNode node) {
+ result
+ .computeIfAbsent(node.getSchemaTemplateId(), k -> new HashSet<>())
+ .add(getPartialPathFromRootToNode(node));
+ return null;
+ }
+
+ @Override
+ protected boolean shouldVisitSubtreeOfFullMatchedNode(IMNode node) {
+ // descendants of the node cannot set another template, exit from this branch
+ return (node.getSchemaTemplateId() == NON_TEMPLATE)
+ && super.shouldVisitSubtreeOfFullMatchedNode(node);
+ }
+
+ @Override
+ protected boolean shouldVisitSubtreeOfInternalMatchedNode(IMNode node) {
+ // descendants of the node cannot set another template, exit from this branch
+ return (node.getSchemaTemplateId() == NON_TEMPLATE)
+ && super.shouldVisitSubtreeOfFullMatchedNode(node);
+ }
+ }) {
+ collector.traverse();
+ }
return result;
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/IMTreeBelowSG.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/IMTreeBelowSG.java
index 29b10aff07..3525a4650e 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/IMTreeBelowSG.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/IMTreeBelowSG.java
@@ -97,6 +97,22 @@ public interface IMTreeBelowSG {
boolean isEmptyInternalMNode(IMNode node) throws MetadataException;
+ /**
+ * Construct schema black list via setting matched timeseries to pre deleted.
+ *
+ * @param pathPattern path pattern
+ * @return PartialPath of timeseries that has been set to pre deleted
+ */
+ List<PartialPath> constructSchemaBlackList(PartialPath pathPattern) throws MetadataException;
+
+ /**
+ * Rollback schema black list via setting matched timeseries to not pre deleted.
+ *
+ * @param pathPattern path pattern
+ * @return PartialPath of timeseries that has been set to not pre deleted
+ */
+ List<PartialPath> rollbackSchemaBlackList(PartialPath pathPattern) throws MetadataException;
+
/**
* Get all pre-deleted timeseries matched by given pathPattern. For example, given path pattern
* root.sg.*.s1 and pre-deleted timeseries root.sg.d1.s1, root.sg.d2.s1, then the result set is
@@ -152,16 +168,34 @@ public interface IMTreeBelowSG {
List<IMeasurementMNode> getAllMeasurementMNode() throws MetadataException;
+ void activateTemplate(PartialPath activatePath, Template template) throws MetadataException;
+
/**
- * Get IMeasurementMNode by path pattern
+ * constructSchemaBlackListWithTemplate
*
- * @param pathPattern full path or path pattern with wildcard
- * @return list of IMeasurementMNode
+ * @param templateSetInfo PathPattern and templateId to pre-deactivate
+ * @return Actual full path and templateId that has been pre-deactivated
*/
- List<IMeasurementMNode> getMatchedMeasurementMNode(PartialPath pathPattern)
- throws MetadataException;
+ Map<PartialPath, List<Integer>> constructSchemaBlackListWithTemplate(
+ Map<PartialPath, List<Integer>> templateSetInfo) throws MetadataException;
- void activateTemplate(PartialPath activatePath, Template template) throws MetadataException;
+ /**
+ * rollbackSchemaBlackListWithTemplate
+ *
+ * @param templateSetInfo PathPattern and templateId to rollback pre-deactivate
+ * @return Actual full path and templateId that has been rolled back
+ */
+ Map<PartialPath, List<Integer>> rollbackSchemaBlackListWithTemplate(
+ Map<PartialPath, List<Integer>> templateSetInfo) throws MetadataException;
+
+ /**
+ * deactivateTemplateInBlackList
+ *
+ * @param templateSetInfo PathPattern and templateId to rollback deactivate
+ * @return Actual full path and templateId that has been deactivated
+ */
+ Map<PartialPath, List<Integer>> deactivateTemplateInBlackList(
+ Map<PartialPath, List<Integer>> templateSetInfo) throws MetadataException;
long countPathsUsingTemplate(PartialPath pathPattern, int templateId) throws MetadataException;
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGCachedImpl.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGCachedImpl.java
index f7d4c74437..e35cec440d 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGCachedImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGCachedImpl.java
@@ -33,6 +33,7 @@ import org.apache.iotdb.db.exception.metadata.PathNotExistException;
import org.apache.iotdb.db.exception.metadata.template.TemplateImcompatibeException;
import org.apache.iotdb.db.exception.metadata.template.TemplateIsInUseException;
import org.apache.iotdb.db.metadata.MetadataConstant;
+import org.apache.iotdb.db.metadata.mnode.AboveDatabaseMNode;
import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
@@ -41,10 +42,13 @@ import org.apache.iotdb.db.metadata.mnode.InternalMNode;
import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
import org.apache.iotdb.db.metadata.mnode.iterator.IMNodeIterator;
import org.apache.iotdb.db.metadata.mtree.store.CachedMTreeStore;
+import org.apache.iotdb.db.metadata.mtree.traverser.TraverserWithLimitOffsetWrapper;
import org.apache.iotdb.db.metadata.mtree.traverser.collector.EntityCollector;
import org.apache.iotdb.db.metadata.mtree.traverser.collector.MNodeCollector;
import org.apache.iotdb.db.metadata.mtree.traverser.collector.MeasurementCollector;
-import org.apache.iotdb.db.metadata.mtree.traverser.counter.CounterTraverser;
+import org.apache.iotdb.db.metadata.mtree.traverser.counter.EntityCounter;
+import org.apache.iotdb.db.metadata.mtree.traverser.updater.EntityUpdater;
+import org.apache.iotdb.db.metadata.mtree.traverser.updater.MeasurementUpdater;
import org.apache.iotdb.db.metadata.plan.schemaregion.read.IShowDevicesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.read.IShowNodesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.read.IShowTimeSeriesPlan;
@@ -67,7 +71,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -103,6 +106,7 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
private final CachedMTreeStore store;
private volatile IStorageGroupMNode storageGroupMNode;
+ private volatile IMNode rootNode;
private final Function<IMeasurementMNode, Map<String, String>> tagGetter;
private final int levelOfSG;
@@ -115,23 +119,30 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
this.tagGetter = tagGetter;
store = new CachedMTreeStore(storageGroupPath, schemaRegionId);
this.storageGroupMNode = store.getRoot().getAsStorageGroupMNode();
-
- this.storageGroupMNode.setParent(generatePrefix(storageGroupPath));
+ this.rootNode = generatePrefix(storageGroupPath, this.storageGroupMNode);
levelOfSG = storageGroupPath.getNodeLength() - 1;
}
- // generate the ancestor nodes of storageGroupNode
- private IMNode generatePrefix(PartialPath storageGroupPath) {
+ /**
+ * Generate the ancestor nodes of storageGroupNode
+ *
+ * @return root node
+ */
+ private IMNode generatePrefix(
+ PartialPath storageGroupPath, IStorageGroupMNode storageGroupMNode) {
String[] nodes = storageGroupPath.getNodes();
// nodes[0] must be root
- IMNode cur = new InternalMNode(null, nodes[0]);
+ IMNode root = new AboveDatabaseMNode(null, nodes[0]);
+ IMNode cur = root;
IMNode child;
for (int i = 1; i < nodes.length - 1; i++) {
- child = new InternalMNode(cur, nodes[i]);
+ child = new AboveDatabaseMNode(cur, nodes[i]);
cur.addChild(nodes[i], child);
cur = child;
}
- return cur;
+ storageGroupMNode.setParent(cur);
+ cur.addChild(storageGroupMNode);
+ return root;
}
/** Only used for load snapshot */
@@ -143,24 +154,22 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
throws MetadataException {
this.store = store;
this.storageGroupMNode = store.getRoot().getAsStorageGroupMNode();
- this.storageGroupMNode.setParent(generatePrefix(storageGroupPath));
+ this.rootNode = generatePrefix(storageGroupPath, this.storageGroupMNode);
levelOfSG = storageGroupMNode.getPartialPath().getNodeLength() - 1;
this.tagGetter = tagGetter;
// recover measurement
- MeasurementCollector<?> collector =
+ try (MeasurementCollector<?> collector =
new MeasurementCollector<Void>(
- this.storageGroupMNode,
- new PartialPath(storageGroupMNode.getFullPath()),
- this.store,
- false) {
+ this.rootNode, new PartialPath(storageGroupMNode.getFullPath()), this.store, true) {
@Override
- protected void collectMeasurement(IMeasurementMNode node) {
+ protected Void collectMeasurement(IMeasurementMNode node) {
measurementProcess.accept(node);
+ return null;
}
- };
- collector.setPrefixMatch(true);
- collector.traverse();
+ }) {
+ collector.traverse();
+ }
}
@Override
@@ -169,6 +178,11 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
storageGroupMNode = null;
}
+ protected void replaceStorageGroupMNode(IStorageGroupMNode newMNode) {
+ this.storageGroupMNode.getParent().replaceChild(this.storageGroupMNode.getName(), newMNode);
+ this.storageGroupMNode = newMNode;
+ }
+
@Override
public boolean createSnapshot(File snapshotDir) {
return store.createSnapshot(snapshotDir);
@@ -265,7 +279,7 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
} else {
entityMNode = store.setToEntity(device);
if (entityMNode.isStorageGroup()) {
- this.storageGroupMNode = entityMNode.getAsStorageGroupMNode();
+ replaceStorageGroupMNode(entityMNode.getAsStorageGroupMNode());
}
device = entityMNode;
}
@@ -349,7 +363,7 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
entityMNode = store.setToEntity(device);
entityMNode.setAligned(true);
if (entityMNode.isStorageGroup()) {
- this.storageGroupMNode = entityMNode.getAsStorageGroupMNode();
+ replaceStorageGroupMNode(entityMNode.getAsStorageGroupMNode());
}
device = entityMNode;
}
@@ -386,7 +400,7 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
@Override
public Map<Integer, MetadataException> checkMeasurementExistence(
PartialPath devicePath, List<String> measurementList, List<String> aliasList) {
- IMNode device = null;
+ IMNode device;
try {
device = getNodeByPath(devicePath);
} catch (MetadataException e) {
@@ -546,7 +560,7 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
synchronized (this) {
curNode = store.setToInternal(entityMNode);
if (curNode.isStorageGroup()) {
- this.storageGroupMNode = curNode.getAsStorageGroupMNode();
+ replaceStorageGroupMNode(curNode.getAsStorageGroupMNode());
}
}
}
@@ -578,22 +592,58 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
}
}
+ @Override
+ public List<PartialPath> constructSchemaBlackList(PartialPath pathPattern)
+ throws MetadataException {
+ List<PartialPath> result = new ArrayList<>();
+ try (MeasurementUpdater updater =
+ new MeasurementUpdater(rootNode, pathPattern, store, false) {
+ @Override
+ protected void updateMeasurement(IMeasurementMNode node) throws MetadataException {
+ node.setPreDeleted(true);
+ updateMNode(node);
+ result.add(getPartialPathFromRootToNode(node));
+ }
+ }) {
+ updater.update();
+ }
+ return result;
+ }
+
+ @Override
+ public List<PartialPath> rollbackSchemaBlackList(PartialPath pathPattern)
+ throws MetadataException {
+ List<PartialPath> result = new ArrayList<>();
+ try (MeasurementUpdater updater =
+ new MeasurementUpdater(rootNode, pathPattern, store, false) {
+ @Override
+ protected void updateMeasurement(IMeasurementMNode node) throws MetadataException {
+ node.setPreDeleted(false);
+ updateMNode(node);
+ result.add(getPartialPathFromRootToNode(node));
+ }
+ }) {
+ updater.update();
+ }
+ return result;
+ }
+
@Override
public List<PartialPath> getPreDeletedTimeseries(PartialPath pathPattern)
throws MetadataException {
List<PartialPath> result = new LinkedList<>();
- MeasurementCollector<List<PartialPath>> collector =
- new MeasurementCollector<List<PartialPath>>(storageGroupMNode, pathPattern, store) {
+ try (MeasurementCollector<Void> collector =
+ new MeasurementCollector<Void>(rootNode, pathPattern, store, false) {
@Override
- protected void collectMeasurement(IMeasurementMNode node) throws MetadataException {
+ protected Void collectMeasurement(IMeasurementMNode node) {
if (node.isPreDeleted()) {
- result.add(getCurrentPartialPath(node));
+ result.add(getPartialPathFromRootToNode(node));
}
+ return null;
}
- };
- collector.setResultSet(result);
- collector.setShouldTraverseTemplate(false);
- collector.traverse();
+ }) {
+ collector.traverse();
+ }
return result;
}
@@ -601,16 +651,19 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
public Set<PartialPath> getDevicesOfPreDeletedTimeseries(PartialPath pathPattern)
throws MetadataException {
Set<PartialPath> result = new HashSet<>();
- MeasurementCollector<List<PartialPath>> collector =
- new MeasurementCollector<List<PartialPath>>(storageGroupMNode, pathPattern, store) {
+ try (MeasurementCollector<Void> collector =
+ new MeasurementCollector<Void>(rootNode, pathPattern, store, false) {
@Override
- protected void collectMeasurement(IMeasurementMNode node) throws MetadataException {
+ protected Void collectMeasurement(IMeasurementMNode node) {
if (node.isPreDeleted()) {
- result.add(getCurrentPartialPath(node).getDevicePath());
+ result.add(getPartialPathFromRootToNode(node).getDevicePath());
}
+ return null;
}
- };
- collector.traverse();
+ }) {
+ collector.traverse();
+ }
+
return result;
}
@@ -657,20 +710,24 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
@Override
public List<ShowDevicesResult> getDevices(IShowDevicesPlan plan) throws MetadataException {
List<ShowDevicesResult> res = new ArrayList<>();
- EntityCollector<List<ShowDevicesResult>> collector =
- new EntityCollector<List<ShowDevicesResult>>(
- storageGroupMNode, plan.getPath(), store, plan.getLimit(), plan.getOffset()) {
+ try (EntityCollector<ShowDevicesResult> collector =
+ new EntityCollector<ShowDevicesResult>(
+ rootNode, plan.getPath(), store, plan.isPrefixMatch()) {
@Override
- protected void collectEntity(IEntityMNode node) {
- PartialPath device = getCurrentPartialPath(node);
- res.add(new ShowDevicesResult(device.getFullPath(), node.isAligned()));
+ protected ShowDevicesResult collectEntity(IEntityMNode node) {
+ PartialPath device = getPartialPathFromRootToNode(node);
+ return new ShowDevicesResult(device.getFullPath(), node.isAligned());
}
- };
- collector.setPrefixMatch(plan.isPrefixMatch());
- if (plan.usingSchemaTemplate()) {
- collector.setSchemaTemplateFilter(plan.getSchemaTemplateId());
+ }) {
+ if (plan.usingSchemaTemplate()) {
+ collector.setSchemaTemplateFilter(plan.getSchemaTemplateId());
+ }
+ TraverserWithLimitOffsetWrapper<ShowDevicesResult> traverser =
+ new TraverserWithLimitOffsetWrapper<>(collector, plan.getLimit(), plan.getOffset());
+ while (traverser.hasNext()) {
+ res.add(traverser.next());
+ }
}
- collector.traverse();
return res;
}
@@ -682,32 +739,31 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
IShowTimeSeriesPlan plan,
Function<Long, Pair<Map<String, String>, Map<String, String>>> tagAndAttributeProvider)
throws MetadataException {
- int limit = plan.getLimit();
- int offset = plan.getOffset();
-
- MeasurementCollector<List<ShowTimeSeriesResult>> collector =
- new MeasurementCollector<List<ShowTimeSeriesResult>>(
- storageGroupMNode, plan.getPath(), store, limit, offset) {
+ List<ShowTimeSeriesResult> result = new LinkedList<>();
+ try (MeasurementCollector<ShowTimeSeriesResult> collector =
+ new MeasurementCollector<ShowTimeSeriesResult>(
+ rootNode, plan.getPath(), store, plan.isPrefixMatch()) {
@Override
- protected void collectMeasurement(IMeasurementMNode node) {
+ protected ShowTimeSeriesResult collectMeasurement(IMeasurementMNode node) {
Pair<Map<String, String>, Map<String, String>> tagAndAttribute =
tagAndAttributeProvider.apply(node.getOffset());
- resultSet.add(
- new ShowTimeSeriesResult(
- getCurrentPartialPath(node).getFullPath(),
- node.getAlias(),
- (MeasurementSchema) node.getSchema(),
- tagAndAttribute.left,
- tagAndAttribute.right,
- getCurrentNodeParent().getAsEntityMNode().isAligned()));
+ return new ShowTimeSeriesResult(
+ getPartialPathFromRootToNode(node).getFullPath(),
+ node.getAlias(),
+ (MeasurementSchema) node.getSchema(),
+ tagAndAttribute.left,
+ tagAndAttribute.right,
+ getParentOfNextMatchedNode().getAsEntityMNode().isAligned());
}
- };
- collector.setPrefixMatch(plan.isPrefixMatch());
- collector.setTemplateMap(plan.getRelatedTemplate());
- collector.setResultSet(new LinkedList<>());
- collector.traverse();
-
- return collector.getResult();
+ }) {
+ collector.setTemplateMap(plan.getRelatedTemplate());
+ TraverserWithLimitOffsetWrapper<ShowTimeSeriesResult> traverser =
+ new TraverserWithLimitOffsetWrapper<>(collector, plan.getLimit(), plan.getOffset());
+ while (traverser.hasNext()) {
+ result.add(traverser.next());
+ }
+ }
+ return result;
}
// endregion
@@ -763,12 +819,12 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
PartialPath pathPattern, Map<Integer, Template> templateMap, boolean withTags)
throws MetadataException {
List<MeasurementPath> result = new LinkedList<>();
- MeasurementCollector<List<PartialPath>> collector =
- new MeasurementCollector<List<PartialPath>>(storageGroupMNode, pathPattern, store) {
+ try (MeasurementCollector<Void> collector =
+ new MeasurementCollector<Void>(rootNode, pathPattern, store, false) {
@Override
- protected void collectMeasurement(IMeasurementMNode node) {
+ protected Void collectMeasurement(IMeasurementMNode node) {
if (node.isPreDeleted()) {
- return;
+ return null;
}
MeasurementPath path = getCurrentMeasurementPathInTraverse(node);
if (nodes[nodes.length - 1].equals(node.getAlias())) {
@@ -779,10 +835,12 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
path.setTagMap(tagGetter.apply(node));
}
result.add(path);
+ return null;
}
- };
- collector.setTemplateMap(templateMap);
- collector.traverse();
+ }) {
+ collector.setTemplateMap(templateMap);
+ collector.traverse();
+ }
return result;
}
@@ -824,24 +882,6 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
}
}
}
-
- @Override
- public List<IMeasurementMNode> getMatchedMeasurementMNode(PartialPath pathPattern)
- throws MetadataException {
- List<IMeasurementMNode> result = new ArrayList<>();
- MeasurementCollector<List<IMeasurementMNode>> collector =
- new MeasurementCollector<List<IMeasurementMNode>>(storageGroupMNode, pathPattern, store) {
- @Override
- protected void collectMeasurement(IMeasurementMNode node) throws MetadataException {
- pinMNode(node);
- result.add(node);
- }
- };
- collector.setShouldTraverseTemplate(false);
- collector.traverse();
- return result;
- }
-
// endregion
// region Interfaces and Implementation for Template check and query
@@ -879,7 +919,7 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
} else {
entityMNode = store.setToEntity(cur);
if (entityMNode.isStorageGroup()) {
- this.storageGroupMNode = entityMNode.getAsStorageGroupMNode();
+ replaceStorageGroupMNode(entityMNode.getAsStorageGroupMNode());
}
}
}
@@ -896,14 +936,15 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
}
}
+ @Override
public Map<PartialPath, List<Integer>> constructSchemaBlackListWithTemplate(
Map<PartialPath, List<Integer>> templateSetInfo) throws MetadataException {
Map<PartialPath, List<Integer>> resultTemplateSetInfo = new HashMap<>();
for (Map.Entry<PartialPath, List<Integer>> entry : templateSetInfo.entrySet()) {
- EntityCollector<List<IEntityMNode>> collector =
- new EntityCollector<List<IEntityMNode>>(storageGroupMNode, entry.getKey(), store) {
+ try (EntityUpdater updater =
+ new EntityUpdater(rootNode, entry.getKey(), store, false) {
@Override
- protected void collectEntity(IEntityMNode node) throws MetadataException {
+ protected void updateEntity(IEntityMNode node) throws MetadataException {
if (entry.getValue().contains(node.getSchemaTemplateId())) {
resultTemplateSetInfo.put(
node.getPartialPath(), Collections.singletonList(node.getSchemaTemplateId()));
@@ -911,20 +952,22 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
store.updateMNode(node);
}
}
- };
- collector.traverse();
+ }) {
+ updater.update();
+ }
}
return resultTemplateSetInfo;
}
+ @Override
public Map<PartialPath, List<Integer>> rollbackSchemaBlackListWithTemplate(
Map<PartialPath, List<Integer>> templateSetInfo) throws MetadataException {
Map<PartialPath, List<Integer>> resultTemplateSetInfo = new HashMap<>();
for (Map.Entry<PartialPath, List<Integer>> entry : templateSetInfo.entrySet()) {
- EntityCollector<List<IEntityMNode>> collector =
- new EntityCollector<List<IEntityMNode>>(storageGroupMNode, entry.getKey(), store) {
+ try (EntityUpdater updater =
+ new EntityUpdater(rootNode, entry.getKey(), store, false) {
@Override
- protected void collectEntity(IEntityMNode node) throws MetadataException {
+ protected void updateEntity(IEntityMNode node) throws MetadataException {
if (entry.getValue().contains(node.getSchemaTemplateId())
&& node.isPreDeactivateTemplate()) {
resultTemplateSetInfo.put(
@@ -933,20 +976,22 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
store.updateMNode(node);
}
}
- };
- collector.traverse();
+ }) {
+ updater.update();
+ }
}
return resultTemplateSetInfo;
}
+ @Override
public Map<PartialPath, List<Integer>> deactivateTemplateInBlackList(
Map<PartialPath, List<Integer>> templateSetInfo) throws MetadataException {
Map<PartialPath, List<Integer>> resultTemplateSetInfo = new HashMap<>();
for (Map.Entry<PartialPath, List<Integer>> entry : templateSetInfo.entrySet()) {
- EntityCollector<List<IEntityMNode>> collector =
- new EntityCollector<List<IEntityMNode>>(storageGroupMNode, entry.getKey(), store) {
+ try (EntityUpdater collector =
+ new EntityUpdater(rootNode, entry.getKey(), store, false) {
@Override
- protected void collectEntity(IEntityMNode node) throws MetadataException {
+ protected void updateEntity(IEntityMNode node) throws MetadataException {
if (entry.getValue().contains(node.getSchemaTemplateId())
&& node.isPreDeactivateTemplate()) {
resultTemplateSetInfo.put(
@@ -956,8 +1001,9 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
deleteEmptyInternalMNodeAndReturnEmptyStorageGroup(node);
}
}
- };
- collector.traverse();
+ }) {
+ collector.traverse();
+ }
}
return resultTemplateSetInfo;
}
@@ -965,23 +1011,10 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
@Override
public long countPathsUsingTemplate(PartialPath pathPattern, int templateId)
throws MetadataException {
- CounterTraverser counterTraverser =
- new CounterTraverser(storageGroupMNode, pathPattern, store) {
- @Override
- protected boolean processInternalMatchedMNode(IMNode node, int idx, int level) {
- return false;
- }
-
- @Override
- protected boolean processFullMatchedMNode(IMNode node, int idx, int level) {
- if (node.isEntity() && node.getAsEntityMNode().getSchemaTemplateId() == templateId) {
- count++;
- }
- return false;
- }
- };
- counterTraverser.traverse();
- return counterTraverser.getCount();
+ try (EntityCounter counter = new EntityCounter(rootNode, pathPattern, store, false)) {
+ counter.setSchemaTemplateFilter(templateId);
+ return counter.count();
+ }
}
// endregion
@@ -1014,34 +1047,30 @@ public class MTreeBelowSGCachedImpl implements IMTreeBelowSG {
// region Interfaces for schema reader
public ISchemaReader<INodeSchemaInfo> getNodeReader(IShowNodesPlan showNodesPlan)
throws MetadataException {
- MNodeCollector<Set<INodeSchemaInfo>> collector =
- new MNodeCollector<Set<INodeSchemaInfo>>(
- storageGroupMNode, showNodesPlan.getPath(), store) {
+ MNodeCollector<INodeSchemaInfo> collector =
+ new MNodeCollector<INodeSchemaInfo>(
+ rootNode, showNodesPlan.getPath(), store, showNodesPlan.isPrefixMatch()) {
@Override
- protected void transferToResult(IMNode node) {
- resultSet.add(
- new ShowNodesResult(
- getCurrentPartialPath(node).getFullPath(), node.getMNodeType(false)));
+ protected INodeSchemaInfo collectMNode(IMNode node) {
+ return new ShowNodesResult(
+ getPartialPathFromRootToNode(node).getFullPath(), node.getMNodeType(false));
}
};
- collector.setResultSet(new HashSet<>());
collector.setTargetLevel(showNodesPlan.getLevel());
- collector.setPrefixMatch(showNodesPlan.isPrefixMatch());
- collector.traverse();
-
- Iterator<INodeSchemaInfo> iterator = collector.getResult().iterator();
return new ISchemaReader<INodeSchemaInfo>() {
@Override
- public void close() throws Exception {}
+ public void close() {
+ collector.close();
+ }
@Override
public boolean hasNext() {
- return iterator.hasNext();
+ return collector.hasNext();
}
@Override
public INodeSchemaInfo next() {
- return iterator.next();
+ return collector.next();
}
};
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGMemoryImpl.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGMemoryImpl.java
index 2920f6baa1..aff1496d27 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGMemoryImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/MTreeBelowSGMemoryImpl.java
@@ -33,6 +33,7 @@ import org.apache.iotdb.db.exception.metadata.PathNotExistException;
import org.apache.iotdb.db.exception.metadata.template.TemplateImcompatibeException;
import org.apache.iotdb.db.exception.metadata.template.TemplateIsInUseException;
import org.apache.iotdb.db.metadata.MetadataConstant;
+import org.apache.iotdb.db.metadata.mnode.AboveDatabaseMNode;
import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
@@ -41,10 +42,13 @@ import org.apache.iotdb.db.metadata.mnode.InternalMNode;
import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
import org.apache.iotdb.db.metadata.mnode.iterator.IMNodeIterator;
import org.apache.iotdb.db.metadata.mtree.store.MemMTreeStore;
+import org.apache.iotdb.db.metadata.mtree.traverser.TraverserWithLimitOffsetWrapper;
import org.apache.iotdb.db.metadata.mtree.traverser.collector.EntityCollector;
import org.apache.iotdb.db.metadata.mtree.traverser.collector.MNodeCollector;
import org.apache.iotdb.db.metadata.mtree.traverser.collector.MeasurementCollector;
-import org.apache.iotdb.db.metadata.mtree.traverser.counter.CounterTraverser;
+import org.apache.iotdb.db.metadata.mtree.traverser.counter.EntityCounter;
+import org.apache.iotdb.db.metadata.mtree.traverser.updater.EntityUpdater;
+import org.apache.iotdb.db.metadata.mtree.traverser.updater.MeasurementUpdater;
import org.apache.iotdb.db.metadata.plan.schemaregion.read.IShowDevicesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.read.IShowNodesPlan;
import org.apache.iotdb.db.metadata.plan.schemaregion.read.IShowTimeSeriesPlan;
@@ -67,7 +71,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -104,6 +107,7 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
// this implementation is based on memory, thus only MTree write operation must invoke MTreeStore
private MemMTreeStore store;
private volatile IStorageGroupMNode storageGroupMNode;
+ private volatile IMNode rootNode;
private final Function<IMeasurementMNode, Map<String, String>> tagGetter;
private int levelOfSG;
@@ -114,7 +118,7 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
int schemaRegionId) {
store = new MemMTreeStore(storageGroupPath, true);
this.storageGroupMNode = store.getRoot().getAsStorageGroupMNode();
- this.storageGroupMNode.setParent(generatePrefix(storageGroupPath));
+ this.rootNode = generatePrefix(storageGroupPath, this.storageGroupMNode);
levelOfSG = storageGroupPath.getNodeLength() - 1;
this.tagGetter = tagGetter;
}
@@ -126,23 +130,31 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
int schemaRegionId) {
this.store = store;
this.storageGroupMNode = store.getRoot().getAsStorageGroupMNode();
- this.storageGroupMNode.setParent(generatePrefix(storageGroupPath));
+ this.rootNode = generatePrefix(storageGroupPath, this.storageGroupMNode);
levelOfSG = storageGroupPath.getNodeLength() - 1;
this.tagGetter = tagGetter;
}
- // generate the ancestor nodes of storageGroupNode
- private IMNode generatePrefix(PartialPath storageGroupPath) {
+ /**
+ * Generate the ancestor nodes of storageGroupNode
+ *
+ * @return root node
+ */
+ private IMNode generatePrefix(
+ PartialPath storageGroupPath, IStorageGroupMNode storageGroupMNode) {
String[] nodes = storageGroupPath.getNodes();
// nodes[0] must be root
- IMNode cur = new InternalMNode(null, nodes[0]);
+ IMNode root = new AboveDatabaseMNode(null, nodes[0]);
+ IMNode cur = root;
IMNode child;
for (int i = 1; i < nodes.length - 1; i++) {
- child = new InternalMNode(cur, nodes[i]);
+ child = new AboveDatabaseMNode(cur, nodes[i]);
cur.addChild(nodes[i], child);
cur = child;
}
- return cur;
+ storageGroupMNode.setParent(cur);
+ cur.addChild(storageGroupMNode);
+ return root;
}
@Override
@@ -151,6 +163,11 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
storageGroupMNode = null;
}
+ protected void replaceStorageGroupMNode(IStorageGroupMNode newMNode) {
+ this.storageGroupMNode.getParent().replaceChild(this.storageGroupMNode.getName(), newMNode);
+ this.storageGroupMNode = newMNode;
+ }
+
@Override
public synchronized boolean createSnapshot(File snapshotDir) {
return store.createSnapshot(snapshotDir);
@@ -241,7 +258,7 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
} else {
entityMNode = store.setToEntity(device);
if (entityMNode.isStorageGroup()) {
- this.storageGroupMNode = entityMNode.getAsStorageGroupMNode();
+ replaceStorageGroupMNode(entityMNode.getAsStorageGroupMNode());
}
}
@@ -323,7 +340,7 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
entityMNode = store.setToEntity(device);
entityMNode.setAligned(true);
if (entityMNode.isStorageGroup()) {
- this.storageGroupMNode = entityMNode.getAsStorageGroupMNode();
+ replaceStorageGroupMNode(entityMNode.getAsStorageGroupMNode());
}
}
@@ -391,7 +408,7 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
@Override
public Map<Integer, MetadataException> checkMeasurementExistence(
PartialPath devicePath, List<String> measurementList, List<String> aliasList) {
- IMNode device = null;
+ IMNode device;
try {
device = getNodeByPath(devicePath);
} catch (PathNotExistException e) {
@@ -475,7 +492,7 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
synchronized (this) {
curNode = store.setToInternal(entityMNode);
if (curNode.isStorageGroup()) {
- this.storageGroupMNode = curNode.getAsStorageGroupMNode();
+ replaceStorageGroupMNode(curNode.getAsStorageGroupMNode());
}
}
}
@@ -501,22 +518,56 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
&& node.getChildren().isEmpty();
}
+ @Override
+ public List<PartialPath> constructSchemaBlackList(PartialPath pathPattern)
+ throws MetadataException {
+ List<PartialPath> result = new ArrayList<>();
+ try (MeasurementUpdater updater =
+ new MeasurementUpdater(rootNode, pathPattern, store, false) {
+ @Override
+ protected void updateMeasurement(IMeasurementMNode node) {
+ node.setPreDeleted(true);
+ result.add(getPartialPathFromRootToNode(node));
+ }
+ }) {
+ updater.update();
+ }
+ return result;
+ }
+
+ @Override
+ public List<PartialPath> rollbackSchemaBlackList(PartialPath pathPattern)
+ throws MetadataException {
+ List<PartialPath> result = new ArrayList<>();
+ try (MeasurementUpdater updater =
+ new MeasurementUpdater(rootNode, pathPattern, store, false) {
+ @Override
+ protected void updateMeasurement(IMeasurementMNode node) {
+ node.setPreDeleted(false);
+ result.add(getPartialPathFromRootToNode(node));
+ }
+ }) {
+ updater.update();
+ }
+ return result;
+ }
+
@Override
public List<PartialPath> getPreDeletedTimeseries(PartialPath pathPattern)
throws MetadataException {
List<PartialPath> result = new LinkedList<>();
- MeasurementCollector<List<PartialPath>> collector =
- new MeasurementCollector<List<PartialPath>>(storageGroupMNode, pathPattern, store) {
+ try (MeasurementCollector<Void> collector =
+ new MeasurementCollector<Void>(rootNode, pathPattern, store, false) {
@Override
- protected void collectMeasurement(IMeasurementMNode node) throws MetadataException {
+ protected Void collectMeasurement(IMeasurementMNode node) {
if (node.isPreDeleted()) {
- result.add(getCurrentPartialPath(node));
+ result.add(getPartialPathFromRootToNode(node));
}
+ return null;
}
- };
- collector.setResultSet(result);
- collector.setShouldTraverseTemplate(false);
- collector.traverse();
+ }) {
+ collector.traverse();
+ }
return result;
}
@@ -524,16 +575,18 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
public Set<PartialPath> getDevicesOfPreDeletedTimeseries(PartialPath pathPattern)
throws MetadataException {
Set<PartialPath> result = new HashSet<>();
- MeasurementCollector<List<PartialPath>> collector =
- new MeasurementCollector<List<PartialPath>>(storageGroupMNode, pathPattern, store) {
+ try (MeasurementCollector<Void> collector =
+ new MeasurementCollector<Void>(rootNode, pathPattern, store, false) {
@Override
- protected void collectMeasurement(IMeasurementMNode node) throws MetadataException {
+ protected Void collectMeasurement(IMeasurementMNode node) {
if (node.isPreDeleted()) {
- result.add(getCurrentPartialPath(node).getDevicePath());
+ result.add(getPartialPathFromRootToNode(node).getDevicePath());
}
+ return null;
}
- };
- collector.traverse();
+ }) {
+ collector.traverse();
+ }
return result;
}
@@ -575,21 +628,24 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
@Override
public List<ShowDevicesResult> getDevices(IShowDevicesPlan plan) throws MetadataException {
List<ShowDevicesResult> res = new ArrayList<>();
- EntityCollector<List<ShowDevicesResult>> collector =
- new EntityCollector<List<ShowDevicesResult>>(
- storageGroupMNode, plan.getPath(), store, plan.getLimit(), plan.getOffset()) {
+ try (EntityCollector<ShowDevicesResult> collector =
+ new EntityCollector<ShowDevicesResult>(
+ rootNode, plan.getPath(), store, plan.isPrefixMatch()) {
@Override
- protected void collectEntity(IEntityMNode node) {
- PartialPath device = getCurrentPartialPath(node);
- res.add(new ShowDevicesResult(device.getFullPath(), node.isAligned()));
+ protected ShowDevicesResult collectEntity(IEntityMNode node) {
+ PartialPath device = getPartialPathFromRootToNode(node);
+ return new ShowDevicesResult(device.getFullPath(), node.isAligned());
}
- };
- collector.setPrefixMatch(plan.isPrefixMatch());
- if (plan.usingSchemaTemplate()) {
- collector.setSchemaTemplateFilter(plan.getSchemaTemplateId());
+ }) {
+ if (plan.usingSchemaTemplate()) {
+ collector.setSchemaTemplateFilter(plan.getSchemaTemplateId());
+ }
+ TraverserWithLimitOffsetWrapper<ShowDevicesResult> traverser =
+ new TraverserWithLimitOffsetWrapper<>(collector, plan.getLimit(), plan.getOffset());
+ while (traverser.hasNext()) {
+ res.add(traverser.next());
+ }
}
- collector.traverse();
-
return res;
}
// endregion
@@ -601,10 +657,10 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
PartialPath pathPattern, Map<Integer, Template> templateMap, boolean withTags)
throws MetadataException {
List<MeasurementPath> result = new LinkedList<>();
- MeasurementCollector<List<PartialPath>> collector =
- new MeasurementCollector<List<PartialPath>>(storageGroupMNode, pathPattern, store) {
+ try (MeasurementCollector<Void> collector =
+ new MeasurementCollector<Void>(rootNode, pathPattern, store, false) {
@Override
- protected void collectMeasurement(IMeasurementMNode node) {
+ protected Void collectMeasurement(IMeasurementMNode node) {
MeasurementPath path = getCurrentMeasurementPathInTraverse(node);
if (nodes[nodes.length - 1].equals(node.getAlias())) {
// only when user query with alias, the alias in path will be set
@@ -614,11 +670,13 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
path.setTagMap(tagGetter.apply(node));
}
result.add(path);
+ return null;
}
- };
- collector.setTemplateMap(templateMap);
- collector.setSkipPreDeletedSchema(true);
- collector.traverse();
+ }) {
+ collector.setTemplateMap(templateMap);
+ collector.setSkipPreDeletedSchema(true);
+ collector.traverse();
+ }
return result;
}
@@ -626,32 +684,31 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
IShowTimeSeriesPlan plan,
Function<Long, Pair<Map<String, String>, Map<String, String>>> tagAndAttributeProvider)
throws MetadataException {
- int limit = plan.getLimit();
- int offset = plan.getOffset();
-
- MeasurementCollector<List<ShowTimeSeriesResult>> collector =
- new MeasurementCollector<List<ShowTimeSeriesResult>>(
- storageGroupMNode, plan.getPath(), store, limit, offset) {
+ List<ShowTimeSeriesResult> result = new LinkedList<>();
+ try (MeasurementCollector<ShowTimeSeriesResult> collector =
+ new MeasurementCollector<ShowTimeSeriesResult>(
+ rootNode, plan.getPath(), store, plan.isPrefixMatch()) {
@Override
- protected void collectMeasurement(IMeasurementMNode node) {
+ protected ShowTimeSeriesResult collectMeasurement(IMeasurementMNode node) {
Pair<Map<String, String>, Map<String, String>> tagAndAttribute =
tagAndAttributeProvider.apply(node.getOffset());
- resultSet.add(
- new ShowTimeSeriesResult(
- getCurrentPartialPath(node).getFullPath(),
- node.getAlias(),
- (MeasurementSchema) node.getSchema(),
- tagAndAttribute.left,
- tagAndAttribute.right,
- getCurrentNodeParent().getAsEntityMNode().isAligned()));
+ return new ShowTimeSeriesResult(
+ getPartialPathFromRootToNode(node).getFullPath(),
+ node.getAlias(),
+ (MeasurementSchema) node.getSchema(),
+ tagAndAttribute.left,
+ tagAndAttribute.right,
+ getParentOfNextMatchedNode().getAsEntityMNode().isAligned());
}
- };
- collector.setPrefixMatch(plan.isPrefixMatch());
- collector.setTemplateMap(plan.getRelatedTemplate());
- collector.setResultSet(new LinkedList<>());
- collector.traverse();
-
- return collector.getResult();
+ }) {
+ collector.setTemplateMap(plan.getRelatedTemplate());
+ TraverserWithLimitOffsetWrapper<ShowTimeSeriesResult> traverser =
+ new TraverserWithLimitOffsetWrapper<>(collector, plan.getLimit(), plan.getOffset());
+ while (traverser.hasNext()) {
+ result.add(traverser.next());
+ }
+ }
+ return result;
}
// endregion
@@ -697,7 +754,7 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
}
@Override
- public List<IMeasurementMNode> getAllMeasurementMNode() throws MetadataException {
+ public List<IMeasurementMNode> getAllMeasurementMNode() {
IMNode cur = storageGroupMNode;
// collect all the LeafMNode in this database
List<IMeasurementMNode> leafMNodes = new LinkedList<>();
@@ -719,22 +776,6 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
return leafMNodes;
}
- @Override
- public List<IMeasurementMNode> getMatchedMeasurementMNode(PartialPath pathPattern)
- throws MetadataException {
- List<IMeasurementMNode> result = new ArrayList<>();
- MeasurementCollector<List<IMeasurementMNode>> collector =
- new MeasurementCollector<List<IMeasurementMNode>>(storageGroupMNode, pathPattern, store) {
- @Override
- protected void collectMeasurement(IMeasurementMNode node) throws MetadataException {
- result.add(node);
- }
- };
- collector.setShouldTraverseTemplate(false);
- collector.traverse();
- return result;
- }
-
// endregion
// region Interfaces and Implementation for Template check and query
@@ -767,7 +808,7 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
} else {
entityMNode = store.setToEntity(cur);
if (entityMNode.isStorageGroup()) {
- this.storageGroupMNode = entityMNode.getAsStorageGroupMNode();
+ replaceStorageGroupMNode(entityMNode.getAsStorageGroupMNode());
}
}
}
@@ -779,6 +820,76 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
entityMNode.setSchemaTemplateId(template.getId());
}
+ @Override
+ public Map<PartialPath, List<Integer>> constructSchemaBlackListWithTemplate(
+ Map<PartialPath, List<Integer>> templateSetInfo) throws MetadataException {
+ Map<PartialPath, List<Integer>> resultTemplateSetInfo = new HashMap<>();
+ for (Map.Entry<PartialPath, List<Integer>> entry : templateSetInfo.entrySet()) {
+ try (EntityUpdater updater =
+ new EntityUpdater(rootNode, entry.getKey(), store, false) {
+ @Override
+ protected void updateEntity(IEntityMNode node) throws MetadataException {
+ if (entry.getValue().contains(node.getSchemaTemplateId())) {
+ resultTemplateSetInfo.put(
+ node.getPartialPath(), Collections.singletonList(node.getSchemaTemplateId()));
+ node.preDeactivateTemplate();
+ store.updateMNode(node);
+ }
+ }
+ }) {
+ updater.update();
+ }
+ }
+ return resultTemplateSetInfo;
+ }
+
+ @Override
+ public Map<PartialPath, List<Integer>> rollbackSchemaBlackListWithTemplate(
+ Map<PartialPath, List<Integer>> templateSetInfo) throws MetadataException {
+ Map<PartialPath, List<Integer>> resultTemplateSetInfo = new HashMap<>();
+ for (Map.Entry<PartialPath, List<Integer>> entry : templateSetInfo.entrySet()) {
+ try (EntityUpdater updater =
+ new EntityUpdater(rootNode, entry.getKey(), store, false) {
+ @Override
+ protected void updateEntity(IEntityMNode node) {
+ if (entry.getValue().contains(node.getSchemaTemplateId())
+ && node.isPreDeactivateTemplate()) {
+ resultTemplateSetInfo.put(
+ node.getPartialPath(), Collections.singletonList(node.getSchemaTemplateId()));
+ node.rollbackPreDeactivateTemplate();
+ }
+ }
+ }) {
+ updater.update();
+ }
+ }
+ return resultTemplateSetInfo;
+ }
+
+ @Override
+ public Map<PartialPath, List<Integer>> deactivateTemplateInBlackList(
+ Map<PartialPath, List<Integer>> templateSetInfo) throws MetadataException {
+ Map<PartialPath, List<Integer>> resultTemplateSetInfo = new HashMap<>();
+ for (Map.Entry<PartialPath, List<Integer>> entry : templateSetInfo.entrySet()) {
+ try (EntityUpdater collector =
+ new EntityUpdater(rootNode, entry.getKey(), store, false) {
+ @Override
+ protected void updateEntity(IEntityMNode node) {
+ if (entry.getValue().contains(node.getSchemaTemplateId())
+ && node.isPreDeactivateTemplate()) {
+ resultTemplateSetInfo.put(
+ node.getPartialPath(), Collections.singletonList(node.getSchemaTemplateId()));
+ node.deactivateTemplate();
+ deleteEmptyInternalMNodeAndReturnEmptyStorageGroup(node);
+ }
+ }
+ }) {
+ collector.traverse();
+ }
+ }
+ return resultTemplateSetInfo;
+ }
+
public void activateTemplateWithoutCheck(
PartialPath activatePath, int templateId, boolean isAligned) {
String[] nodes = activatePath.getNodes();
@@ -793,7 +904,7 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
} else {
entityMNode = store.setToEntity(cur);
if (entityMNode.isStorageGroup()) {
- this.storageGroupMNode = entityMNode.getAsStorageGroupMNode();
+ replaceStorageGroupMNode(entityMNode.getAsStorageGroupMNode());
}
}
@@ -804,61 +915,13 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
entityMNode.setSchemaTemplateId(templateId);
}
- public List<IEntityMNode> getDeviceMNodeUsingTargetTemplate(
- PartialPath pathPattern, List<Integer> templateIdList) throws MetadataException {
- List<IEntityMNode> result = new ArrayList<>();
- EntityCollector<List<IEntityMNode>> collector =
- new EntityCollector<List<IEntityMNode>>(storageGroupMNode, pathPattern, store) {
- @Override
- protected void collectEntity(IEntityMNode node) {
- if (templateIdList.contains(node.getSchemaTemplateId())) {
- result.add(node);
- }
- }
- };
- collector.traverse();
- return result;
- }
-
- public List<IEntityMNode> getPreDeactivatedDeviceMNode(
- PartialPath pathPattern, List<Integer> templateIdList) throws MetadataException {
- List<IEntityMNode> result = new ArrayList<>();
- EntityCollector<List<IEntityMNode>> collector =
- new EntityCollector<List<IEntityMNode>>(storageGroupMNode, pathPattern, store) {
- @Override
- protected void collectEntity(IEntityMNode node) {
- if (templateIdList.contains(node.getSchemaTemplateId())
- && node.isPreDeactivateTemplate()) {
- result.add(node);
- }
- }
- };
- collector.traverse();
- return result;
- }
-
@Override
public long countPathsUsingTemplate(PartialPath pathPattern, int templateId)
throws MetadataException {
- CounterTraverser counterTraverser =
- new CounterTraverser(storageGroupMNode, pathPattern, store) {
- @Override
- protected boolean processInternalMatchedMNode(IMNode node, int idx, int level)
- throws MetadataException {
- return false;
- }
-
- @Override
- protected boolean processFullMatchedMNode(IMNode node, int idx, int level)
- throws MetadataException {
- if (node.isEntity() && node.getAsEntityMNode().getSchemaTemplateId() == templateId) {
- count++;
- }
- return false;
- }
- };
- counterTraverser.traverse();
- return counterTraverser.getCount();
+ try (EntityCounter counter = new EntityCounter(rootNode, pathPattern, store, false)) {
+ counter.setSchemaTemplateFilter(templateId);
+ return counter.count();
+ }
}
// endregion
@@ -866,34 +929,31 @@ public class MTreeBelowSGMemoryImpl implements IMTreeBelowSG {
// region Interfaces for schema reader
public ISchemaReader<INodeSchemaInfo> getNodeReader(IShowNodesPlan showNodesPlan)
throws MetadataException {
- MNodeCollector<Set<INodeSchemaInfo>> collector =
- new MNodeCollector<Set<INodeSchemaInfo>>(
- storageGroupMNode, showNodesPlan.getPath(), store) {
+ MNodeCollector<INodeSchemaInfo> collector =
+ new MNodeCollector<INodeSchemaInfo>(
+ rootNode, showNodesPlan.getPath(), store, showNodesPlan.isPrefixMatch()) {
@Override
- protected void transferToResult(IMNode node) {
- resultSet.add(
- new ShowNodesResult(
- getCurrentPartialPath(node).getFullPath(), node.getMNodeType(false)));
+ protected INodeSchemaInfo collectMNode(IMNode node) {
+ return new ShowNodesResult(
+ getPartialPathFromRootToNode(node).getFullPath(), node.getMNodeType(false));
}
};
- collector.setResultSet(new HashSet<>());
collector.setTargetLevel(showNodesPlan.getLevel());
- collector.setPrefixMatch(showNodesPlan.isPrefixMatch());
- collector.traverse();
- Iterator<INodeSchemaInfo> iterator = collector.getResult().iterator();
return new ISchemaReader<INodeSchemaInfo>() {
@Override
- public void close() throws Exception {}
+ public void close() {
+ collector.close();
+ }
@Override
public boolean hasNext() {
- return iterator.hasNext();
+ return collector.hasNext();
}
@Override
public INodeSchemaInfo next() {
- return iterator.next();
+ return collector.next();
}
};
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/CachedMTreeStore.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/CachedMTreeStore.java
index fe84289890..fa6d1dda71 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/CachedMTreeStore.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/CachedMTreeStore.java
@@ -26,6 +26,8 @@ import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
import org.apache.iotdb.db.metadata.mnode.MNodeUtils;
import org.apache.iotdb.db.metadata.mnode.estimator.IMNodeSizeEstimator;
+import org.apache.iotdb.db.metadata.mnode.iterator.AbstractTraverserIterator;
+import org.apache.iotdb.db.metadata.mnode.iterator.CachedTraverserIterator;
import org.apache.iotdb.db.metadata.mnode.iterator.IMNodeIterator;
import org.apache.iotdb.db.metadata.mtree.store.disk.ICachedMNodeContainer;
import org.apache.iotdb.db.metadata.mtree.store.disk.MTreeFlushTaskManager;
@@ -36,6 +38,7 @@ import org.apache.iotdb.db.metadata.mtree.store.disk.memcontrol.IMemManager;
import org.apache.iotdb.db.metadata.mtree.store.disk.memcontrol.MemManagerHolder;
import org.apache.iotdb.db.metadata.mtree.store.disk.schemafile.ISchemaFile;
import org.apache.iotdb.db.metadata.mtree.store.disk.schemafile.SchemaFile;
+import org.apache.iotdb.db.metadata.template.Template;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,6 +47,7 @@ import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.NoSuchElementException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
@@ -193,6 +197,20 @@ public class CachedMTreeStore implements IMTreeStore {
}
}
+ @Override
+ public IMNodeIterator getTraverserIterator(
+ IMNode parent, Map<Integer, Template> templateMap, boolean skipPreDeletedSchema)
+ throws MetadataException {
+ if (parent.isEntity()) {
+ AbstractTraverserIterator iterator =
+ new CachedTraverserIterator(this, parent.getAsEntityMNode(), templateMap);
+ iterator.setSkipPreDeletedSchema(skipPreDeletedSchema);
+ return iterator;
+ } else {
+ return getChildrenIterator(parent);
+ }
+ }
+
// must pin parent first
@Override
public IMNode addChild(IMNode parent, String childName, IMNode child) {
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/IMTreeStore.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/IMTreeStore.java
index 7e72dd8531..feac00898a 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/IMTreeStore.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/IMTreeStore.java
@@ -23,8 +23,10 @@ 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.iterator.IMNodeIterator;
+import org.apache.iotdb.db.metadata.template.Template;
import java.io.File;
+import java.util.Map;
/**
* This interface defines the basic access methods of an MTreeStore.
@@ -55,6 +57,10 @@ public interface IMTreeStore {
IMNodeIterator getChildrenIterator(IMNode parent) throws MetadataException;
+ IMNodeIterator getTraverserIterator(
+ IMNode parent, Map<Integer, Template> templateMap, boolean skipPreDeletedSchema)
+ throws MetadataException;
+
IMNode addChild(IMNode parent, String childName, IMNode child);
void deleteChild(IMNode parent, String childName) throws MetadataException;
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/MemMTreeStore.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/MemMTreeStore.java
index 19f5502fbd..c5ea4cf348 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/MemMTreeStore.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/store/MemMTreeStore.java
@@ -20,6 +20,7 @@ package org.apache.iotdb.db.metadata.mtree.store;
import org.apache.iotdb.commons.conf.CommonDescriptor;
import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
import org.apache.iotdb.db.metadata.mnode.IMNode;
@@ -29,13 +30,17 @@ import org.apache.iotdb.db.metadata.mnode.MNodeUtils;
import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
import org.apache.iotdb.db.metadata.mnode.estimator.BasicMNodSizeEstimator;
import org.apache.iotdb.db.metadata.mnode.estimator.IMNodeSizeEstimator;
+import org.apache.iotdb.db.metadata.mnode.iterator.AbstractTraverserIterator;
import org.apache.iotdb.db.metadata.mnode.iterator.IMNodeIterator;
import org.apache.iotdb.db.metadata.mnode.iterator.MNodeIterator;
+import org.apache.iotdb.db.metadata.mnode.iterator.MemoryTraverserIterator;
import org.apache.iotdb.db.metadata.mtree.snapshot.MemMTreeSnapshotUtil;
import org.apache.iotdb.db.metadata.rescon.MemoryStatistics;
+import org.apache.iotdb.db.metadata.template.Template;
import java.io.File;
import java.io.IOException;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
@@ -84,6 +89,20 @@ public class MemMTreeStore implements IMTreeStore {
return new MNodeIterator(parent.getChildren().values().iterator());
}
+ @Override
+ public IMNodeIterator getTraverserIterator(
+ IMNode parent, Map<Integer, Template> templateMap, boolean skipPreDeletedSchema)
+ throws MetadataException {
+ if (parent.isEntity()) {
+ AbstractTraverserIterator iterator =
+ new MemoryTraverserIterator(this, parent.getAsEntityMNode(), templateMap);
+ iterator.setSkipPreDeletedSchema(skipPreDeletedSchema);
+ return iterator;
+ } else {
+ return getChildrenIterator(parent);
+ }
+ }
+
@Override
public IMNode addChild(IMNode parent, String childName, IMNode child) {
IMNode result = parent.addChild(childName, child);
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/Traverser.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/Traverser.java
index 53a534c78b..670a64954c 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/Traverser.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/Traverser.java
@@ -21,22 +21,16 @@ package org.apache.iotdb.db.metadata.mtree.traverser;
import org.apache.iotdb.commons.exception.IllegalPathException;
import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.schema.tree.AbstractTreeVisitor;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mnode.iterator.IMNodeIterator;
+import org.apache.iotdb.db.metadata.mnode.iterator.MNodeIterator;
import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
import org.apache.iotdb.db.metadata.template.Template;
-import java.util.ArrayDeque;
-import java.util.Arrays;
-import java.util.Deque;
import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
import java.util.Map;
-import java.util.regex.Pattern;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.ONE_LEVEL_PATH_WILDCARD;
import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_ROOT;
import static org.apache.iotdb.db.metadata.MetadataConstant.NON_TEMPLATE;
@@ -50,23 +44,14 @@ import static org.apache.iotdb.db.metadata.MetadataConstant.NON_TEMPLATE;
* <li>collector: to collect customized results of the matched node or measurement
* </ol>
*/
-public abstract class Traverser {
+public abstract class Traverser<R> extends AbstractTreeVisitor<IMNode, R> {
protected IMTreeStore store;
protected IMNode startNode;
protected String[] nodes;
- protected int startIndex;
- protected int startLevel;
- protected boolean isPrefixStart = false;
- // to construct full path or find mounted node on MTree when traverse into template
- protected Deque<IMNode> traverseContext;
-
- protected boolean isInTemplate = false;
-
- // if true, measurement in template should be processed
- protected boolean shouldTraverseTemplate = false;
+ // measurement in template should be processed only if templateMap is not null
protected Map<Integer, Template> templateMap;
// if true, the pre deleted measurement or pre deactivated template won't be processed
@@ -75,6 +60,8 @@ public abstract class Traverser {
// default false means fullPath pattern match
protected boolean isPrefixMatch = false;
+ protected Traverser() {}
+
/**
* To traverse subtree under root.sg, e.g., init Traverser(root, "root.sg.**")
*
@@ -82,8 +69,9 @@ public abstract class Traverser {
* @param path use wildcard to specify which part to traverse
* @throws MetadataException
*/
- protected Traverser(IMNode startNode, PartialPath path, IMTreeStore store)
+ protected Traverser(IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
throws MetadataException {
+ super(startNode, path, isPrefixMatch);
String[] nodes = path.getNodes();
if (nodes.length == 0 || !nodes[0].equals(PATH_ROOT)) {
throw new IllegalPathException(
@@ -92,49 +80,6 @@ public abstract class Traverser {
this.startNode = startNode;
this.nodes = nodes;
this.store = store;
- this.traverseContext = new ArrayDeque<>();
- initStartIndexAndLevel(path);
- }
-
- /**
- * The traverser may start traversing from a storageGroupMNode, which is an InternalMNode of the
- * whole MTree.
- */
- private void initStartIndexAndLevel(PartialPath path) throws MetadataException {
- IMNode parent = startNode.getParent();
- Deque<IMNode> ancestors = new ArrayDeque<>();
- ancestors.push(startNode);
-
- startLevel = 0;
- while (parent != null) {
- startLevel++;
- traverseContext.addLast(parent);
-
- ancestors.push(parent);
- parent = parent.getParent();
- }
-
- IMNode cur;
- // given root.a.sg, accept path starting with prefix like root.a.sg, root.*.*, root.**,
- // root.a.**, which means the prefix matches the startNode's fullPath
- for (startIndex = 0; startIndex <= startLevel && startIndex < nodes.length; startIndex++) {
- cur = ancestors.pop();
- if (nodes[startIndex].equals(MULTI_LEVEL_PATH_WILDCARD)) {
- return;
- } else if (!nodes[startIndex].equals(cur.getName())
- && !nodes[startIndex].contains(ONE_LEVEL_PATH_WILDCARD)) {
- throw new IllegalPathException(
- path.getFullPath(), path.getFullPath() + " doesn't start with " + cur.getFullPath());
- }
- }
-
- if (startIndex <= startLevel) {
- if (!nodes[startIndex - 1].equals(MULTI_LEVEL_PATH_WILDCARD)) {
- isPrefixStart = true;
- }
- } else {
- startIndex--;
- }
}
/**
@@ -142,380 +87,61 @@ public abstract class Traverser {
* overriding or implement concerned methods.
*/
public void traverse() throws MetadataException {
- if (isPrefixStart && !isPrefixMatch) {
- return;
- }
- traverse(startNode, startIndex, startLevel);
- }
-
- /**
- * The recursive method for MTree traversal. If the node matches nodes[idx], then do some
- * operation and traverse the children with nodes[idx+1].
- *
- * @param node current node that match the targetName in given path
- * @param idx the index of targetName in given path
- * @param level the level of current node in MTree
- * @throws MetadataException some result process may throw MetadataException
- */
- protected void traverse(IMNode node, int idx, int level) throws MetadataException {
-
- if (processMatchedMNode(node, idx, level)) {
- return;
+ while (hasNext()) {
+ next();
}
-
- if (idx >= nodes.length - 1) {
- if (nodes[nodes.length - 1].equals(MULTI_LEVEL_PATH_WILDCARD) || isPrefixMatch) {
- processMultiLevelWildcard(node, idx, level);
- }
- return;
- }
-
- if (node.isMeasurement()) {
- return;
- }
-
- String targetName = nodes[idx + 1];
- if (MULTI_LEVEL_PATH_WILDCARD.equals(targetName)) {
- processMultiLevelWildcard(node, idx, level);
- } else if (targetName.contains(ONE_LEVEL_PATH_WILDCARD)) {
- processOneLevelWildcard(node, idx, level);
- } else {
- processNameMatch(node, idx, level);
+ if (!isSuccess()) {
+ Throwable e = getFailure();
+ throw new MetadataException(e.getMessage(), e);
}
}
- /**
- * process curNode that matches the targetName during traversal. there are two cases: 1. internal
- * match: root.sg internal match root.sg.**(pattern) 2. full match: root.sg.d full match
- * root.sg.**(pattern) Both of them are default abstract and should be implemented according
- * concrete tasks.
- *
- * @return whether this branch of recursive traversal should stop; if true, stop
- */
- private boolean processMatchedMNode(IMNode node, int idx, int level) throws MetadataException {
- if (idx < nodes.length - 1) {
- return processInternalMatchedMNode(node, idx, level);
+ @Override
+ protected IMNode getChild(IMNode parent, String childName) throws MetadataException {
+ IMNode child = null;
+ if (parent.isAboveDatabase()) {
+ child = parent.getChild(childName);
} else {
- return processFullMatchedMNode(node, idx, level);
- }
- }
-
- /**
- * internal match: root.sg internal match root.sg.**(pattern)
- *
- * @return whether this branch of recursive traversal should stop; if true, stop
- */
- protected abstract boolean processInternalMatchedMNode(IMNode node, int idx, int level)
- throws MetadataException;
-
- /**
- * full match: root.sg.d full match root.sg.**(pattern)
- *
- * @return whether this branch of recursive traversal should stop; if true, stop
- */
- protected abstract boolean processFullMatchedMNode(IMNode node, int idx, int level)
- throws MetadataException;
-
- protected void processMultiLevelWildcard(IMNode node, int idx, int level)
- throws MetadataException {
- if (isInTemplate) {
- traverseContext.push(node);
- for (IMNode child : node.getChildren().values()) {
- traverse(child, idx + 1, level + 1);
- }
- traverseContext.pop();
- return;
- }
-
- traverseContext.push(node);
- IMNode child;
- IMNodeIterator iterator = store.getChildrenIterator(node);
- try {
- while (iterator.hasNext()) {
- child = iterator.next();
- try {
- traverse(child, idx + 1, level + 1);
- } finally {
- store.unPin(child);
+ if (parent.getSchemaTemplateId() != NON_TEMPLATE) {
+ if (!skipPreDeletedSchema || !parent.getAsEntityMNode().isPreDeactivateTemplate()) {
+ child = templateMap.get(parent.getSchemaTemplateId()).getDirectNode(childName);
}
}
- } finally {
- iterator.close();
- }
-
- traverseContext.pop();
-
- if (!shouldTraverseTemplate) {
- return;
- }
-
- if (!node.isUseTemplate()) {
- return;
}
-
- Template schemaTemplate = getActivatedSchemaTemplate(node);
- if (schemaTemplate == null) {
- // template == null means the template used by this node is not related to this query in new
- // cluster.
- return;
+ if (child == null) {
+ child = store.getChild(parent, childName);
}
- isInTemplate = true;
- traverseContext.push(node);
- for (IMNode childInTemplate : schemaTemplate.getDirectNodes()) {
- traverse(childInTemplate, idx + 1, level + 1);
- }
- traverseContext.pop();
- isInTemplate = false;
+ return child;
}
- protected void processOneLevelWildcard(IMNode node, int idx, int level) throws MetadataException {
- boolean multiLevelWildcard = nodes[idx].equals(MULTI_LEVEL_PATH_WILDCARD);
- String targetNameRegex = nodes[idx + 1].replace("*", ".*");
-
- if (isInTemplate) {
- traverseContext.push(node);
- for (IMNode child : node.getChildren().values()) {
- if (!Pattern.matches(targetNameRegex, child.getName())) {
- continue;
- }
- traverse(child, idx + 1, level + 1);
- }
- traverseContext.pop();
-
- if (multiLevelWildcard) {
- traverseContext.push(node);
- for (IMNode child : node.getChildren().values()) {
- traverse(child, idx, level + 1);
- }
- traverseContext.pop();
- }
- return;
- }
-
- traverseContext.push(node);
- IMNode child;
- IMNodeIterator iterator = store.getChildrenIterator(node);
- try {
- while (iterator.hasNext()) {
- child = iterator.next();
- try {
- if (child.isMeasurement()) {
- String alias = child.getAsMeasurementMNode().getAlias();
- if (!Pattern.matches(targetNameRegex, child.getName())
- && !(alias != null && Pattern.matches(targetNameRegex, alias))) {
- continue;
- }
- } else {
- if (!Pattern.matches(targetNameRegex, child.getName())) {
- continue;
- }
- }
- traverse(child, idx + 1, level + 1);
- } finally {
- store.unPin(child);
- }
- }
- } finally {
- iterator.close();
- }
-
- traverseContext.pop();
-
- if (multiLevelWildcard) {
- traverseContext.push(node);
- iterator = store.getChildrenIterator(node);
- try {
- while (iterator.hasNext()) {
- child = iterator.next();
- try {
- traverse(child, idx, level + 1);
- } finally {
- store.unPin(child);
- }
- }
- } finally {
- iterator.close();
- }
- traverseContext.pop();
- }
-
- if (!shouldTraverseTemplate) {
- return;
- }
-
- if (!node.isUseTemplate()) {
- return;
- }
-
- Template schemaTemplate = getActivatedSchemaTemplate(node);
- if (schemaTemplate == null) {
- // template == null means the template used by this node is not related to this query in new
- // cluster.
- return;
+ @Override
+ protected void releaseNode(IMNode node) {
+ if (!node.isAboveDatabase() && !node.isStorageGroup()) {
+ // In any case we can call store#inpin directly because the unpin method will not do anything
+ // if it is an IMNode in template or in memory mode.
+ store.unPin(node);
}
- isInTemplate = true;
- traverseContext.push(node);
- for (IMNode childInTemplate : schemaTemplate.getDirectNodes()) {
- if (!Pattern.matches(targetNameRegex, childInTemplate.getName())) {
- continue;
- }
- traverse(childInTemplate, idx + 1, level + 1);
- }
- traverseContext.pop();
-
- if (multiLevelWildcard) {
- traverseContext.push(node);
- for (IMNode childInTemplate : schemaTemplate.getDirectNodes()) {
- traverse(childInTemplate, idx, level + 1);
- }
- traverseContext.pop();
- }
- isInTemplate = false;
}
- @SuppressWarnings("Duplicates")
- protected void processNameMatch(IMNode node, int idx, int level) throws MetadataException {
- boolean multiLevelWildcard = nodes[idx].equals(MULTI_LEVEL_PATH_WILDCARD);
- String targetName = nodes[idx + 1];
-
- if (isInTemplate) {
- IMNode targetNode = node.getChild(targetName);
- if (targetNode != null) {
- traverseContext.push(node);
- traverse(targetNode, idx + 1, level + 1);
- traverseContext.pop();
- }
-
- if (multiLevelWildcard) {
- traverseContext.push(node);
- for (IMNode child : node.getChildren().values()) {
- traverse(child, idx, level + 1);
- }
- traverseContext.pop();
- }
- return;
- }
-
- IMNode next = store.getChild(node, targetName);
- if (next != null) {
- try {
- traverseContext.push(node);
- traverse(next, idx + 1, level + 1);
- traverseContext.pop();
- } finally {
- store.unPin(next);
- }
- }
-
- if (multiLevelWildcard) {
- traverseContext.push(node);
- IMNode child;
- IMNodeIterator iterator = store.getChildrenIterator(node);
- try {
- while (iterator.hasNext()) {
- child = iterator.next();
- try {
- traverse(child, idx, level + 1);
- } finally {
- store.unPin(child);
- }
- }
- } finally {
- iterator.close();
- }
- traverseContext.pop();
- }
-
- if (!shouldTraverseTemplate) {
- return;
- }
-
- if (!node.isUseTemplate()) {
- return;
- }
-
- Template schemaTemplate = getActivatedSchemaTemplate(node);
- if (schemaTemplate == null) {
- // template == null means the template used by this node is not related to this query in new
- // cluster.
- return;
- }
- isInTemplate = true;
- IMNode targetNode = schemaTemplate.getDirectNode(targetName);
- if (targetNode != null) {
- traverseContext.push(node);
- traverse(targetNode, idx + 1, level + 1);
- traverseContext.pop();
- }
-
- if (multiLevelWildcard) {
- traverseContext.push(node);
- for (IMNode child : schemaTemplate.getDirectNodes()) {
- traverse(child, idx, level + 1);
- }
- traverseContext.pop();
+ @Override
+ protected Iterator<IMNode> getChildrenIterator(IMNode parent) throws MetadataException {
+ if (parent.isAboveDatabase()) {
+ return new MNodeIterator(parent.getChildren().values().iterator());
+ } else {
+ return store.getTraverserIterator(parent, templateMap, skipPreDeletedSchema);
}
- isInTemplate = false;
}
- protected Template getActivatedSchemaTemplate(IMNode node) {
- // new cluster, the used template is directly recorded as template id in device mnode
- if (node.getSchemaTemplateId() != NON_TEMPLATE) {
- if (skipPreDeletedSchema && node.getAsEntityMNode().isPreDeactivateTemplate()) {
- // skip this pre deactivated template, the invoker will skip this
- return null;
- }
- return templateMap.get(node.getSchemaTemplateId());
- }
- // if the node is usingTemplate, the upperTemplate won't be null or the upperTemplateId won't be
- // NON_TEMPLATE.
- throw new IllegalStateException(
- String.format(
- "There should be a template mounted on any ancestor of the node [%s] usingTemplate.",
- node.getFullPath()));
+ @Override
+ protected void releaseNodeIterator(Iterator<IMNode> nodeIterator) {
+ ((IMNodeIterator) nodeIterator).close();
}
public void setTemplateMap(Map<Integer, Template> templateMap) {
this.templateMap = templateMap;
}
- public void setPrefixMatch(boolean isPrefixMatch) {
- this.isPrefixMatch = isPrefixMatch;
- }
-
- public void setShouldTraverseTemplate(boolean shouldTraverseTemplate) {
- this.shouldTraverseTemplate = shouldTraverseTemplate;
- }
-
public void setSkipPreDeletedSchema(boolean skipPreDeletedSchema) {
this.skipPreDeletedSchema = skipPreDeletedSchema;
}
-
- /**
- * @param currentNode the node need to get the full path of
- * @return full path from traverse start node to the current node
- */
- protected PartialPath getCurrentPartialPath(IMNode currentNode) {
- return new PartialPath(getCurrentPathNodes(currentNode));
- }
-
- protected String[] getCurrentPathNodes(IMNode currentNode) {
- Iterator<IMNode> nodes = traverseContext.descendingIterator();
- List<String> nodeNames = new LinkedList<>();
- if (nodes.hasNext()) {
- nodeNames.addAll(Arrays.asList(nodes.next().getPartialPath().getNodes()));
- }
-
- while (nodes.hasNext()) {
- nodeNames.add(nodes.next().getName());
- }
-
- nodeNames.add(currentNode.getName());
-
- return nodeNames.toArray(new String[0]);
- }
-
- protected IMNode getCurrentNodeParent() {
- return traverseContext.peek();
- }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/TraverserWithLimitOffsetWrapper.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/TraverserWithLimitOffsetWrapper.java
new file mode 100644
index 0000000000..f43468756e
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/TraverserWithLimitOffsetWrapper.java
@@ -0,0 +1,122 @@
+/*
+ * 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.mtree.traverser;
+
+import org.apache.iotdb.commons.exception.MetadataException;
+import org.apache.iotdb.db.metadata.mnode.IMNode;
+
+import java.util.NoSuchElementException;
+
+public class TraverserWithLimitOffsetWrapper<R> extends Traverser<R> {
+ private final Traverser<R> traverser;
+ private final int limit;
+ private final int offset;
+ private final boolean hasLimit;
+
+ private int count = 0;
+ int curOffset = 0;
+
+ public TraverserWithLimitOffsetWrapper(Traverser<R> traverser, int limit, int offset) {
+ this.traverser = traverser;
+ this.limit = limit;
+ this.offset = offset;
+ hasLimit = limit > 0 || offset > 0;
+
+ if (hasLimit) {
+ while (curOffset < offset && traverser.hasNext()) {
+ traverser.next();
+ curOffset++;
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (hasLimit) {
+ return count < limit && traverser.hasNext();
+ } else {
+ return traverser.hasNext();
+ }
+ }
+
+ @Override
+ public R next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ R result = traverser.next();
+ if (hasLimit) {
+ count++;
+ }
+ return result;
+ }
+
+ @Override
+ public void traverse() throws MetadataException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected boolean shouldVisitSubtreeOfInternalMatchedNode(IMNode node) {
+ return false;
+ }
+
+ @Override
+ protected boolean shouldVisitSubtreeOfFullMatchedNode(IMNode node) {
+ return false;
+ }
+
+ @Override
+ protected boolean acceptInternalMatchedNode(IMNode node) {
+ return false;
+ }
+
+ @Override
+ protected boolean acceptFullMatchedNode(IMNode node) {
+ return false;
+ }
+
+ @Override
+ protected R generateResult(IMNode nextMatchedNode) {
+ return null;
+ }
+
+ @Override
+ public void close() {
+ traverser.close();
+ }
+
+ @Override
+ public void reset() {
+ traverser.reset();
+ count = 0;
+ curOffset = 0;
+ if (hasLimit) {
+ while (curOffset < offset && traverser.hasNext()) {
+ traverser.next();
+ curOffset++;
+ }
+ }
+ }
+
+ public int getNextOffset() {
+ return curOffset + count;
+ }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/StorageGroupCollector.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/basic/DatabaseTraverser.java
similarity index 53%
copy from server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/StorageGroupCollector.java
copy to server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/basic/DatabaseTraverser.java
index 2017efbb5f..9a177b4a76 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/StorageGroupCollector.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/basic/DatabaseTraverser.java
@@ -16,45 +16,52 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.iotdb.db.metadata.mtree.traverser.collector;
+package org.apache.iotdb.db.metadata.mtree.traverser.basic;
import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.metadata.mnode.IMNode;
-import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
+import org.apache.iotdb.db.metadata.mtree.traverser.Traverser;
-// This class implements database path collection function.
-public abstract class StorageGroupCollector<T> extends CollectorTraverser<T> {
+public abstract class DatabaseTraverser<R> extends Traverser<R> {
protected boolean collectInternal = false;
- protected StorageGroupCollector(IMNode startNode, PartialPath path, IMTreeStore store)
+ /**
+ * To traverse subtree under root.sg, e.g., init Traverser(root, "root.sg.**")
+ *
+ * @param startNode denote which tree to traverse by passing its root
+ * @param path use wildcard to specify which part to traverse
+ * @param store
+ * @param isPrefixMatch
+ * @throws MetadataException
+ */
+ public DatabaseTraverser(
+ IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
throws MetadataException {
- super(startNode, path, store);
+ super(startNode, path, store, isPrefixMatch);
}
@Override
- protected boolean processInternalMatchedMNode(IMNode node, int idx, int level) {
- if (node.isStorageGroup()) {
- if (collectInternal) {
- collectStorageGroup(node.getAsStorageGroupMNode());
- }
- return true;
- }
- return false;
+ protected boolean acceptFullMatchedNode(IMNode node) {
+ return node.isStorageGroup();
}
@Override
- protected boolean processFullMatchedMNode(IMNode node, int idx, int level) {
- if (node.isStorageGroup()) {
- collectStorageGroup(node.getAsStorageGroupMNode());
- return true;
- }
- return false;
+ protected boolean acceptInternalMatchedNode(IMNode node) {
+ return collectInternal && node.isStorageGroup();
}
- protected abstract void collectStorageGroup(IStorageGroupMNode node);
+ @Override
+ protected boolean shouldVisitSubtreeOfFullMatchedNode(IMNode node) {
+ return !node.isStorageGroup();
+ }
+
+ @Override
+ protected boolean shouldVisitSubtreeOfInternalMatchedNode(IMNode node) {
+ return !node.isStorageGroup();
+ }
public void setCollectInternal(boolean collectInternal) {
this.collectInternal = collectInternal;
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/EntityCollector.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/basic/EntityTraverser.java
similarity index 53%
copy from server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/EntityCollector.java
copy to server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/basic/EntityTraverser.java
index 3f324f037f..54fb6c6d93 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/EntityCollector.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/basic/EntityTraverser.java
@@ -16,61 +16,59 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.iotdb.db.metadata.mtree.traverser.collector;
+package org.apache.iotdb.db.metadata.mtree.traverser.basic;
import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
+import org.apache.iotdb.db.metadata.mtree.traverser.Traverser;
-// This class defines EntityMNode as target node and defines the Entity process framework.
-public abstract class EntityCollector<T> extends CollectorTraverser<T> {
+public abstract class EntityTraverser<R> extends Traverser<R> {
private boolean usingTemplate = false;
private int schemaTemplateId = -1;
- protected EntityCollector(IMNode startNode, PartialPath path, IMTreeStore store)
+ /**
+ * To traverse subtree under root.sg, e.g., init Traverser(root, "root.sg.**")
+ *
+ * @param startNode denote which tree to traverse by passing its root
+ * @param path use wildcard to specify which part to traverse
+ * @param store
+ * @param isPrefixMatch
+ * @throws MetadataException
+ */
+ public EntityTraverser(
+ IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
throws MetadataException {
- super(startNode, path, store);
+ super(startNode, path, store, isPrefixMatch);
}
- protected EntityCollector(
- IMNode startNode, PartialPath path, IMTreeStore store, int limit, int offset)
- throws MetadataException {
- super(startNode, path, store, limit, offset);
+ @Override
+ protected boolean acceptFullMatchedNode(IMNode node) {
+ if (node.isEntity()) {
+ return !usingTemplate || schemaTemplateId == node.getSchemaTemplateId();
+ }
+ return false;
}
@Override
- protected boolean processInternalMatchedMNode(IMNode node, int idx, int level) {
+ protected boolean acceptInternalMatchedNode(IMNode node) {
return false;
}
@Override
- protected boolean processFullMatchedMNode(IMNode node, int idx, int level)
- throws MetadataException {
- if (node.isEntity()) {
- if (usingTemplate && schemaTemplateId != node.getSchemaTemplateId()) {
- return false;
- }
- if (hasLimit) {
- curOffset += 1;
- if (curOffset < offset) {
- return true;
- }
- }
- collectEntity(node.getAsEntityMNode());
- if (hasLimit) {
- count += 1;
- }
- }
- return false;
+ protected boolean shouldVisitSubtreeOfFullMatchedNode(IMNode node) {
+ return !node.isMeasurement();
+ }
+
+ @Override
+ protected boolean shouldVisitSubtreeOfInternalMatchedNode(IMNode node) {
+ return !node.isMeasurement();
}
public void setSchemaTemplateFilter(int schemaTemplateId) {
this.usingTemplate = true;
this.schemaTemplateId = schemaTemplateId;
}
-
- protected abstract void collectEntity(IEntityMNode node) throws MetadataException;
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/basic/MNodeTraverser.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/basic/MNodeTraverser.java
new file mode 100644
index 0000000000..3c19bbb50f
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/basic/MNodeTraverser.java
@@ -0,0 +1,103 @@
+/*
+ * 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.mtree.traverser.basic;
+
+import org.apache.iotdb.commons.exception.MetadataException;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.metadata.mnode.IMNode;
+import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
+import org.apache.iotdb.db.metadata.mtree.traverser.Traverser;
+
+/**
+ * This class defines any node in MTree as potential target node. On finding a path matching the
+ * given pattern, if a level is specified and the path is longer than the specified level,
+ * MNodeTraverser finds the node of the specified level on the path and process it. The same node
+ * will not be processed more than once. If a level is not given, the current node is processed.
+ */
+public abstract class MNodeTraverser<R> extends Traverser<R> {
+
+ // Level query option started from 0. For example, level of root.sg.d1.s1 is 3.
+ protected int targetLevel = -1;
+ protected IMNode lastVisitNode = null;
+
+ /**
+ * To traverse subtree under root.sg, e.g., init Traverser(root, "root.sg.**")
+ *
+ * @param startNode denote which tree to traverse by passing its root
+ * @param path use wildcard to specify which part to traverse
+ * @param store
+ * @param isPrefixMatch
+ * @throws MetadataException
+ */
+ public MNodeTraverser(
+ IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
+ throws MetadataException {
+ super(startNode, path, store, isPrefixMatch);
+ }
+
+ @Override
+ protected boolean acceptFullMatchedNode(IMNode node) {
+ if (targetLevel >= 0) {
+ if (getSizeOfAncestor() > targetLevel) {
+ return getAncestorNodeByLevel(targetLevel) != lastVisitNode;
+ } else if (getSizeOfAncestor() == targetLevel) {
+ return node != lastVisitNode;
+ } else {
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
+
+ @Override
+ protected boolean acceptInternalMatchedNode(IMNode node) {
+ return false;
+ }
+
+ @Override
+ protected boolean shouldVisitSubtreeOfFullMatchedNode(IMNode node) {
+ return !node.isMeasurement();
+ }
+
+ @Override
+ protected boolean shouldVisitSubtreeOfInternalMatchedNode(IMNode node) {
+ return !node.isMeasurement();
+ }
+
+ public void setTargetLevel(int targetLevel) {
+ this.targetLevel = targetLevel;
+ }
+
+ @Override
+ protected final R generateResult(IMNode nextMatchedNode) {
+ if (targetLevel >= 0) {
+ if (getLevelOfNextMatchedNode() == targetLevel) {
+ lastVisitNode = nextMatchedNode;
+ } else {
+ lastVisitNode = getAncestorNodeByLevel(targetLevel);
+ }
+ return transferToResult(lastVisitNode);
+ } else {
+ return transferToResult(nextMatchedNode);
+ }
+ }
+
+ protected abstract R transferToResult(IMNode node);
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/CounterTraverser.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/basic/MeasurementTraverser.java
similarity index 52%
rename from server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/CounterTraverser.java
rename to server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/basic/MeasurementTraverser.java
index b1312cfb58..1cc7dc6b1a 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/CounterTraverser.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/basic/MeasurementTraverser.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.iotdb.db.metadata.mtree.traverser.counter;
+package org.apache.iotdb.db.metadata.mtree.traverser.basic;
import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.path.PartialPath;
@@ -24,17 +24,40 @@ import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
import org.apache.iotdb.db.metadata.mtree.traverser.Traverser;
-// This class define the count as traversal result.
-public abstract class CounterTraverser extends Traverser {
+public abstract class MeasurementTraverser<R> extends Traverser<R> {
- protected long count;
-
- protected CounterTraverser(IMNode startNode, PartialPath path, IMTreeStore store)
+ /**
+ * To traverse subtree under root.sg, e.g., init Traverser(root, "root.sg.**")
+ *
+ * @param startNode denote which tree to traverse by passing its root
+ * @param path use wildcard to specify which part to traverse
+ * @param store
+ * @param isPrefixMatch
+ * @throws MetadataException
+ */
+ public MeasurementTraverser(
+ IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
throws MetadataException {
- super(startNode, path, store);
+ super(startNode, path, store, isPrefixMatch);
+ }
+
+ @Override
+ protected boolean acceptFullMatchedNode(IMNode node) {
+ return node.isMeasurement();
+ }
+
+ @Override
+ protected boolean acceptInternalMatchedNode(IMNode node) {
+ return false;
+ }
+
+ @Override
+ protected boolean shouldVisitSubtreeOfFullMatchedNode(IMNode node) {
+ return !node.isMeasurement();
}
- public long getCount() {
- return count;
+ @Override
+ protected boolean shouldVisitSubtreeOfInternalMatchedNode(IMNode node) {
+ return !node.isMeasurement();
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/CollectorTraverser.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/CollectorTraverser.java
deleted file mode 100644
index fe9d70db98..0000000000
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/CollectorTraverser.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.mtree.traverser.collector;
-
-import org.apache.iotdb.commons.exception.MetadataException;
-import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.IMNode;
-import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
-import org.apache.iotdb.db.metadata.mtree.traverser.Traverser;
-
-// This class defines the generic resultSet as traversal result and add more restrictions on MTree
-// traversal.
-public abstract class CollectorTraverser<T> extends Traverser {
-
- // used for implement slimit and offset function in DDL
- protected int limit;
- protected int offset;
-
- protected boolean hasLimit = false;
- protected int count = 0;
- protected int curOffset = -1;
-
- protected T resultSet;
-
- public CollectorTraverser(IMNode startNode, PartialPath path, IMTreeStore store)
- throws MetadataException {
- super(startNode, path, store);
- }
-
- public CollectorTraverser(
- IMNode startNode, PartialPath path, IMTreeStore store, int limit, int offset)
- throws MetadataException {
- super(startNode, path, store);
- this.limit = limit;
- this.offset = offset;
- if (limit > 0 || offset > 0) {
- hasLimit = true;
- }
- }
-
- /** extends traversal with limit restriction */
- @Override
- protected void traverse(IMNode node, int idx, int level) throws MetadataException {
- if (hasLimit && count == limit) {
- return;
- }
- super.traverse(node, idx, level);
- }
-
- /**
- * After invoke traverse(), this method could be invoked to get result
- *
- * @return the traversal result
- */
- public T getResult() {
- return resultSet;
- }
-
- public void setResultSet(T resultSet) {
- this.resultSet = resultSet;
- }
-
- public int getCurOffset() {
- return curOffset;
- }
-
- public void setLimit(int limit) {
- this.limit = limit;
- if (limit > 0) {
- hasLimit = true;
- }
- }
-
- public void setOffset(int offset) {
- this.offset = offset;
- if (offset > 0) {
- hasLimit = true;
- }
- }
-}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/StorageGroupCollector.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/DatabaseCollector.java
similarity index 58%
rename from server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/StorageGroupCollector.java
rename to server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/DatabaseCollector.java
index 2017efbb5f..ea3762f1dc 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/StorageGroupCollector.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/DatabaseCollector.java
@@ -23,40 +23,22 @@ import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
+import org.apache.iotdb.db.metadata.mtree.traverser.basic.DatabaseTraverser;
// This class implements database path collection function.
-public abstract class StorageGroupCollector<T> extends CollectorTraverser<T> {
-
- protected boolean collectInternal = false;
-
- protected StorageGroupCollector(IMNode startNode, PartialPath path, IMTreeStore store)
+public abstract class DatabaseCollector<R> extends DatabaseTraverser<R> {
+ protected DatabaseCollector(
+ IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
throws MetadataException {
- super(startNode, path, store);
+ super(startNode, path, store, isPrefixMatch);
}
@Override
- protected boolean processInternalMatchedMNode(IMNode node, int idx, int level) {
- if (node.isStorageGroup()) {
- if (collectInternal) {
- collectStorageGroup(node.getAsStorageGroupMNode());
- }
- return true;
- }
- return false;
+ protected R generateResult(IMNode nextMatchedNode) {
+ collectDatabase(nextMatchedNode.getAsStorageGroupMNode());
+ return null;
}
- @Override
- protected boolean processFullMatchedMNode(IMNode node, int idx, int level) {
- if (node.isStorageGroup()) {
- collectStorageGroup(node.getAsStorageGroupMNode());
- return true;
- }
- return false;
- }
-
- protected abstract void collectStorageGroup(IStorageGroupMNode node);
-
- public void setCollectInternal(boolean collectInternal) {
- this.collectInternal = collectInternal;
- }
+ // TODO: make collectDatabase return R
+ protected abstract void collectDatabase(IStorageGroupMNode node);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/EntityCollector.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/EntityCollector.java
index 3f324f037f..1756daf271 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/EntityCollector.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/EntityCollector.java
@@ -23,54 +23,22 @@ import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
+import org.apache.iotdb.db.metadata.mtree.traverser.basic.EntityTraverser;
// This class defines EntityMNode as target node and defines the Entity process framework.
-public abstract class EntityCollector<T> extends CollectorTraverser<T> {
-
- private boolean usingTemplate = false;
- private int schemaTemplateId = -1;
-
- protected EntityCollector(IMNode startNode, PartialPath path, IMTreeStore store)
- throws MetadataException {
- super(startNode, path, store);
- }
+// TODO: set R is IDeviceSchemaInfo
+public abstract class EntityCollector<R> extends EntityTraverser<R> {
protected EntityCollector(
- IMNode startNode, PartialPath path, IMTreeStore store, int limit, int offset)
+ IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
throws MetadataException {
- super(startNode, path, store, limit, offset);
- }
-
- @Override
- protected boolean processInternalMatchedMNode(IMNode node, int idx, int level) {
- return false;
+ super(startNode, path, store, isPrefixMatch);
}
@Override
- protected boolean processFullMatchedMNode(IMNode node, int idx, int level)
- throws MetadataException {
- if (node.isEntity()) {
- if (usingTemplate && schemaTemplateId != node.getSchemaTemplateId()) {
- return false;
- }
- if (hasLimit) {
- curOffset += 1;
- if (curOffset < offset) {
- return true;
- }
- }
- collectEntity(node.getAsEntityMNode());
- if (hasLimit) {
- count += 1;
- }
- }
- return false;
- }
-
- public void setSchemaTemplateFilter(int schemaTemplateId) {
- this.usingTemplate = true;
- this.schemaTemplateId = schemaTemplateId;
+ protected R generateResult(IMNode nextMatchedNode) {
+ return collectEntity(nextMatchedNode.getAsEntityMNode());
}
- protected abstract void collectEntity(IEntityMNode node) throws MetadataException;
+ protected abstract R collectEntity(IEntityMNode node);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MNodeAboveSGCollector.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MNodeAboveSGCollector.java
index f97fe38d74..06ae88d87b 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MNodeAboveSGCollector.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MNodeAboveSGCollector.java
@@ -30,29 +30,30 @@ public abstract class MNodeAboveSGCollector<T> extends MNodeCollector<T> {
protected Set<PartialPath> involvedStorageGroupMNodes = new HashSet<>();
- protected MNodeAboveSGCollector(IMNode startNode, PartialPath path, IMTreeStore store)
+ protected MNodeAboveSGCollector(
+ IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
throws MetadataException {
- super(startNode, path, store);
+ super(startNode, path, store, isPrefixMatch);
}
@Override
- protected boolean processInternalMatchedMNode(IMNode node, int idx, int level) {
- boolean shouldSkipSubtree = super.processInternalMatchedMNode(node, idx, level);
+ protected boolean shouldVisitSubtreeOfFullMatchedNode(IMNode node) {
if (node.isStorageGroup()) {
- involvedStorageGroupMNodes.add(node.getPartialPath());
- return true;
+ involvedStorageGroupMNodes.add(getParentPartialPath().concatNode(node.getName()));
+ return false;
+ } else {
+ return super.shouldVisitSubtreeOfFullMatchedNode(node);
}
- return shouldSkipSubtree;
}
@Override
- protected boolean processFullMatchedMNode(IMNode node, int idx, int level) {
- boolean shouldSkipSubtree = super.processFullMatchedMNode(node, idx, level);
+ protected boolean shouldVisitSubtreeOfInternalMatchedNode(IMNode node) {
if (node.isStorageGroup()) {
- involvedStorageGroupMNodes.add(node.getPartialPath());
- return true;
+ involvedStorageGroupMNodes.add(getParentPartialPath().concatNode(node.getName()));
+ return false;
+ } else {
+ return super.shouldVisitSubtreeOfInternalMatchedNode(node);
}
- return shouldSkipSubtree;
}
public Set<PartialPath> getInvolvedStorageGroupMNodes() {
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MNodeCollector.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MNodeCollector.java
index 53c57eea7c..5104f778b7 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MNodeCollector.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MNodeCollector.java
@@ -22,11 +22,7 @@ import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
-
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.HashSet;
-import java.util.Set;
+import org.apache.iotdb.db.metadata.mtree.traverser.basic.MNodeTraverser;
/**
* This class defines any node in MTree as potential target node. On finding a path matching the
@@ -34,54 +30,18 @@ import java.util.Set;
* MNodeLevelCounter finds the node of the specified level on the path and process it. The same node
* will not be processed more than once. If a level is not given, the current node is processed.
*/
-public abstract class MNodeCollector<T> extends CollectorTraverser<T> {
-
- // level query option
- protected int targetLevel = -1;
+// TODO: set R to IMNodeInfo
+public abstract class MNodeCollector<R> extends MNodeTraverser<R> {
- private Set<IMNode> processedNodes = new HashSet<>();
-
- protected MNodeCollector(IMNode startNode, PartialPath path, IMTreeStore store)
+ protected MNodeCollector(
+ IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
throws MetadataException {
- super(startNode, path, store);
+ super(startNode, path, store, isPrefixMatch);
}
- @Override
- protected boolean processInternalMatchedMNode(IMNode node, int idx, int level) {
- return false;
+ protected final R transferToResult(IMNode node) {
+ return collectMNode(node);
}
- @Override
- protected boolean processFullMatchedMNode(IMNode node, int idx, int level) {
- if (targetLevel >= 0) {
- // move the cursor the given level when matched
- if (level < targetLevel) {
- return false;
- }
- Deque<IMNode> stack = new ArrayDeque<>();
- while (level > targetLevel) {
- node = traverseContext.pop();
- stack.push(node);
- level--;
- }
- // record processed node so they will not be processed twice
- if (!processedNodes.contains(node)) {
- processedNodes.add(node);
- transferToResult(node);
- }
- while (!stack.isEmpty()) {
- traverseContext.push(stack.pop());
- }
- return true;
- } else {
- transferToResult(node);
- }
- return false;
- }
-
- protected abstract void transferToResult(IMNode node);
-
- public void setTargetLevel(int targetLevel) {
- this.targetLevel = targetLevel;
- }
+ protected abstract R collectMNode(IMNode node);
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MeasurementCollector.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MeasurementCollector.java
index c8453cc5ac..ff488befbb 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MeasurementCollector.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/collector/MeasurementCollector.java
@@ -24,54 +24,21 @@ import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
+import org.apache.iotdb.db.metadata.mtree.traverser.basic.MeasurementTraverser;
// This class defines MeasurementMNode as target node and defines the measurement process framework.
-public abstract class MeasurementCollector<T> extends CollectorTraverser<T> {
-
- protected MeasurementCollector(IMNode startNode, PartialPath path, IMTreeStore store)
- throws MetadataException {
- super(startNode, path, store);
- shouldTraverseTemplate = true;
- }
-
- protected MeasurementCollector(
- IMNode startNode, PartialPath path, IMTreeStore store, boolean shouldTraverseTemplate)
- throws MetadataException {
- super(startNode, path, store);
- this.shouldTraverseTemplate = shouldTraverseTemplate;
- }
+// TODO: set R is ITimeseriesInfo
+public abstract class MeasurementCollector<R> extends MeasurementTraverser<R> {
protected MeasurementCollector(
- IMNode startNode, PartialPath path, IMTreeStore store, int limit, int offset)
+ IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
throws MetadataException {
- super(startNode, path, store, limit, offset);
- shouldTraverseTemplate = true;
+ super(startNode, path, store, isPrefixMatch);
}
@Override
- protected boolean processInternalMatchedMNode(IMNode node, int idx, int level)
- throws MetadataException {
- return false;
- }
-
- @Override
- protected boolean processFullMatchedMNode(IMNode node, int idx, int level)
- throws MetadataException {
- if (!node.isMeasurement()
- || (skipPreDeletedSchema && node.getAsMeasurementMNode().isPreDeleted())) {
- return false;
- }
- if (hasLimit) {
- curOffset += 1;
- if (curOffset < offset) {
- return true;
- }
- }
- collectMeasurement(node.getAsMeasurementMNode());
- if (hasLimit) {
- count += 1;
- }
- return true;
+ protected R generateResult(IMNode nextMatchedNode) {
+ return collectMeasurement(nextMatchedNode.getAsMeasurementMNode());
}
/**
@@ -79,7 +46,7 @@ public abstract class MeasurementCollector<T> extends CollectorTraverser<T> {
*
* @param node MeasurementMNode holding the measurement schema
*/
- protected abstract void collectMeasurement(IMeasurementMNode node) throws MetadataException;
+ protected abstract R collectMeasurement(IMeasurementMNode node);
/**
* When traverse goes into a template, IMNode.getPartialPath may not work as nodes in template has
@@ -87,15 +54,10 @@ public abstract class MeasurementCollector<T> extends CollectorTraverser<T> {
* stack traverseContext.
*/
protected MeasurementPath getCurrentMeasurementPathInTraverse(IMeasurementMNode currentNode) {
- IMNode par = traverseContext.peek();
+ IMNode par = getParentOfNextMatchedNode();
MeasurementPath retPath =
- new MeasurementPath(
- new PartialPath(getCurrentPathNodes(currentNode)), currentNode.getSchema());
+ new MeasurementPath(getPartialPathFromRootToNode(currentNode), currentNode.getSchema());
retPath.setUnderAlignedEntity(par.getAsEntityMNode().isAligned());
return retPath;
}
-
- protected boolean isUnderAlignedEntity() {
- return traverseContext.peek().getAsEntityMNode().isAligned();
- }
}
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/ITreeNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/Counter.java
similarity index 80%
copy from node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/ITreeNode.java
copy to server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/Counter.java
index 900e943fbd..e439dc9e1d 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/ITreeNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/Counter.java
@@ -16,10 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
+package org.apache.iotdb.db.metadata.mtree.traverser.counter;
-package org.apache.iotdb.commons.schema.tree;
+import org.apache.iotdb.commons.exception.MetadataException;
-public interface ITreeNode {
-
- String getName();
+public interface Counter {
+ long count() throws MetadataException;
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/StorageGroupCounter.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/DatabaseCounter.java
similarity index 62%
copy from server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/StorageGroupCounter.java
copy to server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/DatabaseCounter.java
index 98d6413e47..0e7b589317 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/StorageGroupCounter.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/DatabaseCounter.java
@@ -22,27 +22,34 @@ import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
+import org.apache.iotdb.db.metadata.mtree.traverser.basic.DatabaseTraverser;
-// This class implements database count function.
-public class StorageGroupCounter extends CounterTraverser {
+// This class implement database counter.
+public class DatabaseCounter extends DatabaseTraverser<Void> implements Counter {
- public StorageGroupCounter(IMNode startNode, PartialPath path, IMTreeStore store)
+ private int count;
+
+ public DatabaseCounter(
+ IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
throws MetadataException {
- super(startNode, path, store);
+ super(startNode, path, store, isPrefixMatch);
}
@Override
- protected boolean processInternalMatchedMNode(IMNode node, int idx, int level) {
- return node.isStorageGroup();
+ protected Void generateResult(IMNode nextMatchedNode) {
+ count++;
+ return null;
}
@Override
- protected boolean processFullMatchedMNode(IMNode node, int idx, int level) {
- if (node.isStorageGroup()) {
- count++;
- return true;
- } else {
- return false;
+ public long count() throws MetadataException {
+ while (hasNext()) {
+ next();
+ }
+ if (!isSuccess()) {
+ Throwable e = getFailure();
+ throw new MetadataException(e.getMessage(), e);
}
+ return count;
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/StorageGroupCounter.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/EntityCounter.java
similarity index 63%
rename from server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/StorageGroupCounter.java
rename to server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/EntityCounter.java
index 98d6413e47..3feaa46b58 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/StorageGroupCounter.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/counter/EntityCounter.java
@@ -22,27 +22,32 @@ import org.apache.iotdb.commons.exception.MetadataException;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
+import org.apache.iotdb.db.metadata.mtree.traverser.basic.EntityTraverser;
-// This class implements database count function.
-public class StorageGroupCounter extends CounterTraverser {
+// This class implement entity counter.
+public class EntityCounter extends EntityTraverser<Void> implements Counter {
+ private int count;
- public StorageGroupCounter(IMNode startNode, PartialPath path, IMTreeStore store)
+ public EntityCounter(IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
throws MetadataException {
- super(startNode, path, store);
+ super(startNode, path, store, isPrefixMatch);
}
@Override
- protected boolean processInternalMatchedMNode(IMNode node, int idx, int level) {
- return node.isStorageGroup();
+ protected Void generateResult(IMNode nextMatchedNode) {
+ count++;
+ return null;
}
@Override
- protected boolean processFullMatchedMNode(IMNode node, int idx, int level) {
- if (node.isStorageGroup()) {
- count++;
- return true;
- } else {
- return false;
+ public long count() throws MetadataException {
+ while (hasNext()) {
+ next();
}
+ if (!isSuccess()) {
+ Throwable e = getFailure();
+ throw new MetadataException(e.getMessage(), e);
+ }
+ return count;
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/updater/EntityUpdater.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/updater/EntityUpdater.java
new file mode 100644
index 0000000000..64a822d4ee
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/updater/EntityUpdater.java
@@ -0,0 +1,65 @@
+/*
+ * 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.mtree.traverser.updater;
+
+import org.apache.iotdb.commons.exception.MetadataException;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.metadata.mnode.IEntityMNode;
+import org.apache.iotdb.db.metadata.mnode.IMNode;
+import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
+import org.apache.iotdb.db.metadata.mtree.traverser.basic.EntityTraverser;
+
+public abstract class EntityUpdater extends EntityTraverser<Void> implements Updater {
+ /**
+ * To traverse subtree under root.sg, e.g., init Traverser(root, "root.sg.**")
+ *
+ * @param startNode denote which tree to traverse by passing its root
+ * @param path use wildcard to specify which part to traverse
+ * @param store
+ * @param isPrefixMatch
+ * @throws MetadataException
+ */
+ public EntityUpdater(IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
+ throws MetadataException {
+ super(startNode, path, store, isPrefixMatch);
+ }
+
+ @Override
+ protected Void generateResult(IMNode nextMatchedNode) {
+ try {
+ updateEntity(nextMatchedNode.getAsEntityMNode());
+ } catch (MetadataException e) {
+ setFailure(e);
+ }
+ return null;
+ }
+
+ @Override
+ public void update() throws MetadataException {
+ while (super.hasNext()) {
+ super.next();
+ }
+ if (!isSuccess()) {
+ Throwable e = getFailure();
+ throw new MetadataException(e.getMessage(), e);
+ }
+ }
+
+ protected abstract void updateEntity(IEntityMNode node) throws MetadataException;
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/updater/MeasurementUpdater.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/updater/MeasurementUpdater.java
new file mode 100644
index 0000000000..2dd84d202b
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/updater/MeasurementUpdater.java
@@ -0,0 +1,66 @@
+/*
+ * 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.mtree.traverser.updater;
+
+import org.apache.iotdb.commons.exception.MetadataException;
+import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.db.metadata.mnode.IMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.mtree.store.IMTreeStore;
+import org.apache.iotdb.db.metadata.mtree.traverser.basic.MeasurementTraverser;
+
+public abstract class MeasurementUpdater extends MeasurementTraverser<Void> implements Updater {
+ /**
+ * To traverse subtree under root.sg, e.g., init Traverser(root, "root.sg.**")
+ *
+ * @param startNode denote which tree to traverse by passing its root
+ * @param path use wildcard to specify which part to traverse
+ * @param store
+ * @param isPrefixMatch
+ * @throws MetadataException
+ */
+ public MeasurementUpdater(
+ IMNode startNode, PartialPath path, IMTreeStore store, boolean isPrefixMatch)
+ throws MetadataException {
+ super(startNode, path, store, isPrefixMatch);
+ }
+
+ @Override
+ protected Void generateResult(IMNode nextMatchedNode) {
+ try {
+ updateMeasurement(nextMatchedNode.getAsMeasurementMNode());
+ } catch (MetadataException e) {
+ setFailure(e);
+ }
+ return null;
+ }
+
+ @Override
+ public void update() throws MetadataException {
+ while (super.hasNext()) {
+ super.next();
+ }
+ if (!isSuccess()) {
+ Throwable e = getFailure();
+ throw new MetadataException(e.getMessage(), e);
+ }
+ }
+
+ protected abstract void updateMeasurement(IMeasurementMNode node) throws MetadataException;
+}
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/ITreeNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/updater/Updater.java
similarity index 61%
copy from node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/ITreeNode.java
copy to server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/updater/Updater.java
index 900e943fbd..968c36bc18 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/schema/tree/ITreeNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mtree/traverser/updater/Updater.java
@@ -17,9 +17,14 @@
* under the License.
*/
-package org.apache.iotdb.commons.schema.tree;
+package org.apache.iotdb.db.metadata.mtree.traverser.updater;
-public interface ITreeNode {
+import org.apache.iotdb.commons.exception.MetadataException;
- String getName();
+// TODO: In schema file mode, since the updated node won't be cache evicted until it been flushed to
+// disk and currently the flush won't happen during traversing which takes the read lock, we need to
+// consider the concurrency of flush and traverse for better memory control in future work.
+public interface Updater {
+ // TODO: rename to traverse()
+ void update() throws MetadataException;
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionMemoryImpl.java b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionMemoryImpl.java
index f6524c900a..2531bf0678 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionMemoryImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionMemoryImpl.java
@@ -39,7 +39,6 @@ import org.apache.iotdb.db.metadata.logfile.FakeCRC32Deserializer;
import org.apache.iotdb.db.metadata.logfile.FakeCRC32Serializer;
import org.apache.iotdb.db.metadata.logfile.SchemaLogReader;
import org.apache.iotdb.db.metadata.logfile.SchemaLogWriter;
-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.mtree.MTreeBelowSGMemoryImpl;
@@ -85,7 +84,6 @@ import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -288,7 +286,7 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
long time = System.currentTimeMillis();
// init the metadata from the operation log
if (logFile.exists()) {
- int idx = 0;
+ int idx;
try (SchemaLogReader<ISchemaRegionPlan> mLogReader =
new SchemaLogReader<>(
schemaRegionDirPath,
@@ -408,7 +406,7 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
long startTime = System.currentTimeMillis();
long mtreeSnapshotStartTime = System.currentTimeMillis();
- isSuccess = isSuccess && mtree.createSnapshot(snapshotDir);
+ isSuccess = mtree.createSnapshot(snapshotDir);
logger.info(
"MTree snapshot creation of schemaRegion {} costs {}ms.",
schemaRegionId,
@@ -701,16 +699,14 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
public long constructSchemaBlackList(PathPatternTree patternTree) throws MetadataException {
long preDeletedNum = 0;
for (PartialPath pathPattern : patternTree.getAllPathPatterns()) {
- for (IMeasurementMNode measurementMNode : mtree.getMatchedMeasurementMNode(pathPattern)) {
- // Given pathPatterns may match one timeseries multi times, which may results in the
- // preDeletedNum larger than the actual num of timeseries. It doesn't matter since the main
- // purpose is to check whether there's timeseries to be deleted.
- preDeletedNum++;
- measurementMNode.setPreDeleted(true);
+ // Given pathPatterns may match one timeseries multi times, which may results in the
+ // preDeletedNum larger than the actual num of timeseries. It doesn't matter since the main
+ // purpose is to check whether there's timeseries to be deleted.
+ List<PartialPath> paths = mtree.constructSchemaBlackList(pathPattern);
+ preDeletedNum += paths.size();
+ for (PartialPath path : paths) {
try {
- writeToMLog(
- SchemaRegionWritePlanFactory.getPreDeleteTimeSeriesPlan(
- measurementMNode.getPartialPath()));
+ writeToMLog(SchemaRegionWritePlanFactory.getPreDeleteTimeSeriesPlan(path));
} catch (IOException e) {
throw new MetadataException(e);
}
@@ -727,12 +723,10 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
@Override
public void rollbackSchemaBlackList(PathPatternTree patternTree) throws MetadataException {
for (PartialPath pathPattern : patternTree.getAllPathPatterns()) {
- for (IMeasurementMNode measurementMNode : mtree.getMatchedMeasurementMNode(pathPattern)) {
- measurementMNode.setPreDeleted(false);
+ List<PartialPath> paths = mtree.rollbackSchemaBlackList(pathPattern);
+ for (PartialPath path : paths) {
try {
- writeToMLog(
- SchemaRegionWritePlanFactory.getRollbackPreDeleteTimeSeriesPlan(
- measurementMNode.getPartialPath()));
+ writeToMLog(SchemaRegionWritePlanFactory.getRollbackPreDeleteTimeSeriesPlan(path));
} catch (IOException e) {
throw new MetadataException(e);
}
@@ -1180,72 +1174,39 @@ public class SchemaRegionMemoryImpl implements ISchemaRegion {
@Override
public long constructSchemaBlackListWithTemplate(IPreDeactivateTemplatePlan plan)
throws MetadataException {
- long preDeactivateNum = 0;
- Map<PartialPath, List<Integer>> templateSetInfo = plan.getTemplateSetInfo();
- for (Map.Entry<PartialPath, List<Integer>> entry : templateSetInfo.entrySet()) {
- for (IEntityMNode entityMNode :
- mtree.getDeviceMNodeUsingTargetTemplate(entry.getKey(), entry.getValue())) {
- Map<PartialPath, List<Integer>> subTemplateSetInfo = new HashMap<>();
- subTemplateSetInfo.put(
- entityMNode.getPartialPath(),
- Collections.singletonList(entityMNode.getSchemaTemplateId()));
- entityMNode.preDeactivateTemplate();
- preDeactivateNum++;
- try {
- writeToMLog(
- SchemaRegionWritePlanFactory.getPreDeactivateTemplatePlan(subTemplateSetInfo));
- } catch (IOException e) {
- throw new MetadataException(e);
- }
- }
+ Map<PartialPath, List<Integer>> resultTemplateSetInfo =
+ mtree.constructSchemaBlackListWithTemplate(plan.getTemplateSetInfo());
+ try {
+ writeToMLog(SchemaRegionWritePlanFactory.getPreDeactivateTemplatePlan(resultTemplateSetInfo));
+ } catch (IOException e) {
+ throw new MetadataException(e);
}
- return preDeactivateNum;
+ return resultTemplateSetInfo.size();
}
@Override
public void rollbackSchemaBlackListWithTemplate(IRollbackPreDeactivateTemplatePlan plan)
throws MetadataException {
- Map<PartialPath, List<Integer>> templateSetInfo = plan.getTemplateSetInfo();
- for (Map.Entry<PartialPath, List<Integer>> entry : templateSetInfo.entrySet()) {
- for (IEntityMNode entityMNode :
- mtree.getPreDeactivatedDeviceMNode(entry.getKey(), entry.getValue())) {
- if (!entityMNode.isPreDeactivateTemplate()) {
- continue;
- }
- Map<PartialPath, List<Integer>> subTemplateSetInfo = new HashMap<>();
- subTemplateSetInfo.put(
- entityMNode.getPartialPath(),
- Collections.singletonList(entityMNode.getSchemaTemplateId()));
- entityMNode.rollbackPreDeactivateTemplate();
- try {
- writeToMLog(
- SchemaRegionWritePlanFactory.getRollbackPreDeactivateTemplatePlan(
- subTemplateSetInfo));
- } catch (IOException e) {
- throw new MetadataException(e);
- }
- }
+ Map<PartialPath, List<Integer>> resultTemplateSetInfo =
+ mtree.rollbackSchemaBlackListWithTemplate(plan.getTemplateSetInfo());
+ try {
+ writeToMLog(
+ SchemaRegionWritePlanFactory.getRollbackPreDeactivateTemplatePlan(resultTemplateSetInfo));
+ } catch (IOException e) {
+ throw new MetadataException(e);
}
}
@Override
public void deactivateTemplateInBlackList(IDeactivateTemplatePlan plan) throws MetadataException {
- Map<PartialPath, List<Integer>> templateSetInfo = plan.getTemplateSetInfo();
- for (Map.Entry<PartialPath, List<Integer>> entry : templateSetInfo.entrySet()) {
- for (IEntityMNode entityMNode :
- mtree.getPreDeactivatedDeviceMNode(entry.getKey(), entry.getValue())) {
- Map<PartialPath, List<Integer>> subTemplateSetInfo = new HashMap<>();
- subTemplateSetInfo.put(
- entityMNode.getPartialPath(),
- Collections.singletonList(entityMNode.getSchemaTemplateId()));
- entityMNode.deactivateTemplate();
- mtree.deleteEmptyInternalMNodeAndReturnEmptyStorageGroup(entityMNode);
- try {
- writeToMLog(SchemaRegionWritePlanFactory.getDeactivateTemplatePlan(subTemplateSetInfo));
- } catch (IOException e) {
- throw new MetadataException(e);
- }
- }
+ // TODO: We can consider implement this as a consumer passed to MTree which takes responsibility
+ // of operating tree structure and concurrency control in future work.
+ Map<PartialPath, List<Integer>> resultTemplateSetInfo =
+ mtree.deactivateTemplateInBlackList(plan.getTemplateSetInfo());
+ try {
+ writeToMLog(SchemaRegionWritePlanFactory.getDeactivateTemplatePlan(resultTemplateSetInfo));
+ } catch (IOException e) {
+ throw new MetadataException(e);
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionSchemaFileImpl.java b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionSchemaFileImpl.java
index 9f431395c8..11364d6e1b 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionSchemaFileImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaRegionSchemaFileImpl.java
@@ -757,27 +757,16 @@ public class SchemaRegionSchemaFileImpl implements ISchemaRegion {
public long constructSchemaBlackList(PathPatternTree patternTree) throws MetadataException {
long preDeletedNum = 0;
for (PartialPath pathPattern : patternTree.getAllPathPatterns()) {
- List<IMeasurementMNode> measurementMNodeList = mtree.getMatchedMeasurementMNode(pathPattern);
- try {
- for (IMeasurementMNode measurementMNode : measurementMNodeList) {
- // Given pathPatterns may match one timeseries multi times, which may results in the
- // preDeletedNum larger than the actual num of timeseries. It doesn't matter since the
- // main
- // purpose is to check whether there's timeseries to be deleted.
- try {
- preDeletedNum++;
- measurementMNode.setPreDeleted(true);
- mtree.updateMNode(measurementMNode);
- writeToMLog(
- SchemaRegionWritePlanFactory.getPreDeleteTimeSeriesPlan(
- measurementMNode.getPartialPath()));
- } catch (IOException e) {
- throw new MetadataException(e);
- }
- }
- } finally {
- for (IMeasurementMNode measurementMNode : measurementMNodeList) {
- mtree.unPinMNode(measurementMNode);
+ // Given pathPatterns may match one timeseries multi times, which may results in the
+ // preDeletedNum larger than the actual num of timeseries. It doesn't matter since the main
+ // purpose is to check whether there's timeseries to be deleted.
+ List<PartialPath> paths = mtree.constructSchemaBlackList(pathPattern);
+ preDeletedNum += paths.size();
+ for (PartialPath path : paths) {
+ try {
+ writeToMLog(SchemaRegionWritePlanFactory.getPreDeleteTimeSeriesPlan(path));
+ } catch (IOException e) {
+ throw new MetadataException(e);
}
}
}
@@ -787,17 +776,13 @@ public class SchemaRegionSchemaFileImpl implements ISchemaRegion {
@Override
public void rollbackSchemaBlackList(PathPatternTree patternTree) throws MetadataException {
for (PartialPath pathPattern : patternTree.getAllPathPatterns()) {
- for (IMeasurementMNode measurementMNode : mtree.getMatchedMeasurementMNode(pathPattern)) {
+ List<PartialPath> paths = mtree.rollbackSchemaBlackList(pathPattern);
+ ;
+ for (PartialPath path : paths) {
try {
- measurementMNode.setPreDeleted(false);
- mtree.updateMNode(measurementMNode);
- writeToMLog(
- SchemaRegionWritePlanFactory.getRollbackPreDeleteTimeSeriesPlan(
- measurementMNode.getPartialPath()));
+ writeToMLog(SchemaRegionWritePlanFactory.getRollbackPreDeleteTimeSeriesPlan(path));
} catch (IOException e) {
throw new MetadataException(e);
- } finally {
- mtree.unPinMNode(measurementMNode);
}
}
}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/visitor/SchemaTreeDeviceVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/visitor/SchemaTreeDeviceVisitor.java
index 59072f43c0..4e0ab4fb56 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/visitor/SchemaTreeDeviceVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/visitor/SchemaTreeDeviceVisitor.java
@@ -47,7 +47,7 @@ public class SchemaTreeDeviceVisitor extends SchemaTreeVisitor<DeviceSchemaInfo>
@Override
protected DeviceSchemaInfo generateResult(SchemaNode nextMatchedNode) {
- PartialPath path = new PartialPath(generateFullPathNodes());
+ PartialPath path = getPartialPathFromRootToNode(nextMatchedNode);
List<MeasurementSchemaInfo> measurementSchemaInfoList = new ArrayList<>();
Iterator<SchemaNode> iterator = getChildrenIterator(nextMatchedNode);
SchemaNode node;
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/visitor/SchemaTreeMeasurementVisitor.java b/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/visitor/SchemaTreeMeasurementVisitor.java
index 9dd71548b3..7221b1641c 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/visitor/SchemaTreeMeasurementVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/common/schematree/visitor/SchemaTreeMeasurementVisitor.java
@@ -111,7 +111,8 @@ public class SchemaTreeMeasurementVisitor extends SchemaTreeVisitor<MeasurementP
protected MeasurementPath generateResult(SchemaNode nextMatchedNode) {
MeasurementPath result =
new MeasurementPath(
- generateFullPathNodes(), nextMatchedNode.getAsMeasurementNode().getSchema());
+ getFullPathFromRootToNode(nextMatchedNode),
+ nextMatchedNode.getAsMeasurementNode().getSchema());
result.setTagMap(nextMatchedNode.getAsMeasurementNode().getTagMap());
result.setUnderAlignedEntity(getParentOfNextMatchedNode().getAsEntityNode().isAligned());
String alias = nextMatchedNode.getAsMeasurementNode().getAlias();
diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/mtree/ConfigMTreeTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/mtree/ConfigMTreeTest.java
index 12d74448b9..77fb3819b6 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/mtree/ConfigMTreeTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/mtree/ConfigMTreeTest.java
@@ -35,9 +35,6 @@ import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -97,28 +94,6 @@ public class ConfigMTreeTest {
assertTrue(root.isStorageGroupAlreadySet(new PartialPath("root.laptop.d1")));
}
- @Test
- public void testGetAllChildNodeNamesByPath() {
- try {
- root.setStorageGroup(new PartialPath("root.a.d0"));
- root.setStorageGroup(new PartialPath("root.a.d5"));
-
- // getChildNodeByPath
- Set<String> result1 = root.getChildNodeNameInNextLevel(new PartialPath("root.a.d0")).left;
- Set<String> result2 = root.getChildNodeNameInNextLevel(new PartialPath("root.a")).left;
- Set<String> result3 = root.getChildNodeNameInNextLevel(new PartialPath("root")).left;
- assertEquals(new HashSet<>(), result1);
- assertEquals(new HashSet<>(Arrays.asList("d0", "d5")), result2);
- assertEquals(new HashSet<>(Collections.singletonList("a")), result3);
-
- // if child node is nll will return null HashSet
- Set<String> result4 = root.getChildNodeNameInNextLevel(new PartialPath("root.a.d5")).left;
- assertEquals(result4, new HashSet<>(Collections.emptyList()));
- } catch (MetadataException e1) {
- e1.printStackTrace();
- }
- }
-
@Test
public void testSetStorageGroup() throws IllegalPathException {
try {
diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionBasicTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionBasicTest.java
index 191b3b8b5d..5a5aa000cc 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionBasicTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionBasicTest.java
@@ -514,13 +514,13 @@ public class SchemaRegionBasicTest extends AbstractSchemaRegionTest {
"root.laptop.d2.s2"));
Assert.assertEquals(
- new LinkedList<>(Arrays.asList(new PartialPath("root"))),
+ new LinkedList<>(Collections.singletonList(new PartialPath("root"))),
getNodesListInGivenLevel(schemaRegion, new PartialPath("root.**"), 0, false));
Assert.assertEquals(
- new LinkedList<>(Arrays.asList(new PartialPath("root.laptop"))),
+ new LinkedList<>(Collections.singletonList(new PartialPath("root.laptop"))),
getNodesListInGivenLevel(schemaRegion, new PartialPath("root.**"), 1, false));
Assert.assertEquals(
- new LinkedList<>(Arrays.asList(new PartialPath("root.laptop"))),
+ new LinkedList<>(Collections.singletonList(new PartialPath("root.laptop"))),
getNodesListInGivenLevel(schemaRegion, new PartialPath("root.laptop"), 1, false));
Assert.assertEquals(
new HashSet<>(
@@ -548,7 +548,7 @@ public class SchemaRegionBasicTest extends AbstractSchemaRegionTest {
getNodesListInGivenLevel(schemaRegion, new PartialPath("root.laptop.*.s1"), 3, false)));
// Empty return
Assert.assertEquals(
- new HashSet<>(Arrays.asList()),
+ new HashSet<>(Collections.emptyList()),
new HashSet<>(
getNodesListInGivenLevel(
schemaRegion, new PartialPath("root.laptop.notExists"), 1, false)));
@@ -569,7 +569,7 @@ public class SchemaRegionBasicTest extends AbstractSchemaRegionTest {
"root.laptop.d2.s2"));
Assert.assertEquals(
- new HashSet<>(Arrays.asList()),
+ new HashSet<>(Collections.emptyList()),
getChildNodePathInNextLevel(schemaRegion, new PartialPath("root.laptop.d0")));
Assert.assertEquals(
@@ -597,7 +597,8 @@ public class SchemaRegionBasicTest extends AbstractSchemaRegionTest {
Assert.assertEquals(
new HashSet<>(
- Arrays.asList(new ShowNodesResult("root.laptop.d1.s2.t1", MNodeType.MEASUREMENT))),
+ Collections.singletonList(
+ new ShowNodesResult("root.laptop.d1.s2.t1", MNodeType.MEASUREMENT))),
getChildNodePathInNextLevel(schemaRegion, new PartialPath("root.**.s2")));
}
diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionTemplateTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionTemplateTest.java
index ba88c50b05..f66c083b89 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionTemplateTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionTemplateTest.java
@@ -19,9 +19,12 @@
package org.apache.iotdb.db.metadata.schemaRegion;
+import org.apache.iotdb.commons.path.MeasurementPath;
import org.apache.iotdb.commons.path.PartialPath;
import org.apache.iotdb.commons.path.PathPatternTree;
+import org.apache.iotdb.db.metadata.plan.schemaregion.impl.read.SchemaRegionReadPlanFactory;
import org.apache.iotdb.db.metadata.plan.schemaregion.impl.write.SchemaRegionWritePlanFactory;
+import org.apache.iotdb.db.metadata.plan.schemaregion.result.ShowTimeSeriesResult;
import org.apache.iotdb.db.metadata.schemaregion.ISchemaRegion;
import org.apache.iotdb.db.metadata.template.Template;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
@@ -33,6 +36,7 @@ import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -179,4 +183,62 @@ public class SchemaRegionTemplateTest extends AbstractSchemaRegionTest {
allPatternTree.constructTree();
Assert.assertEquals(1, schemaRegion.countPathsUsingTemplate(templateId, allPatternTree));
}
+
+ @Test
+ public void testFetchSchemaWithTemplate() throws Exception {
+ ISchemaRegion schemaRegion = getSchemaRegion("root.sg", 0);
+ SchemaRegionTestUtil.createSimpleTimeseriesByList(
+ schemaRegion, Arrays.asList("root.sg.wf01.wt01.status", "root.sg.wf01.wt01.temperature"));
+ int templateId = 1;
+ Template template =
+ new Template(
+ "t1",
+ Arrays.asList(Collections.singletonList("s1"), Collections.singletonList("s2")),
+ Arrays.asList(
+ Collections.singletonList(TSDataType.DOUBLE),
+ Collections.singletonList(TSDataType.INT32)),
+ Arrays.asList(
+ Collections.singletonList(TSEncoding.RLE),
+ Collections.singletonList(TSEncoding.RLE)),
+ Arrays.asList(
+ Collections.singletonList(CompressionType.SNAPPY),
+ Collections.singletonList(CompressionType.SNAPPY)));
+ template.setId(templateId);
+ schemaRegion.activateSchemaTemplate(
+ SchemaRegionWritePlanFactory.getActivateTemplateInClusterPlan(
+ new PartialPath("root.sg.wf01.wt01"), 3, templateId),
+ template);
+ schemaRegion.activateSchemaTemplate(
+ SchemaRegionWritePlanFactory.getActivateTemplateInClusterPlan(
+ new PartialPath("root.sg.wf02"), 2, templateId),
+ template);
+ Map<Integer, Template> templateMap = Collections.singletonMap(templateId, template);
+ List<String> expectedTimeseries =
+ Arrays.asList(
+ "root.sg.wf01.wt01.s1",
+ "root.sg.wf01.wt01.s2",
+ "root.sg.wf01.wt01.status",
+ "root.sg.wf01.wt01.temperature",
+ "root.sg.wf02.s1",
+ "root.sg.wf02.s2");
+
+ // check fetch schema
+ List<MeasurementPath> schemas =
+ schemaRegion.fetchSchema(new PartialPath("root.**"), templateMap, true);
+ Assert.assertEquals(expectedTimeseries.size(), schemas.size());
+ schemas.sort(Comparator.comparing(PartialPath::getFullPath));
+ for (int i = 0; i < schemas.size(); i++) {
+ Assert.assertEquals(expectedTimeseries.get(i), schemas.get(i).getFullPath());
+ }
+
+ // check show timeseries
+ List<ShowTimeSeriesResult> result =
+ schemaRegion.showTimeseries(
+ SchemaRegionReadPlanFactory.getShowTimeSeriesPlan(
+ new PartialPath("root.**"), templateMap));
+ result.sort(ShowTimeSeriesResult::compareTo);
+ for (int i = 0; i < result.size(); i++) {
+ Assert.assertEquals(expectedTimeseries.get(i), result.get(i).getFullPath());
+ }
+ }
}