Skip to content

Commit c4c8bb7

Browse files
authored
Pipe: support pattern pruning and redundancy removal in TreePattern parsing (#16789)
* setup * reset * add UT * apply review * use trie for optimizePatterns * apply review * remove useless * improve pruneInclusionPatterns & pruneIrrelevantExclusions
1 parent 8a5e1e3 commit c4c8bb7

File tree

5 files changed

+571
-83
lines changed

5 files changed

+571
-83
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.iotdb.db.pipe.pattern;
21+
22+
import org.apache.iotdb.commons.pipe.config.constant.PipeSourceConstant;
23+
import org.apache.iotdb.commons.pipe.datastructure.pattern.IoTDBTreePattern;
24+
import org.apache.iotdb.commons.pipe.datastructure.pattern.PrefixTreePattern;
25+
import org.apache.iotdb.commons.pipe.datastructure.pattern.TreePattern;
26+
import org.apache.iotdb.commons.pipe.datastructure.pattern.UnionIoTDBTreePattern;
27+
import org.apache.iotdb.pipe.api.customizer.parameter.PipeParameters;
28+
import org.apache.iotdb.pipe.api.exception.PipeException;
29+
30+
import org.junit.Assert;
31+
import org.junit.Test;
32+
33+
import java.util.HashMap;
34+
35+
public class TreePatternPruningTest {
36+
37+
@Test
38+
public void testUnionInternalPruning_Cover() {
39+
final PipeParameters params =
40+
new PipeParameters(
41+
new HashMap<String, String>() {
42+
{
43+
put(PipeSourceConstant.SOURCE_PATH_KEY, "root.db.d1.*,root.db.d1.s1");
44+
}
45+
});
46+
47+
final TreePattern result = TreePattern.parsePipePatternFromSourceParameters(params);
48+
49+
Assert.assertTrue("Should be IoTDBTreePattern", result instanceof IoTDBTreePattern);
50+
Assert.assertEquals("root.db.d1.*", result.getPattern());
51+
}
52+
53+
@Test
54+
public void testUnionInternalPruning_Duplicates() {
55+
final PipeParameters params =
56+
new PipeParameters(
57+
new HashMap<String, String>() {
58+
{
59+
put(PipeSourceConstant.SOURCE_PATH_KEY, "root.db.d1,root.db.d1");
60+
}
61+
});
62+
63+
final TreePattern result = TreePattern.parsePipePatternFromSourceParameters(params);
64+
65+
Assert.assertTrue(result instanceof IoTDBTreePattern);
66+
Assert.assertEquals("root.db.d1", result.getPattern());
67+
}
68+
69+
@Test
70+
public void testInclusionPrunedByExclusion_Partial() {
71+
final PipeParameters params =
72+
new PipeParameters(
73+
new HashMap<String, String>() {
74+
{
75+
put(PipeSourceConstant.SOURCE_PATH_KEY, "root.sg.d1,root.sg.d2");
76+
put(PipeSourceConstant.SOURCE_PATH_EXCLUSION_KEY, "root.sg.d1");
77+
}
78+
});
79+
80+
final TreePattern result = TreePattern.parsePipePatternFromSourceParameters(params);
81+
82+
Assert.assertTrue(result instanceof IoTDBTreePattern);
83+
Assert.assertEquals("root.sg.d2", result.getPattern());
84+
}
85+
86+
@Test
87+
public void testInclusionPrunedByExclusion_FullCoverage_Exception() {
88+
final PipeParameters params =
89+
new PipeParameters(
90+
new HashMap<String, String>() {
91+
{
92+
put(PipeSourceConstant.SOURCE_PATH_KEY, "root.sg.d1");
93+
put(PipeSourceConstant.SOURCE_PATH_EXCLUSION_KEY, "root.sg.**");
94+
}
95+
});
96+
97+
try {
98+
TreePattern.parsePipePatternFromSourceParameters(params);
99+
Assert.fail("Should throw PipeException because Exclusion fully covers Inclusion");
100+
} catch (final PipeException ignored) {
101+
// Expected exception
102+
}
103+
}
104+
105+
@Test
106+
public void testComplexPruning() {
107+
final PipeParameters params =
108+
new PipeParameters(
109+
new HashMap<String, String>() {
110+
{
111+
put(PipeSourceConstant.SOURCE_PATH_KEY, "root.sg.A,root.sg.B,root.sg.A.sub");
112+
put(PipeSourceConstant.SOURCE_PATH_EXCLUSION_KEY, "root.sg.A,root.sg.A.**");
113+
}
114+
});
115+
116+
final TreePattern result = TreePattern.parsePipePatternFromSourceParameters(params);
117+
118+
Assert.assertTrue(result instanceof IoTDBTreePattern);
119+
Assert.assertEquals("root.sg.B", result.getPattern());
120+
}
121+
122+
@Test
123+
public void testComplexPruning_Prefix() {
124+
final PipeParameters params =
125+
new PipeParameters(
126+
new HashMap<String, String>() {
127+
{
128+
put(PipeSourceConstant.SOURCE_PATTERN_KEY, "root.sg.A,root.sg.B,root.sg.A.sub");
129+
put(PipeSourceConstant.SOURCE_PATTERN_EXCLUSION_KEY, "root.sg.A");
130+
put(PipeSourceConstant.SOURCE_PATTERN_FORMAT_KEY, "prefix");
131+
}
132+
});
133+
134+
final TreePattern result = TreePattern.parsePipePatternFromSourceParameters(params);
135+
136+
Assert.assertTrue(result instanceof PrefixTreePattern);
137+
Assert.assertEquals("root.sg.B", result.getPattern());
138+
}
139+
140+
@Test
141+
public void testUnionPreservedWhenNotCovered() {
142+
final PipeParameters params =
143+
new PipeParameters(
144+
new HashMap<String, String>() {
145+
{
146+
put(PipeSourceConstant.SOURCE_PATH_KEY, "root.sg.d1,root.sg.d2");
147+
put(PipeSourceConstant.SOURCE_PATH_EXCLUSION_KEY, "root.other");
148+
}
149+
});
150+
151+
final TreePattern result = TreePattern.parsePipePatternFromSourceParameters(params);
152+
153+
Assert.assertTrue(result instanceof UnionIoTDBTreePattern);
154+
Assert.assertEquals("root.sg.d1,root.sg.d2", result.getPattern());
155+
}
156+
}

0 commit comments

Comments
 (0)