This is an automated email from the ASF dual-hosted git repository.
jackietien 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 67d70cea85f [IOTDB-5887] Optimize the construction performance of
PathPatternTree without wildcards
67d70cea85f is described below
commit 67d70cea85f2e9e6339ae001ac3246bf4f9eac4e
Author: liuminghui233 <[email protected]>
AuthorDate: Sun May 21 19:43:43 2023 +0800
[IOTDB-5887] Optimize the construction performance of PathPatternTree
without wildcards
---
.../apache/iotdb/commons/path/PathPatternTree.java | 34 ++++++++----
.../iotdb/commons/path/PathPatternTreeTest.java | 61 ++++++++++++++++++----
.../iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java | 2 +-
.../iotdb/db/mpp/plan/parser/ASTVisitor.java | 6 +++
.../db/mpp/plan/statement/crud/QueryStatement.java | 10 ++++
5 files changed, 90 insertions(+), 23 deletions(-)
diff --git
a/node-commons/src/main/java/org/apache/iotdb/commons/path/PathPatternTree.java
b/node-commons/src/main/java/org/apache/iotdb/commons/path/PathPatternTree.java
index 4c9179cce93..629195d4a63 100644
---
a/node-commons/src/main/java/org/apache/iotdb/commons/path/PathPatternTree.java
+++
b/node-commons/src/main/java/org/apache/iotdb/commons/path/PathPatternTree.java
@@ -43,6 +43,14 @@ public class PathPatternTree {
private List<PartialPath> pathPatternList;
+ // set the default value to TRUE to ensure correctness
+ private boolean useWildcard = true;
+
+ public PathPatternTree(boolean useWildcard) {
+ this();
+ this.useWildcard = useWildcard;
+ }
+
public PathPatternTree() {
this.root = new PathPatternNode<>(IoTDBConstant.PATH_ROOT,
VoidSerializer.getInstance());
this.pathPatternList = new LinkedList<>();
@@ -77,18 +85,22 @@ public class PathPatternTree {
/** Add a pathPattern (may contain wildcards) to pathPatternList. */
public void appendPathPattern(PartialPath pathPattern) {
- boolean isExist = false;
- for (PartialPath path : pathPatternList) {
- if (path.include(pathPattern)) {
- // path already exists in pathPatternList
- isExist = true;
- break;
+ if (useWildcard) {
+ boolean isExist = false;
+ for (PartialPath path : pathPatternList) {
+ if (path.include(pathPattern)) {
+ // path already exists in pathPatternList
+ isExist = true;
+ break;
+ }
}
- }
- if (!isExist) {
- // remove duplicate path in pathPatternList
- pathPatternList.removeIf(pathPattern::include);
- pathPatternList.add(pathPattern);
+ if (!isExist) {
+ // remove duplicate path in pathPatternList
+ pathPatternList.removeIf(pathPattern::include);
+ pathPatternList.add(pathPattern);
+ }
+ } else {
+ appendBranchWithoutPrune(root, pathPattern.getNodes(), 0);
}
}
diff --git
a/node-commons/src/test/java/org/apache/iotdb/commons/path/PathPatternTreeTest.java
b/node-commons/src/test/java/org/apache/iotdb/commons/path/PathPatternTreeTest.java
index 08dcbbe6d8e..ed30c293b38 100644
---
a/node-commons/src/test/java/org/apache/iotdb/commons/path/PathPatternTreeTest.java
+++
b/node-commons/src/test/java/org/apache/iotdb/commons/path/PathPatternTreeTest.java
@@ -43,7 +43,8 @@ public class PathPatternTreeTest {
new PartialPath("root.sg1.d1.*"),
new PartialPath("root.sg1.d1.s3")),
Collections.singletonList(new PartialPath("root.sg1.d1.*")),
- Collections.singletonList(new PartialPath("root.sg1.d1")));
+ Collections.singletonList(new PartialPath("root.sg1.d1")),
+ true);
}
@Test
@@ -55,7 +56,8 @@ public class PathPatternTreeTest {
new PartialPath("root.sg1.*.t1.s1"),
new PartialPath("root.sg1.d2.t1.s1")),
Arrays.asList(new PartialPath("root.sg1.d1.t2.s2"), new
PartialPath("root.sg1.*.t1.s1")),
- Arrays.asList(new PartialPath("root.sg1.d1.t2"), new
PartialPath("root.sg1.*")));
+ Arrays.asList(new PartialPath("root.sg1.d1.t2"), new
PartialPath("root.sg1.*")),
+ true);
}
@Test
@@ -74,7 +76,8 @@ public class PathPatternTreeTest {
Arrays.asList(
new PartialPath("root.sg1.d1"),
new PartialPath("root.sg1.d1.t1"),
- new PartialPath("root.sg1.*")));
+ new PartialPath("root.sg1.*")),
+ true);
}
@Test
@@ -91,7 +94,8 @@ public class PathPatternTreeTest {
new PartialPath("root.sg1.d1.t1.s1"),
new PartialPath("root.sg1.d2.s3")),
Collections.singletonList(new PartialPath("root.**")),
- Collections.singletonList(new PartialPath("root.**")));
+ Collections.singletonList(new PartialPath("root.**")),
+ true);
}
@Test
@@ -104,7 +108,8 @@ public class PathPatternTreeTest {
new PartialPath("root.sg1.d2.s1"),
new PartialPath("root.sg1.**.s1")),
Arrays.asList(new PartialPath("root.sg1.d1.s2"), new
PartialPath("root.sg1.**.s1")),
- Arrays.asList(new PartialPath("root.sg1.d1"), new
PartialPath("root.sg1.**")));
+ Arrays.asList(new PartialPath("root.sg1.d1"), new
PartialPath("root.sg1.**")),
+ true);
}
@Test
@@ -132,7 +137,8 @@ public class PathPatternTreeTest {
new PartialPath("root.sg1.d2"),
new PartialPath("root.sg1.**"),
new PartialPath("root.sg1.*"),
- new PartialPath("root.sg1.d3.t1")));
+ new PartialPath("root.sg1.d3.t1")),
+ true);
}
/** This use case is used to test the de-duplication of getAllPathPatterns
results */
@@ -146,7 +152,8 @@ public class PathPatternTreeTest {
new PartialPath("root.sg1.*.s1"),
new PartialPath("root.sg1.**.s1")),
Arrays.asList(new PartialPath("root.sg1.*.s2"), new
PartialPath("root.sg1.**.s1")),
- Arrays.asList(new PartialPath("root.sg1.*"), new
PartialPath("root.sg1.**")));
+ Arrays.asList(new PartialPath("root.sg1.*"), new
PartialPath("root.sg1.**")),
+ true);
}
/** This use case is used to test the de-duplication of getAllDevicePatterns
results */
@@ -155,7 +162,8 @@ public class PathPatternTreeTest {
checkPathPatternTree(
Arrays.asList(new PartialPath("root.sg1.d1.s1"), new
PartialPath("root.sg1.d1.s2")),
Arrays.asList(new PartialPath("root.sg1.d1.s1"), new
PartialPath("root.sg1.d1.s2")),
- Collections.singletonList(new PartialPath("root.sg1.d1")));
+ Collections.singletonList(new PartialPath("root.sg1.d1")),
+ true);
}
/**
@@ -177,7 +185,37 @@ public class PathPatternTreeTest {
Arrays.asList(
new PartialPath("root.sg1"),
new PartialPath("root.sg1.d1"),
- new PartialPath("root.sg1.d1.**")));
+ new PartialPath("root.sg1.d1.**")),
+ true);
+ }
+
+ @Test
+ public void pathPatternTreeWithoutWildcardTest() throws
IllegalPathException, IOException {
+ checkPathPatternTree(
+ Arrays.asList(
+ new PartialPath("root.sg1.d1.s1"),
+ new PartialPath("root.sg1.d2.s1"),
+ new PartialPath("root.sg1.d1.s2"),
+ new PartialPath("root.sg1.d1.t1.s1"),
+ new PartialPath("root.sg1.d1.t2.s2"),
+ new PartialPath("root.sg1.d2.s1"),
+ new PartialPath("root.sg1.d2.s2"),
+ new PartialPath("root.sg1.d1.t1.s1"),
+ new PartialPath("root.sg1.d1.t2.s2"),
+ new PartialPath("root.sg1.d1.s1")),
+ Arrays.asList(
+ new PartialPath("root.sg1.d1.s1"),
+ new PartialPath("root.sg1.d1.s2"),
+ new PartialPath("root.sg1.d2.s1"),
+ new PartialPath("root.sg1.d2.s2"),
+ new PartialPath("root.sg1.d1.t1.s1"),
+ new PartialPath("root.sg1.d1.t2.s2")),
+ Arrays.asList(
+ new PartialPath("root.sg1.d1"),
+ new PartialPath("root.sg1.d2"),
+ new PartialPath("root.sg1.d1.t1"),
+ new PartialPath("root.sg1.d1.t2")),
+ false);
}
/**
@@ -189,9 +227,10 @@ public class PathPatternTreeTest {
private void checkPathPatternTree(
List<PartialPath> paths,
List<PartialPath> compressedPaths,
- List<PartialPath> compressedDevicePaths)
+ List<PartialPath> compressedDevicePaths,
+ boolean useWildcard)
throws IOException {
- PathPatternTree patternTree = new PathPatternTree();
+ PathPatternTree patternTree = new PathPatternTree(useWildcard);
for (PartialPath path : paths) {
patternTree.appendPathPattern(path);
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
index 7313a600df5..c49f2e17680 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
@@ -240,7 +240,7 @@ public class AnalyzeVisitor extends
StatementVisitor<Analysis, MPPQueryContext>
queryStatement.semanticCheck();
// concat path and construct path pattern tree
- PathPatternTree patternTree = new PathPatternTree();
+ PathPatternTree patternTree = new
PathPatternTree(queryStatement.useWildcard());
queryStatement =
(QueryStatement) new ConcatPathRewriter().rewrite(queryStatement,
patternTree);
analysis.setStatement(queryStatement);
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
index 869add24d41..956b3158447 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/parser/ASTVisitor.java
@@ -258,6 +258,8 @@ public class ASTVisitor extends
IoTDBSqlParserBaseVisitor<Statement> {
private static final String IGNORENULL = "IgnoreNull";
private ZoneId zoneId;
+ private boolean useWildcard = false;
+
public void setZoneId(ZoneId zoneId) {
this.zoneId = zoneId;
}
@@ -1248,6 +1250,7 @@ public class ASTVisitor extends
IoTDBSqlParserBaseVisitor<Statement> {
queryStatement.setResultSetFormat(parseAlignBy(ctx.alignByClause()));
}
+ queryStatement.setUseWildcard(useWildcard);
return queryStatement;
}
@@ -1823,6 +1826,9 @@ public class ASTVisitor extends
IoTDBSqlParserBaseVisitor<Statement> {
}
private String parseNodeName(IoTDBSqlParser.NodeNameContext ctx) {
+ if (!useWildcard && !ctx.wildcard().isEmpty()) {
+ useWildcard = true;
+ }
return parseNodeString(ctx.getText());
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/crud/QueryStatement.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/crud/QueryStatement.java
index 984db33270f..2dd2a129f8b 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/crud/QueryStatement.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/statement/crud/QueryStatement.java
@@ -113,6 +113,8 @@ public class QueryStatement extends Statement {
private boolean isOutputEndTime = false;
+ private boolean useWildcard = true;
+
public QueryStatement() {
this.statementType = StatementType.QUERY;
}
@@ -467,6 +469,14 @@ public class QueryStatement extends Statement {
return rowOffset > 0;
}
+ public void setUseWildcard(boolean useWildcard) {
+ this.useWildcard = useWildcard;
+ }
+
+ public boolean useWildcard() {
+ return useWildcard;
+ }
+
public void semanticCheck() {
if (isAggregationQuery()) {
if (disableAlign()) {