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()) {

Reply via email to