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 3ecc1d27b8 [IOTDB-4352] PatialPath#overlapWith supports 
MULTI_LEVEL_PATH_WILDCARD (#7259)
3ecc1d27b8 is described below

commit 3ecc1d27b8e9310ba487cfcb2e4eedf4b42d3cd4
Author: Chen YZ <[email protected]>
AuthorDate: Wed Sep 7 14:38:25 2022 +0800

    [IOTDB-4352] PatialPath#overlapWith supports MULTI_LEVEL_PATH_WILDCARD 
(#7259)
    
    [IOTDB-4352] PatialPath#overlapWith supports MULTI_LEVEL_PATH_WILDCARD 
(#7259)
---
 .../org/apache/iotdb/commons/path/PartialPath.java | 64 ++++++++++++++++++++--
 .../apache/iotdb/commons/path/PartialPathTest.java | 23 +++++++-
 2 files changed, 81 insertions(+), 6 deletions(-)

diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java 
b/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java
index abb58beb1f..a79a8a14bf 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/path/PartialPath.java
@@ -361,16 +361,28 @@ public class PartialPath extends Path implements 
Comparable<Path>, Cloneable {
    * "root.**", "root.*.d.s" overlaps with "root.sg.d.s", "root.sg.**" 
overlaps with "root.**.s",
    * "root.*.d.s" doesn't overlap with "root.sg.d1.*"
    *
-   * @param rPath a plain full path of a timeseries
-   * @return true if a successful match, otherwise return false
+   * @param rPath a pattern path of a timeseries
+   * @return true if overlapping otherwise return false
    */
   public boolean overlapWith(PartialPath rPath) {
     String[] rNodes = rPath.getNodes();
     for (int i = 0; i < this.nodes.length && i < rNodes.length; i++) {
+      // if encounter MULTI_LEVEL_PATH_WILDCARD, check recursively
+      if (nodes[i].equals(MULTI_LEVEL_PATH_WILDCARD)) {
+        if (checkOverlapWithMultiLevelWildcard(nodes, rNodes, i + 1, i + 1)) {
+          return true;
+        }
+      }
+      if (rNodes[i].equals(MULTI_LEVEL_PATH_WILDCARD)) {
+        if (checkOverlapWithMultiLevelWildcard(rNodes, nodes, i + 1, i + 1)) {
+          return true;
+        }
+      }
       if (nodes[i].equals(MULTI_LEVEL_PATH_WILDCARD)
-          || rNodes[i].equals(MULTI_LEVEL_PATH_WILDCARD)) {
-        return true;
+          && rNodes[i].equals(MULTI_LEVEL_PATH_WILDCARD)) {
+        return false;
       }
+      // if without MULTI_LEVEL_PATH_WILDCARD, scan and check
       if (nodes[i].equals(ONE_LEVEL_PATH_WILDCARD) || 
rNodes[i].equals(ONE_LEVEL_PATH_WILDCARD)) {
         continue;
       }
@@ -381,6 +393,50 @@ public class PartialPath extends Path implements 
Comparable<Path>, Cloneable {
     return this.nodes.length == rNodes.length;
   }
 
+  /**
+   * Try to check overlap between nodes1[pos1:] and nodes2[pos2:] recursively.
+   *
+   * @param nodes1 nodes1[pos1-1] is MULTI_LEVEL_PATH_WILDCARD.
+   * @param nodes2 nodes2 is another pattern path to check overlapping
+   * @param pos1 start index of nodes1
+   * @param pos2 start index of nodes2
+   * @return true if overlapping, otherwise return false
+   */
+  private boolean checkOverlapWithMultiLevelWildcard(
+      String[] nodes1, String[] nodes2, int pos1, int pos2) {
+    // make sure pos1<nodes1.length and pos2<node2.length
+    if (pos1 > nodes1.length || pos2 > nodes2.length) {
+      return false;
+    } else if (pos1 == nodes1.length && pos2 == nodes2.length) {
+      return true;
+    }
+    int i, j;
+    for (i = pos1, j = pos2; i < nodes1.length && j < nodes2.length; i++, j++) 
{
+      if (nodes1[i].equals(MULTI_LEVEL_PATH_WILDCARD)) {
+        if (checkOverlapWithMultiLevelWildcard(nodes1, nodes2, pos1 + 1, pos2 
+ 1)) {
+          return true;
+        }
+      }
+      if (nodes2[j].equals(MULTI_LEVEL_PATH_WILDCARD)) {
+        if (checkOverlapWithMultiLevelWildcard(nodes2, nodes1, pos2 + 1, pos1 
+ 1)) {
+          return true;
+        }
+      }
+      if (nodes1[i].equals(ONE_LEVEL_PATH_WILDCARD) || 
nodes2[j].equals(ONE_LEVEL_PATH_WILDCARD)) {
+        continue;
+      } else if (!nodes1[i].equals(nodes2[j])) {
+        // failed to match, MULTI_LEVEL_PATH_WILDCARD should match more path 
in nodes2.
+        return checkOverlapWithMultiLevelWildcard(nodes1, nodes2, pos1, pos2 + 
1);
+      }
+    }
+    if (i != nodes1.length || j != nodes2.length) {
+      // MULTI_LEVEL_PATH_WILDCARD should match more path in nodes2.
+      return checkOverlapWithMultiLevelWildcard(nodes1, nodes2, pos1, pos2 + 
1);
+    } else {
+      return true;
+    }
+  }
+
   @Override
   public String getFullPath() {
     if (fullPath == null) {
diff --git 
a/node-commons/src/test/java/org/apache/iotdb/commons/path/PartialPathTest.java 
b/node-commons/src/test/java/org/apache/iotdb/commons/path/PartialPathTest.java
index 55c1a6491f..273e7e12c2 100644
--- 
a/node-commons/src/test/java/org/apache/iotdb/commons/path/PartialPathTest.java
+++ 
b/node-commons/src/test/java/org/apache/iotdb/commons/path/PartialPathTest.java
@@ -672,9 +672,28 @@ public class PartialPathTest {
           new PartialPath[] {new PartialPath("root.*.d.s"), new 
PartialPath("root.**.s")},
           new PartialPath[] {new PartialPath("root.*.d.s"), new 
PartialPath("root.sg.*.s")},
           new PartialPath[] {new PartialPath("root.*.d.s"), new 
PartialPath("root.sg.d2.s")},
-          new PartialPath[] {new PartialPath("root.*.d.s.*"), new 
PartialPath("root.sg.d.s")}
+          new PartialPath[] {new PartialPath("root.*.d.s.*"), new 
PartialPath("root.sg.d.s")},
+          new PartialPath[] {new PartialPath("root.**.d.s"), new 
PartialPath("root.**.d2.s")},
+          new PartialPath[] {new PartialPath("root.**.*.s"), new 
PartialPath("root.**.d2.s")},
+          new PartialPath[] {new PartialPath("root.**.d1.*"), new 
PartialPath("root.*")},
+          new PartialPath[] {new PartialPath("root.**.d1.*"), new 
PartialPath("root.d2.*.s")},
+          new PartialPath[] {new PartialPath("root.**.d1.**"), new 
PartialPath("root.d2.**")},
+          new PartialPath[] {
+            new PartialPath("root.**.*.**.**"), new 
PartialPath("root.d2.*.s1.**")
+          },
+          new PartialPath[] {new PartialPath("root.**.s1.d1"), new 
PartialPath("root.s1.d1.**")},
+          new PartialPath[] {new PartialPath("root.**.s1"), new 
PartialPath("root.**.s2.s1")},
+          new PartialPath[] {
+            new PartialPath("root.**.s1.s2.**"), new 
PartialPath("root.d1.s1.s2.*")
+          },
+          new PartialPath[] {new PartialPath("root.**.s1"), new 
PartialPath("root.**.s2")},
         };
-    boolean[] results = new boolean[] {true, true, true, true, true, true, 
false, false};
+    boolean[] results =
+        new boolean[] {
+          true, true, true, true, true, true, false, false, false, true, 
false, true, true, true,
+          true, true, true, false
+        };
+    Assert.assertEquals(pathPairs.length, results.length);
     for (int i = 0; i < pathPairs.length; i++) {
       Assert.assertEquals(results[i], 
pathPairs[i][0].overlapWith(pathPairs[i][1]));
     }

Reply via email to