Added: hadoop/pig/trunk/test/org/apache/pig/test/TestExperimentalOperatorPlan.java URL: http://svn.apache.org/viewvc/hadoop/pig/trunk/test/org/apache/pig/test/TestExperimentalOperatorPlan.java?rev=898497&view=auto ============================================================================== --- hadoop/pig/trunk/test/org/apache/pig/test/TestExperimentalOperatorPlan.java (added) +++ hadoop/pig/trunk/test/org/apache/pig/test/TestExperimentalOperatorPlan.java Tue Jan 12 20:32:29 2010 @@ -0,0 +1,646 @@ +/* + * 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.pig.test; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +import org.apache.pig.experimental.plan.BaseOperatorPlan; +import org.apache.pig.experimental.plan.DependencyOrderWalker; +import org.apache.pig.experimental.plan.DepthFirstWalker; +import org.apache.pig.experimental.plan.Operator; +import org.apache.pig.experimental.plan.OperatorPlan; +import org.apache.pig.experimental.plan.PlanEdge; +import org.apache.pig.experimental.plan.PlanVisitor; +import org.apache.pig.experimental.plan.PlanWalker; +import org.apache.pig.experimental.plan.ReverseDependencyOrderWalker; +import org.apache.pig.impl.util.Pair; +import org.junit.Test; + +import junit.framework.TestCase; + +public class TestExperimentalOperatorPlan extends TestCase { + + private static class SillyPlan extends BaseOperatorPlan { + + SillyPlan() { + super(); + } + + } + + private static class SillyOperator extends Operator { + private String name; + + SillyOperator(String n, SillyPlan p) { + super(n, p); + name = n; + } + + public boolean equals(SillyOperator other) { + return other.name == name; + } + + @Override + public void accept(PlanVisitor v) { + if (v instanceof SillyVisitor) { + ((SillyVisitor)v).visitSillyOperator(this); + } + } + } + + private static class SillyVisitor extends PlanVisitor { + + StringBuffer buf; + + protected SillyVisitor(OperatorPlan plan, PlanWalker walker) { + super(plan, walker); + buf = new StringBuffer(); + } + + public void visitSillyOperator(SillyOperator so) { + buf.append(so.getName()); + } + + public String getVisitPattern() { + return buf.toString(); + } + + } + + // Tests for PlanEdge + + @Test + public void testPlanEdgeInsert() { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + PlanEdge edges = new PlanEdge(); + + // Test initial entry + edges.put(fred, joe, 0); + Collection<Operator> c = edges.get(fred); + assertEquals(1, c.size()); + Operator[] a = new Operator[1]; + Operator[] b = c.toArray(a); + assertEquals(joe, b[0]); + + // Test entry with no position + SillyOperator bob = new SillyOperator("bob", plan); + edges.put(fred, bob); + c = edges.get(fred); + assertEquals(2, c.size()); + a = new Operator[2]; + b = c.toArray(a); + assertEquals(joe, b[0]); + assertEquals(bob, b[1]); + + // Test entry with position + SillyOperator jill = new SillyOperator("jill", plan); + edges.put(fred, jill, 1); + c = edges.get(fred); + assertEquals(3, c.size()); + a = new Operator[3]; + b = c.toArray(a); + assertEquals(joe, b[0]); + assertEquals(jill, b[1]); + assertEquals(bob, b[2]); + } + + // Test that entry with invalid position cannot be made. + @Test + public void testPlanEdgeInsertFirstIndexBad() { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + PlanEdge edges = new PlanEdge(); + boolean caught = false; + try { + edges.put(fred, joe, 1); + } catch (IndexOutOfBoundsException e) { + caught = true; + } + assertTrue(caught); + + caught = false; + edges.put(fred, joe); + SillyOperator bob = new SillyOperator("bob", plan); + try { + edges.put(fred, bob, 2); + } catch (IndexOutOfBoundsException e) { + caught = true; + } + assertTrue(caught); + } + + // Test OperatorPlan + @Test + public void testOperatorPlan() throws IOException { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + SillyOperator bob = new SillyOperator("bob", plan); + SillyOperator jim = new SillyOperator("jim", plan); + SillyOperator sam = new SillyOperator("sam", plan); + + // Test that roots and leaves are empty when there are no operators in + // plan. + List<Operator> list = plan.getRoots(); + assertEquals(0, list.size()); + list = plan.getLeaves(); + assertEquals(0, list.size()); + + plan.add(fred); + plan.add(joe); + plan.add(bob); + plan.add(jim); + plan.add(sam); + + // Test that when not connected all nodes are roots and leaves. + list = plan.getRoots(); + assertEquals(5, list.size()); + list = plan.getLeaves(); + assertEquals(5, list.size()); + + // Connect them up + plan.connect(fred, bob); + plan.connect(joe, bob); + plan.connect(bob, jim); + plan.connect(bob, sam); + + // Check that the roots and leaves came out right + list = plan.getRoots(); + assertEquals(2, list.size()); + for (Operator op : list) { + assertTrue(fred.equals(op) || joe.equals(op)); + } + list = plan.getLeaves(); + assertEquals(2, list.size()); + for (Operator op : list) { + assertTrue(jim.equals(op) || sam.equals(op)); + } + + // Check each of their successors and predecessors + list = plan.getSuccessors(fred); + assertEquals(1, list.size()); + assertEquals(bob, list.get(0)); + + list = plan.getSuccessors(joe); + assertEquals(1, list.size()); + assertEquals(bob, list.get(0)); + + list = plan.getPredecessors(jim); + assertEquals(1, list.size()); + assertEquals(bob, list.get(0)); + + list = plan.getPredecessors(sam); + assertEquals(1, list.size()); + assertEquals(bob, list.get(0)); + + list = plan.getPredecessors(bob); + assertEquals(2, list.size()); + assertEquals(fred, list.get(0)); + assertEquals(joe, list.get(1)); + + list = plan.getSuccessors(bob); + assertEquals(2, list.size()); + assertEquals(jim, list.get(0)); + assertEquals(sam, list.get(1)); + + // Now try swapping two, and check that all comes out as planned + Pair<Integer, Integer> p1 = plan.disconnect(bob, jim); + Pair<Integer, Integer> p2 = plan.disconnect(fred, bob); + + plan.connect(bob, p1.first, fred, p1.second); + plan.connect(jim, p2.first, bob, p2.second); + + // Check that the roots and leaves came out right + list = plan.getRoots(); + assertEquals(2, list.size()); + for (Operator op : list) { + assertTrue(jim.equals(op) || joe.equals(op)); + } + list = plan.getLeaves(); + assertEquals(2, list.size()); + for (Operator op : list) { + assertTrue(fred.equals(op) || sam.equals(op)); + } + + // Check each of their successors and predecessors + list = plan.getSuccessors(jim); + assertEquals(1, list.size()); + assertEquals(bob, list.get(0)); + + list = plan.getSuccessors(joe); + assertEquals(1, list.size()); + assertEquals(bob, list.get(0)); + + list = plan.getPredecessors(fred); + assertEquals(1, list.size()); + assertEquals(bob, list.get(0)); + + list = plan.getPredecessors(sam); + assertEquals(1, list.size()); + assertEquals(bob, list.get(0)); + + list = plan.getPredecessors(bob); + assertEquals(2, list.size()); + assertEquals(jim, list.get(0)); + assertEquals(joe, list.get(1)); + + list = plan.getSuccessors(bob); + assertEquals(2, list.size()); + assertEquals(fred, list.get(0)); + assertEquals(sam, list.get(1)); + + } + + @Test + public void testDisconnectAndRemove() throws IOException { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + SillyOperator bob = new SillyOperator("bob", plan); + + plan.add(fred); + plan.add(joe); + plan.add(bob); + + plan.connect(fred, joe); + + plan.remove(bob); + plan.disconnect(fred, joe); + + List<Operator> list = plan.getRoots(); + assertEquals(2, list.size()); + list = plan.getLeaves(); + assertEquals(2, list.size()); + + plan.remove(fred); + plan.remove(joe); + + assertEquals(0, plan.size()); + + list = plan.getRoots(); + assertEquals(0, list.size()); + list = plan.getLeaves(); + assertEquals(0, list.size()); + } + + // Test bad remove + @Test + public void testRemoveNegative() { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + + plan.add(fred); + plan.add(joe); + + plan.connect(fred, joe); + + boolean caught = false; + try { + plan.remove(fred); + } catch (IOException e) { + caught = true; + } + assertTrue(caught); + + caught = false; + try { + plan.remove(joe); + } catch (IOException e) { + caught = true; + } + assertTrue(caught); + + } + + @Test + public void testDisconnectNegative() { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + + plan.add(fred); + plan.add(joe); + + boolean caught = false; + try { + plan.disconnect(fred, joe); + } catch (IOException e) { + caught = true; + } + assertTrue(caught); + + } + + // Tests for DependencyOrderWalker + + @Test + public void testDependencyOrderWalkerLinear() throws IOException { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + SillyOperator bob = new SillyOperator("bob", plan); + + plan.add(fred); + plan.add(joe); + plan.add(bob); + + plan.connect(fred, joe); + plan.connect(joe, bob); + + SillyVisitor v = + new SillyVisitor(plan, new DependencyOrderWalker(plan)); + + v.visit(); + + String s = v.getVisitPattern(); + + assertEquals("fredjoebob", s); + } + + @Test + public void testDependencyOrderWalkerTree() throws IOException { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + SillyOperator bob = new SillyOperator("bob", plan); + SillyOperator jill = new SillyOperator("jill", plan); + SillyOperator jane = new SillyOperator("jane", plan); + + plan.add(fred); + plan.add(joe); + plan.add(bob); + plan.add(jill); + plan.add(jane); + + plan.connect(fred, bob); + plan.connect(joe, bob); + plan.connect(bob, jill); + plan.connect(jane, jill); + + SillyVisitor v = + new SillyVisitor(plan, new DependencyOrderWalker(plan)); + + v.visit(); + + String s = v.getVisitPattern(); + + if (!s.equals("fredjoebobjanejill") && + !s.equals("joefredbobjanejill") && + !s.equals("janefredjoebobjill") && + !s.equals("janejoefredbobjill")) { + System.out.println("Invalid order " + s); + fail(); + } + } + + @Test + public void testDependencyOrderWalkerGraph() throws IOException { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + SillyOperator bob = new SillyOperator("bob", plan); + SillyOperator jill = new SillyOperator("jill", plan); + SillyOperator jane = new SillyOperator("jane", plan); + + plan.add(fred); + plan.add(joe); + plan.add(bob); + plan.add(jill); + plan.add(jane); + + plan.connect(fred, bob); + plan.connect(joe, bob); + plan.connect(bob, jill); + plan.connect(bob, jane); + + SillyVisitor v = + new SillyVisitor(plan, new DependencyOrderWalker(plan)); + + v.visit(); + + String s = v.getVisitPattern(); + + if (!s.equals("fredjoebobjanejill") && + !s.equals("joefredbobjanejill") && + !s.equals("fredjoebobjilljane") && + !s.equals("joefredbobjilljane")) { + System.out.println("Invalid order " + s); + fail(); + } + } + + // Tests for DepthFirstWalker + + @Test + public void testDepthFirstWalkerLinear() throws IOException { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + SillyOperator bob = new SillyOperator("bob", plan); + + plan.add(fred); + plan.add(joe); + plan.add(bob); + + plan.connect(fred, joe); + plan.connect(joe, bob); + + SillyVisitor v = + new SillyVisitor(plan, new DepthFirstWalker(plan)); + + v.visit(); + + String s = v.getVisitPattern(); + + assertEquals("fredjoebob", s); + } + + @Test + public void testDepthFirstWalkerTree() throws IOException { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + SillyOperator bob = new SillyOperator("bob", plan); + SillyOperator jill = new SillyOperator("jill", plan); + SillyOperator jane = new SillyOperator("jane", plan); + + plan.add(fred); + plan.add(joe); + plan.add(bob); + plan.add(jill); + plan.add(jane); + + plan.connect(fred, bob); + plan.connect(fred, joe); + plan.connect(joe, jill); + plan.connect(joe, jane); + + SillyVisitor v = + new SillyVisitor(plan, new DepthFirstWalker(plan)); + + v.visit(); + + String s = v.getVisitPattern(); + + assertEquals("fredbobjoejilljane", s); + } + + @Test + public void testDepthFirstWalkerGraph() throws IOException { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + SillyOperator bob = new SillyOperator("bob", plan); + SillyOperator jill = new SillyOperator("jill", plan); + SillyOperator jane = new SillyOperator("jane", plan); + + plan.add(fred); + plan.add(joe); + plan.add(bob); + plan.add(jill); + plan.add(jane); + + plan.connect(fred, bob); + plan.connect(joe, bob); + plan.connect(bob, jill); + plan.connect(bob, jane); + + SillyVisitor v = + new SillyVisitor(plan, new DepthFirstWalker(plan)); + + v.visit(); + + String s = v.getVisitPattern(); + + if (!s.equals("fredbobjilljanejoe") && + !s.equals("joebobjilljanefred")) { + System.out.println("Invalid order " + s); + fail(); + } + } + + // Tests for ReverseDependencyOrderWalker + + @Test + public void testReverseDependencyOrderWalkerLinear() throws IOException { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + SillyOperator bob = new SillyOperator("bob", plan); + + plan.add(fred); + plan.add(joe); + plan.add(bob); + + plan.connect(fred, joe); + plan.connect(joe, bob); + + SillyVisitor v = + new SillyVisitor(plan, new ReverseDependencyOrderWalker(plan)); + + v.visit(); + + String s = v.getVisitPattern(); + + assertEquals("bobjoefred", s); + } + + @Test + public void testReverseDependencyOrderWalkerTree() throws IOException { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + SillyOperator bob = new SillyOperator("bob", plan); + SillyOperator jill = new SillyOperator("jill", plan); + SillyOperator jane = new SillyOperator("jane", plan); + + plan.add(fred); + plan.add(joe); + plan.add(bob); + plan.add(jill); + plan.add(jane); + + plan.connect(fred, bob); + plan.connect(joe, bob); + plan.connect(bob, jill); + plan.connect(jane, jill); + + SillyVisitor v = + new SillyVisitor(plan, new ReverseDependencyOrderWalker(plan)); + + v.visit(); + + String s = v.getVisitPattern(); + + if (!s.equals("jilljanebobjoefred") && + !s.equals("jilljanebobfredjoe") && + !s.equals("jillbobjoefredjane") && + !s.equals("jillbobjoejanefred") && + !s.equals("jillbobfredjoejane") && + !s.equals("jillbobfredjanejoe") && + !s.equals("jillbobjanejoefred") && + !s.equals("jillbobjanefredjoe")) { + System.out.println("Invalid order " + s); + fail(); + } + } + + @Test + public void testReverseDependencyOrderWalkerGraph() throws IOException { + SillyPlan plan = new SillyPlan(); + SillyOperator fred = new SillyOperator("fred", plan); + SillyOperator joe = new SillyOperator("joe", plan); + SillyOperator bob = new SillyOperator("bob", plan); + SillyOperator jill = new SillyOperator("jill", plan); + SillyOperator jane = new SillyOperator("jane", plan); + + plan.add(fred); + plan.add(joe); + plan.add(bob); + plan.add(jill); + plan.add(jane); + + plan.connect(fred, bob); + plan.connect(joe, bob); + plan.connect(bob, jill); + plan.connect(bob, jane); + + SillyVisitor v = + new SillyVisitor(plan, new ReverseDependencyOrderWalker(plan)); + + v.visit(); + + String s = v.getVisitPattern(); + + if (!s.equals("jilljanebobjoefred") && + !s.equals("jilljanebobfredjoe") && + !s.equals("janejillbobjoefred") && + !s.equals("janejillbobfredjoe")) { + System.out.println("Invalid order " + s); + fail(); + } + } + +}
Added: hadoop/pig/trunk/test/org/apache/pig/test/TestExperimentalRule.java URL: http://svn.apache.org/viewvc/hadoop/pig/trunk/test/org/apache/pig/test/TestExperimentalRule.java?rev=898497&view=auto ============================================================================== --- hadoop/pig/trunk/test/org/apache/pig/test/TestExperimentalRule.java (added) +++ hadoop/pig/trunk/test/org/apache/pig/test/TestExperimentalRule.java Tue Jan 12 20:32:29 2010 @@ -0,0 +1,316 @@ +/* + * 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.pig.test; + +import java.util.List; + +import org.apache.pig.experimental.plan.BaseOperatorPlan; +import org.apache.pig.experimental.plan.Operator; +import org.apache.pig.experimental.plan.OperatorPlan; +import org.apache.pig.experimental.plan.PlanVisitor; +import org.apache.pig.experimental.plan.optimizer.Rule; +import org.apache.pig.experimental.plan.optimizer.Transformer; + +import junit.framework.TestCase; + +public class TestExperimentalRule extends TestCase { + + private static class SillyRule extends Rule { + + public SillyRule(String n, OperatorPlan p) { + super(n, p); + } + + @Override + public Transformer getNewTransformer() { + return null; + } + + @Override + protected OperatorPlan buildPattern() { + // TODO Auto-generated method stub + return null; + } + + } + + private static class SillyPlan extends BaseOperatorPlan { + + SillyPlan() { + super(); + } + + } + + private static class OP extends Operator { + OP(String n, OperatorPlan p) { + super(n, p); + } + + public void accept(PlanVisitor v) { + + } + } + + private static class OP_Load extends OP { + OP_Load(String n, OperatorPlan p) { + super(n, p); + } + } + + private static class OP_Filter extends OP { + OP_Filter(String n, OperatorPlan p) { + super(n, p); + } + } + + private static class OP_Split extends OP { + OP_Split(String n, OperatorPlan p) { + super(n, p); + } + } + + private static class OP_Store extends OP { + OP_Store(String n, OperatorPlan p) { + super(n, p); + } + } + + private static class OP_Join extends OP { + OP_Join(String n, OperatorPlan p) { + super(n, p); + } + } + + + OperatorPlan plan = null; + + public void setUp() { + plan = new SillyPlan(); + Operator l1 = new OP_Load("p1", plan); + plan.add(l1); + Operator l2 = new OP_Load("p2", plan); + plan.add(l2); + Operator j1 = new OP_Join("j1", plan); + plan.add(j1); + Operator f1 = new OP_Filter("f1", plan); + plan.add(f1); + Operator f2 = new OP_Filter("f2", plan); + plan.add(f2); + Operator t1 = new OP_Split("t1",plan); + plan.add(t1); + Operator f3 = new OP_Filter("f3", plan); + plan.add(f3); + Operator f4 = new OP_Filter("f4", plan); + plan.add(f4); + Operator s1 = new OP_Store("s1", plan); + plan.add(s1); + Operator s2 = new OP_Store("s2", plan); + plan.add(s2); + + // load --|-join - filter - filter - split |- filter - store + // load --| |- filter - store + plan.connect(l1, j1); + plan.connect(l2, j1); + plan.connect(j1, f1); + plan.connect(f1, f2); + plan.connect(f2, t1); + plan.connect(t1, f3); + plan.connect(t1, f4); + plan.connect(f3, s1); + plan.connect(f4, s2); + } + + public void testSingleNodeMatch() { + // search for Load + OperatorPlan pattern = new SillyPlan(); + pattern.add(new OP_Load("mmm", pattern)); + + Rule r = new SillyRule("basic", pattern); + List<OperatorPlan> l = r.match(plan); + assertEquals(l.size(), 2); + + Operator m1 = l.get(0).getRoots().get(0); + assertTrue(m1.getName().equals("p1") || m1.getName().equals("p2")); + assertEquals(l.get(0).size(), 1); + + Operator m2 = l.get(1).getRoots().get(0); + assertTrue(m2.getName().equals("p1") || m2.getName().equals("p2")); + assertEquals(l.get(1).size(), 1); + assertNotSame(m1.getName(), m2.getName()); + + // search for filter + pattern = new SillyPlan(); + pattern.add(new OP_Filter("mmm",pattern)); + r = new SillyRule("basic", pattern); + l = r.match(plan); + assertEquals(l.size(), 4); + + m1 = l.get(0).getRoots().get(0); + assertTrue(m1.getName().equals("f1") || m1.getName().equals("f2") + || m1.getName().equals("f3") || m1.getName().equals("f4")); + assertEquals(l.get(0).size(), 1); + + m2 = l.get(1).getRoots().get(0); + assertTrue(m1.getName().equals("f1") || m1.getName().equals("f2") + || m1.getName().equals("f3") || m1.getName().equals("f4")); + assertEquals(l.get(1).size(), 1); + assertNotSame(m1.getName(), m2.getName()); + + // search for store + pattern = new SillyPlan(); + pattern.add(new OP_Store("mmm",pattern)); + r = new SillyRule("basic", pattern); + l = r.match(plan); + assertEquals(l.size(), 2); + + m1 = l.get(0).getRoots().get(0); + assertTrue(m1.getName().equals("s1") || m1.getName().equals("s2")); + assertEquals(l.get(0).size(), 1); + + m2 = l.get(1).getRoots().get(0); + assertTrue(m2.getName().equals("s1") || m2.getName().equals("s2")); + assertEquals(l.get(1).size(), 1); + assertNotSame(m1.getName(), m2.getName()); + + // search for split + pattern = new SillyPlan(); + pattern.add(new OP_Split("mmm",pattern)); + r = new SillyRule("basic", pattern); + l = r.match(plan); + assertEquals(l.size(), 1); + + m1 = l.get(0).getRoots().get(0); + assertTrue(m1.getName().equals("t1")); + assertEquals(l.get(0).size(), 1); + + // search for join + pattern = new SillyPlan(); + pattern.add(new OP_Join("mmm",pattern)); + r = new SillyRule("basic", pattern); + l = r.match(plan); + assertEquals(l.size(), 1); + + m1 = l.get(0).getRoots().get(0); + assertTrue(m1.getName().equals("j1")); + assertEquals(l.get(0).size(), 1); + + } + + public void testTwoNodeMatch() { + // search for 2 Loads at the same time + OperatorPlan pattern = new SillyPlan(); + pattern.add(new OP_Load("mmm1", pattern)); + pattern.add(new OP_Load("mmm2", pattern)); + + Rule r = new SillyRule("basic", pattern); + List<OperatorPlan> l = r.match(plan); + assertEquals(l.size(), 1); + + assertEquals(l.get(0).getRoots().size(), 2); + assertEquals(l.get(0).getLeaves().size(), 2); + assertEquals(l.get(0).size(), 2); + + Operator m1 = l.get(0).getRoots().get(0); + assertTrue(m1.getName().equals("p1") || m1.getName().equals("p2")); + Operator m2 = l.get(0).getRoots().get(1); + assertTrue(m2.getName().equals("p1") || m2.getName().equals("p2")); + assertNotSame(m1.getName(), m2.getName()); + + + // search for join then filter + pattern = new SillyPlan(); + Operator s1 = new OP_Join("mmm1", pattern); + Operator s2 = new OP_Filter("mmm2", pattern); + pattern.add(s1); + pattern.add(s2); + pattern.connect(s1, s2); + + r = new SillyRule("basic", pattern); + l = r.match(plan); + assertEquals(l.size(), 1); + + assertEquals(l.get(0).getRoots().size(), 1); + assertEquals(l.get(0).getLeaves().size(), 1); + assertEquals(l.get(0).size(), 2); + + m1 = l.get(0).getRoots().get(0); + assertTrue(m1.getName().equals("j1")); + m2 = l.get(0).getLeaves().get(0); + assertTrue(m2.getName().equals("f1")); + + + // search for filter, then store + pattern = new SillyPlan(); + s1 = new OP_Filter("mmm1", pattern); + s2 = new OP_Store("mmm2", pattern); + pattern.add(s1); + pattern.add(s2); + pattern.connect(s1, s2); + + r = new SillyRule("basic", pattern); + l = r.match(plan); + assertEquals(2, l.size()); + + assertEquals(l.get(0).getRoots().size(), 1); + assertEquals(l.get(0).getLeaves().size(), 1); + + // search for 2 loads, then join + pattern = new SillyPlan(); + s1 = new OP_Load("mmm1", pattern); + s2 = new OP_Load("mmm2", pattern); + Operator s3 = new OP_Join("jjj", pattern); + pattern.add(s1); + pattern.add(s2); + pattern.add(s3); + pattern.connect(s1, s3); + pattern.connect(s2, s3); + + r = new SillyRule("basic", pattern); + l = r.match(plan); + assertEquals(l.size(), 1); + + // search for split then 2 filters + pattern = new SillyPlan(); + s1 = new OP_Split("mmm1", pattern); + s2 = new OP_Filter("mmm2", pattern); + s3 = new OP_Filter("mmm3", pattern); + pattern.add(s1); + pattern.add(s2); + pattern.add(s3); + pattern.connect(s1, s2); + pattern.connect(s1, s3); + + r = new SillyRule("basic", pattern); + l = r.match(plan); + assertEquals(1, l.size()); + + assertEquals(l.get(0).getRoots().size(), 1); + assertEquals(l.get(0).getLeaves().size(), 2); + assertEquals(l.get(0).size(), 3); + + m1 = l.get(0).getRoots().get(0); + assertTrue(m1.getName().equals("t1")); + m2 = l.get(0).getLeaves().get(0); + assertTrue(m2.getName().equals("f3") || m2.getName().equals("f4")); + m2 = l.get(0).getLeaves().get(1); + assertTrue(m2.getName().equals("f3") || m2.getName().equals("f4")); + } + +}