/// <summary> /// Remove a filter callback from the given index node. /// </summary> /// <param name="filterCallback">is the callback to remove</param> public void Remove(FilterHandle filterCallback, FilterServiceEntry filterServiceEntry) { EventTypeIndexBuilderValueIndexesPair pair; if (_isolatableCallbacks != null) { using (_callbacksLock.Acquire()) { pair = _isolatableCallbacks.Pluck(filterCallback); } if (pair == null) { return; } } else { pair = (EventTypeIndexBuilderValueIndexesPair)filterServiceEntry; } using (Instrument.With( i => i.QFilterRemove(filterCallback, pair), i => i.AFilterRemove())) { var eventType = pair.FilterValueSet.EventType; var rootNode = _eventTypeIndex.Get(eventType); // Now remove from tree if (rootNode != null) { pair.IndexPairs.ForEach( indexPair => IndexTreeBuilder.Remove(eventType, filterCallback, indexPair, rootNode)); } } }
/// <summary> /// Add a filter to the event type index structure, and to the filter subtree. /// Throws an IllegalStateException exception if the callback is already registered. /// </summary> /// <param name="filterValueSet">is the filter information</param> /// <param name="filterCallback">is the callback</param> /// <param name="lockFactory">The lock factory.</param> /// <returns></returns> /// <exception cref="IllegalStateException">Callback for filter specification already exists in collection</exception> public FilterServiceEntry Add(FilterValueSet filterValueSet, FilterHandle filterCallback, FilterServiceGranularLockFactory lockFactory) { using (Instrument.With( i => i.QFilterAdd(filterValueSet, filterCallback), i => i.AFilterAdd())) { var eventType = filterValueSet.EventType; // Check if a filter tree exists for this event type var rootNode = _eventTypeIndex.Get(eventType); // Make sure we have a root node if (rootNode == null) { using (_callbacksLock.Acquire()) { rootNode = _eventTypeIndex.Get(eventType); if (rootNode == null) { rootNode = new FilterHandleSetNode(lockFactory.ObtainNew()); _eventTypeIndex.Add(eventType, rootNode); } } } // GetInstance add to tree var path = IndexTreeBuilder.Add(filterValueSet, filterCallback, rootNode, lockFactory); var pathArray = path.Select(p => p.ToArray()).ToArray(); var pair = new EventTypeIndexBuilderValueIndexesPair(filterValueSet, pathArray); // for non-isolatable callbacks the consumer keeps track of tree location if (_isolatableCallbacks == null) { return(pair); } // for isolatable callbacks this class is keeping track of tree location using (_callbacksLock.Acquire()) { _isolatableCallbacks.Put(filterCallback, pair); } return(null); } }
public void TestVerifyFilterSpecSet() { // Add all the above filter definitions foreach (var filterSpec in _testFilterSpecs) { var filterValues = filterSpec.GetValueSet(null, null, null); FilterHandle callback = new SupportFilterHandle(); _filterCallbacks.Add(callback); _pathsAddedTo.Add(IndexTreeBuilder.Add(filterValues, callback, _topNode, _lockFactory)[0]); } // None of the not-matching events should cause any match foreach (var theEvent in _unmatchedEvents) { IList <FilterHandle> matches = new List <FilterHandle>(); _topNode.MatchEvent(theEvent, matches); Assert.IsTrue(matches.Count == 0); } // All of the matching events should cause exactly one match foreach (var theEvent in _matchedEvents) { IList <FilterHandle> matches = new List <FilterHandle>(); _topNode.MatchEvent(theEvent, matches); Assert.IsTrue(matches.Count == 1); } // Remove all expressions previously added var count = 0; foreach (var treePath in _pathsAddedTo) { var callback = _filterCallbacks[count++]; IndexTreeBuilder.Remove(_eventType, callback, treePath.ToArray(), _topNode); } // After the remove no matches are expected foreach (var theEvent in _matchedEvents) { IList <FilterHandle> matches = new List <FilterHandle>(); _topNode.MatchEvent(theEvent, matches); Assert.IsTrue(matches.Count == 0); } }
public void TestBuildWithMatch() { var topNode = new FilterHandleSetNode(_container.RWLockManager().CreateDefaultLock()); // Add some parameter-less expression var filterSpec = MakeFilterValues(); IndexTreeBuilder.Add(filterSpec, _testFilterCallback[0], topNode, _lockFactory); Assert.IsTrue(topNode.Contains(_testFilterCallback[0])); // Attempt a match topNode.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 1); _matches.Clear(); // Add a filter that won't match, with a single parameter matching against an int filterSpec = MakeFilterValues("IntPrimitive", FilterOperator.EQUAL, 100); IndexTreeBuilder.Add(filterSpec, _testFilterCallback[1], topNode, _lockFactory); Assert.IsTrue(topNode.Indizes.Count == 1); Assert.IsTrue(topNode.Indizes[0].Count == 1); // Match again topNode.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 1); _matches.Clear(); // Add a filter that will match filterSpec = MakeFilterValues("IntPrimitive", FilterOperator.EQUAL, 50); IndexTreeBuilder.Add(filterSpec, _testFilterCallback[2], topNode, _lockFactory); Assert.IsTrue(topNode.Indizes.Count == 1); Assert.IsTrue(topNode.Indizes[0].Count == 2); // match topNode.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 2); _matches.Clear(); // Add some filter against a double filterSpec = MakeFilterValues("DoublePrimitive", FilterOperator.LESS, 1.1); IndexTreeBuilder.Add(filterSpec, _testFilterCallback[3], topNode, _lockFactory); Assert.IsTrue(topNode.Indizes.Count == 2); Assert.IsTrue(topNode.Indizes[0].Count == 2); Assert.IsTrue(topNode.Indizes[1].Count == 1); topNode.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 3); _matches.Clear(); filterSpec = MakeFilterValues("DoublePrimitive", FilterOperator.LESS_OR_EQUAL, 0.5); IndexTreeBuilder.Add(filterSpec, _testFilterCallback[4], topNode, _lockFactory); Assert.IsTrue(topNode.Indizes.Count == 3); Assert.IsTrue(topNode.Indizes[0].Count == 2); Assert.IsTrue(topNode.Indizes[1].Count == 1); Assert.IsTrue(topNode.Indizes[2].Count == 1); topNode.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 4); _matches.Clear(); // Add an filterSpec against double and string filterSpec = MakeFilterValues("DoublePrimitive", FilterOperator.LESS, 1.1, "TheString", FilterOperator.EQUAL, "jack"); IndexTreeBuilder.Add(filterSpec, _testFilterCallback[5], topNode, _lockFactory); Assert.IsTrue(topNode.Indizes.Count == 3); Assert.IsTrue(topNode.Indizes[0].Count == 2); Assert.IsTrue(topNode.Indizes[1].Count == 1); Assert.IsTrue(topNode.Indizes[2].Count == 1); var nextLevelSetNode = (FilterHandleSetNode)topNode.Indizes[1][1.1d]; Assert.IsTrue(nextLevelSetNode != null); Assert.IsTrue(nextLevelSetNode.Indizes.Count == 1); topNode.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 5); _matches.Clear(); filterSpec = MakeFilterValues("DoublePrimitive", FilterOperator.LESS, 1.1, "TheString", FilterOperator.EQUAL, "beta"); IndexTreeBuilder.Add(filterSpec, _testFilterCallback[6], topNode, _lockFactory); topNode.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 5); _matches.Clear(); filterSpec = MakeFilterValues("DoublePrimitive", FilterOperator.LESS, 1.1, "TheString", FilterOperator.EQUAL, "jack"); IndexTreeBuilder.Add(filterSpec, _testFilterCallback[7], topNode, _lockFactory); Assert.IsTrue(nextLevelSetNode.Indizes.Count == 1); var nodeTwo = (FilterHandleSetNode)nextLevelSetNode.Indizes[0]["jack"]; Assert.IsTrue(nodeTwo.FilterCallbackCount == 2); topNode.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 6); _matches.Clear(); // Try depth first filterSpec = MakeFilterValues("TheString", FilterOperator.EQUAL, "jack", "LongPrimitive", FilterOperator.EQUAL, 10L, "ShortPrimitive", FilterOperator.EQUAL, (short)20); IndexTreeBuilder.Add(filterSpec, _testFilterCallback[8], topNode, _lockFactory); topNode.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 7); _matches.Clear(); // Add an filterSpec in the middle filterSpec = MakeFilterValues("LongPrimitive", FilterOperator.EQUAL, 10L, "TheString", FilterOperator.EQUAL, "jack"); IndexTreeBuilder.Add(filterSpec, _testFilterCallback[9], topNode, _lockFactory); filterSpec = MakeFilterValues("LongPrimitive", FilterOperator.EQUAL, 10L, "TheString", FilterOperator.EQUAL, "jim"); IndexTreeBuilder.Add(filterSpec, _testFilterCallback[10], topNode, _lockFactory); filterSpec = MakeFilterValues("LongPrimitive", FilterOperator.EQUAL, 10L, "TheString", FilterOperator.EQUAL, "joe"); IndexTreeBuilder.Add(filterSpec, _testFilterCallback[11], topNode, _lockFactory); topNode.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 8); _matches.Clear(); }
public void TestBuildMatchRemove() { var top = new FilterHandleSetNode(_container.RWLockManager().CreateDefaultLock()); // Add a parameter-less filter var filterSpecNoParams = MakeFilterValues(); var pathAddedTo = IndexTreeBuilder.Add(filterSpecNoParams, _testFilterCallback[0], top, _lockFactory); // Try a match top.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 1); _matches.Clear(); // Remove filter IndexTreeBuilder.Remove(_eventType, _testFilterCallback[0], ToArrayPath(pathAddedTo[0]), top); // Match should not be found top.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 0); _matches.Clear(); // Add a depth-first filterSpec var filterSpecOne = MakeFilterValues( "TheString", FilterOperator.EQUAL, "jack", "LongPrimitive", FilterOperator.EQUAL, 10L, "ShortPrimitive", FilterOperator.EQUAL, (short)20); var pathAddedToOne = IndexTreeBuilder.Add(filterSpecOne, _testFilterCallback[1], top, _lockFactory); var filterSpecTwo = MakeFilterValues( "TheString", FilterOperator.EQUAL, "jack", "LongPrimitive", FilterOperator.EQUAL, 10L, "ShortPrimitive", FilterOperator.EQUAL, (short)20); var pathAddedToTwo = IndexTreeBuilder.Add(filterSpecTwo, _testFilterCallback[2], top, _lockFactory); var filterSpecThree = MakeFilterValues( "TheString", FilterOperator.EQUAL, "jack", "LongPrimitive", FilterOperator.EQUAL, 10L); var pathAddedToThree = IndexTreeBuilder.Add(filterSpecThree, _testFilterCallback[3], top, _lockFactory); var filterSpecFour = MakeFilterValues( "TheString", FilterOperator.EQUAL, "jack"); var pathAddedToFour = IndexTreeBuilder.Add(filterSpecFour, _testFilterCallback[4], top, _lockFactory); var filterSpecFive = MakeFilterValues( "LongPrimitive", FilterOperator.EQUAL, 10L); var pathAddedToFive = IndexTreeBuilder.Add(filterSpecFive, _testFilterCallback[5], top, _lockFactory); top.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 5); _matches.Clear(); // Remove some of the nodes IndexTreeBuilder.Remove(_eventType, _testFilterCallback[2], ToArrayPath(pathAddedToTwo[0]), top); top.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 4); _matches.Clear(); // Remove some of the nodes IndexTreeBuilder.Remove(_eventType, _testFilterCallback[4], ToArrayPath(pathAddedToFour[0]), top); top.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 3); _matches.Clear(); // Remove some of the nodes IndexTreeBuilder.Remove(_eventType, _testFilterCallback[5], ToArrayPath(pathAddedToFive[0]), top); top.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 2); _matches.Clear(); // Remove some of the nodes IndexTreeBuilder.Remove(_eventType, _testFilterCallback[1], ToArrayPath(pathAddedToOne[0]), top); top.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 1); _matches.Clear(); // Remove some of the nodes IndexTreeBuilder.Remove(_eventType, _testFilterCallback[3], ToArrayPath(pathAddedToThree[0]), top); top.MatchEvent(_eventBean, _matches); Assert.IsTrue(_matches.Count == 0); _matches.Clear(); }