/* * ************************************************************************************* * Copyright (C) 2008 EsperTech, Inc. All rights reserved. * * http://esper.codehaus.org * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * * ************************************************************************************* */ package com.espertech.esper.filter; import junit.framework.TestCase; import com.espertech.esper.support.bean.SupportBean; import com.espertech.esper.support.filter.SupportFilterSpecBuilder; import com.espertech.esper.support.filter.SupportFilterHandle; import com.espertech.esper.support.event.SupportEventBeanFactory; import com.espertech.esper.client.EventType; import com.espertech.esper.client.EventBean; import java.util.LinkedList; import java.util.List; public class TestIndexTreeBuilder extends TestCase { List<FilterHandle> matches; IndexTreeBuilder builder; EventBean eventBean; EventType eventType; FilterHandle testFilterCallback[]; public void setUp() { SupportBean testBean = new SupportBean(); testBean.setIntPrimitive(50); testBean.setDoublePrimitive(0.5); testBean.setTheString("jack"); testBean.setLongPrimitive(10); testBean.setShortPrimitive((short) 20); builder = new IndexTreeBuilder(); eventBean = SupportEventBeanFactory.createObject(testBean); eventType = eventBean.getEventType(); matches = new LinkedList<FilterHandle>(); // Allocate a couple of callbacks testFilterCallback = new SupportFilterHandle[20]; for (int i = 0; i < testFilterCallback.length; i++) { testFilterCallback[i] = new SupportFilterHandle(); } } public void testBuildWithMatch() { FilterHandleSetNode topNode = new FilterHandleSetNode(); // Add some parameter-less expression FilterValueSet filterSpec = makeFilterValues(); builder.add(filterSpec, testFilterCallback[0], topNode); assertTrue(topNode.contains(testFilterCallback[0])); // Attempt a match topNode.matchEvent(eventBean, matches); assertTrue(matches.size() == 1); matches.clear(); // Add a filter that won't match, with a single parameter matching against an int filterSpec = makeFilterValues("intPrimitive", FilterOperator.EQUAL, 100); builder.add(filterSpec, testFilterCallback[1], topNode); assertTrue(topNode.getIndizes().size() == 1); assertTrue(topNode.getIndizes().get(0).size() == 1); // Match again topNode.matchEvent(eventBean, matches); assertTrue(matches.size() == 1); matches.clear(); // Add a filter that will match filterSpec = makeFilterValues("intPrimitive", FilterOperator.EQUAL, 50); builder.add(filterSpec, testFilterCallback[2], topNode); assertTrue(topNode.getIndizes().size() == 1); assertTrue(topNode.getIndizes().get(0).size() == 2); // match topNode.matchEvent(eventBean, matches); assertTrue(matches.size() == 2); matches.clear(); // Add some filter against a double filterSpec = makeFilterValues("doublePrimitive", FilterOperator.LESS, 1.1); builder.add(filterSpec, testFilterCallback[3], topNode); assertTrue(topNode.getIndizes().size() == 2); assertTrue(topNode.getIndizes().get(0).size() == 2); assertTrue(topNode.getIndizes().get(1).size() == 1); topNode.matchEvent(eventBean, matches); assertTrue(matches.size() == 3); matches.clear(); filterSpec = makeFilterValues("doublePrimitive", FilterOperator.LESS_OR_EQUAL, 0.5); builder.add(filterSpec, testFilterCallback[4], topNode); assertTrue(topNode.getIndizes().size() == 3); assertTrue(topNode.getIndizes().get(0).size() == 2); assertTrue(topNode.getIndizes().get(1).size() == 1); assertTrue(topNode.getIndizes().get(2).size() == 1); topNode.matchEvent(eventBean, matches); assertTrue(matches.size() == 4); matches.clear(); // Add an filterSpec against double and string filterSpec = makeFilterValues("doublePrimitive", FilterOperator.LESS, 1.1, "theString", FilterOperator.EQUAL, "jack"); builder.add(filterSpec, testFilterCallback[5], topNode); assertTrue(topNode.getIndizes().size() == 3); assertTrue(topNode.getIndizes().get(0).size() == 2); assertTrue(topNode.getIndizes().get(1).size() == 1); assertTrue(topNode.getIndizes().get(2).size() == 1); FilterHandleSetNode nextLevelSetNode = (FilterHandleSetNode) topNode.getIndizes().get(1).get(Double.valueOf(1.1)); assertTrue(nextLevelSetNode != null); assertTrue(nextLevelSetNode.getIndizes().size() == 1); topNode.matchEvent(eventBean, matches); assertTrue(matches.size() == 5); matches.clear(); filterSpec = makeFilterValues("doublePrimitive", FilterOperator.LESS, 1.1, "theString", FilterOperator.EQUAL, "beta"); builder.add(filterSpec, testFilterCallback[6], topNode); topNode.matchEvent(eventBean, matches); assertTrue(matches.size() == 5); matches.clear(); filterSpec = makeFilterValues("doublePrimitive", FilterOperator.LESS, 1.1, "theString", FilterOperator.EQUAL, "jack"); builder.add(filterSpec, testFilterCallback[7], topNode); assertTrue(nextLevelSetNode.getIndizes().size() == 1); FilterHandleSetNode nodeTwo = (FilterHandleSetNode) nextLevelSetNode.getIndizes().get(0).get("jack"); assertTrue(nodeTwo.getFilterCallbackCount() == 2); topNode.matchEvent(eventBean, matches); assertTrue(matches.size() == 6); matches.clear(); // Try depth first filterSpec = makeFilterValues("theString", FilterOperator.EQUAL, "jack", "longPrimitive", FilterOperator.EQUAL, 10L, "shortPrimitive", FilterOperator.EQUAL, (short) 20); builder.add(filterSpec, testFilterCallback[8], topNode); topNode.matchEvent(eventBean, matches); assertTrue(matches.size() == 7); matches.clear(); // Add an filterSpec in the middle filterSpec = makeFilterValues("longPrimitive", FilterOperator.EQUAL, 10L, "theString", FilterOperator.EQUAL, "jack"); builder.add(filterSpec, testFilterCallback[9], topNode); filterSpec = makeFilterValues("longPrimitive", FilterOperator.EQUAL, 10L, "theString", FilterOperator.EQUAL, "jim"); builder.add(filterSpec, testFilterCallback[10], topNode); filterSpec = makeFilterValues("longPrimitive", FilterOperator.EQUAL, 10L, "theString", FilterOperator.EQUAL, "joe"); builder.add(filterSpec, testFilterCallback[11], topNode); topNode.matchEvent(eventBean, matches); assertTrue(matches.size() == 8); matches.clear(); } public void testBuildMatchRemove() { FilterHandleSetNode top = new FilterHandleSetNode(); // Add a parameter-less filter FilterValueSet filterSpecNoParams = makeFilterValues(); IndexTreePath pathAddedTo = builder.add(filterSpecNoParams, testFilterCallback[0], top); // Try a match top.matchEvent(eventBean, matches); assertTrue(matches.size() == 1); matches.clear(); // Remove filter builder.remove(eventType, testFilterCallback[0], pathAddedTo, top); // Match should not be found top.matchEvent(eventBean, matches); assertTrue(matches.size() == 0); matches.clear(); // Add a depth-first filterSpec FilterValueSet filterSpecOne = makeFilterValues( "theString", FilterOperator.EQUAL, "jack", "longPrimitive", FilterOperator.EQUAL, 10L, "shortPrimitive", FilterOperator.EQUAL, (short) 20); IndexTreePath pathAddedToOne = builder.add(filterSpecOne, testFilterCallback[1], top); FilterValueSet filterSpecTwo = makeFilterValues( "theString", FilterOperator.EQUAL, "jack", "longPrimitive", FilterOperator.EQUAL, 10L, "shortPrimitive", FilterOperator.EQUAL, (short) 20); IndexTreePath pathAddedToTwo = builder.add(filterSpecTwo, testFilterCallback[2], top); FilterValueSet filterSpecThree = makeFilterValues( "theString", FilterOperator.EQUAL, "jack", "longPrimitive", FilterOperator.EQUAL, 10L); IndexTreePath pathAddedToThree = builder.add(filterSpecThree, testFilterCallback[3], top); FilterValueSet filterSpecFour = makeFilterValues( "theString", FilterOperator.EQUAL, "jack"); IndexTreePath pathAddedToFour = builder.add(filterSpecFour, testFilterCallback[4], top); FilterValueSet filterSpecFive = makeFilterValues( "longPrimitive", FilterOperator.EQUAL, 10L); IndexTreePath pathAddedToFive = builder.add(filterSpecFive, testFilterCallback[5], top); top.matchEvent(eventBean, matches); assertTrue(matches.size() == 5); matches.clear(); // Remove some of the nodes builder.remove(eventType, testFilterCallback[2], pathAddedToTwo, top); top.matchEvent(eventBean, matches); assertTrue(matches.size() == 4); matches.clear(); // Remove some of the nodes builder.remove(eventType, testFilterCallback[4], pathAddedToFour, top); top.matchEvent(eventBean, matches); assertTrue(matches.size() == 3); matches.clear(); // Remove some of the nodes builder.remove(eventType, testFilterCallback[5], pathAddedToFive, top); top.matchEvent(eventBean, matches); assertTrue(matches.size() == 2); matches.clear(); // Remove some of the nodes builder.remove(eventType, testFilterCallback[1], pathAddedToOne, top); top.matchEvent(eventBean, matches); assertTrue(matches.size() == 1); matches.clear(); // Remove some of the nodes builder.remove(eventType, testFilterCallback[3], pathAddedToThree, top); top.matchEvent(eventBean, matches); assertTrue(matches.size() == 0); matches.clear(); } private FilterValueSet makeFilterValues(Object ... filterSpecArgs) { FilterSpecCompiled spec = SupportFilterSpecBuilder.build(eventType, filterSpecArgs); FilterValueSet filterValues = spec.getValueSet(null, null, null); return filterValues; } }