public void SetUp() { SupportBean testBean = new SupportBean(); _testEventBean = SupportEventBeanFactory.CreateObject(testBean); _testEventType = _testEventBean.EventType; _handleSetNode = new FilterHandleSetNode(ReaderWriterLockManager.CreateDefaultLock()); _filterCallback = new SupportFilterHandle(); _handleSetNode.Add(_filterCallback); _testIndex = new EventTypeIndex(new FilterServiceGranularLockFactoryReentrant()); _testIndex.Add(_testEventType, _handleSetNode); }
public void TestNodeGetSet() { FilterHandle exprOne = new SupportFilterHandle(); // Check pre-conditions Assert.IsTrue(_testNode.NodeRWLock != null); Assert.IsFalse(_testNode.Contains(exprOne)); Assert.AreEqual(0, _testNode.FilterCallbackCount); Assert.AreEqual(0, _testNode.Indizes.Count); Assert.IsTrue(_testNode.IsEmpty()); _testNode.Add(exprOne); // Check after add Assert.IsTrue(_testNode.Contains(exprOne)); Assert.AreEqual(1, _testNode.FilterCallbackCount); Assert.IsFalse(_testNode.IsEmpty()); // Add an indexOne EventType eventType = SupportEventTypeFactory.CreateBeanType(typeof(SupportBean)); FilterSpecLookupable lookupable = new FilterSpecLookupable("IntPrimitive", eventType.GetGetter("IntPrimitive"), eventType.GetPropertyType("IntPrimitive"), false); FilterParamIndexBase indexOne = new SupportFilterParamIndex(lookupable); _testNode.Add(indexOne); // Check after add Assert.AreEqual(1, _testNode.Indizes.Count); Assert.AreEqual(indexOne, _testNode.Indizes.FirstOrDefault()); // Check removes Assert.IsTrue(_testNode.Remove(exprOne)); Assert.IsFalse(_testNode.IsEmpty()); Assert.IsFalse(_testNode.Remove(exprOne)); Assert.IsTrue(_testNode.Remove(indexOne)); Assert.IsFalse(_testNode.Remove(indexOne)); Assert.IsTrue(_testNode.IsEmpty()); }
/// <summary> /// Add to an index the value to filter for. /// </summary> /// <param name="remainingParameters">The remaining parameters.</param> /// <param name="filterCallback">The filter callback.</param> /// <param name="index">is the index to add to</param> /// <param name="filterForValue">is the filter parameter value to add</param> /// <param name="treePathInfo">is the specification to fill on where is was added</param> /// <param name="lockFactory">The lock factory.</param> private static void AddToIndex( ArrayDeque <FilterValueSetParam> remainingParameters, FilterHandle filterCallback, FilterParamIndexBase index, Object filterForValue, ArrayDeque <EventTypeIndexBuilderIndexLookupablePair> treePathInfo, FilterServiceGranularLockFactory lockFactory) { if ((ExecutionPathDebugLog.IsEnabled) && (Log.IsDebugEnabled)) { Log.Debug(".addToIndex ({0}) Adding to index {1} expressionValue={2}", Thread.CurrentThread.ManagedThreadId, index, filterForValue); } EventEvaluator eventEvaluator; using (index.ReadWriteLock.AcquireReadLock()) { eventEvaluator = index[filterForValue]; // The filter parameter value already existed in bean, add and release locks if (eventEvaluator != null) { var added = AddToEvaluator(remainingParameters, filterCallback, eventEvaluator, treePathInfo, lockFactory); if (added) { return; } } } // new filter parameter value, need a write lock using (index.ReadWriteLock.AcquireWriteLock()) { eventEvaluator = index[filterForValue]; // It may exist now since another thread could have added the entry if (eventEvaluator != null) { var added = AddToEvaluator(remainingParameters, filterCallback, eventEvaluator, treePathInfo, lockFactory); if (added) { return; } // The found eventEvaluator must be converted to a new FilterHandleSetNode var nextIndexX = (FilterParamIndexBase)eventEvaluator; var newNode = new FilterHandleSetNode(lockFactory.ObtainNew()); newNode.Add(nextIndexX); index.Remove(filterForValue); index[filterForValue] = newNode; AddToNode(remainingParameters, filterCallback, newNode, treePathInfo, lockFactory); return; } // The index does not currently have this filterCallback value, // if there are no remaining parameters, create a node if (remainingParameters.IsEmpty()) { var node = new FilterHandleSetNode(lockFactory.ObtainNew()); AddToNode(remainingParameters, filterCallback, node, treePathInfo, lockFactory); index[filterForValue] = node; return; } // If there are remaining parameters, create a new index for the next parameter FilterValueSetParam parameterPickedForIndex = remainingParameters.RemoveFirst(); var nextIndex = IndexFactory.CreateIndex(parameterPickedForIndex.Lookupable, lockFactory, parameterPickedForIndex.FilterOperator); index[filterForValue] = nextIndex; treePathInfo.Add(new EventTypeIndexBuilderIndexLookupablePair(nextIndex, parameterPickedForIndex.FilterForValue)); AddToIndex(remainingParameters, filterCallback, nextIndex, parameterPickedForIndex.FilterForValue, treePathInfo, lockFactory); } }
/// <summary> /// Add to the current node building up the tree path information. /// </summary> /// <param name="remainingParameters">The remaining parameters.</param> /// <param name="filterCallback">The filter callback.</param> /// <param name="currentNode">is the node to add to</param> /// <param name="treePathInfo">is filled with information about which indizes were chosen to add the filter to</param> /// <param name="lockFactory">The lock factory.</param> private static void AddToNode( ArrayDeque <FilterValueSetParam> remainingParameters, FilterHandle filterCallback, FilterHandleSetNode currentNode, ArrayDeque <EventTypeIndexBuilderIndexLookupablePair> treePathInfo, FilterServiceGranularLockFactory lockFactory) { if ((ExecutionPathDebugLog.IsEnabled) && (Log.IsDebugEnabled)) { Log.Debug(".addToNode (" + Thread.CurrentThread.ManagedThreadId + ") Adding filterCallback, node=" + currentNode + " remainingParameters=" + PrintRemainingParameters(remainingParameters)); } // If no parameters are specified, add to current node, and done if (remainingParameters.IsEmpty()) { using (currentNode.NodeRWLock.AcquireWriteLock()) { currentNode.Add(filterCallback); } return; } // Need to find an existing index that matches one of the filter parameters Pair <FilterValueSetParam, FilterParamIndexBase> pair; using (currentNode.NodeRWLock.AcquireReadLock()) { pair = IndexHelper.FindIndex(remainingParameters, currentNode.Indizes); // Found an index matching a filter parameter if (pair != null) { remainingParameters.Remove(pair.First); var filterForValue = pair.First.FilterForValue; var index = pair.Second; treePathInfo.Add(new EventTypeIndexBuilderIndexLookupablePair(index, filterForValue)); AddToIndex(remainingParameters, filterCallback, index, filterForValue, treePathInfo, lockFactory); return; } } // An index for any of the filter parameters was not found, create one using (currentNode.NodeRWLock.AcquireWriteLock()) { pair = IndexHelper.FindIndex(remainingParameters, currentNode.Indizes); // Attempt to find an index again this time under a write lock if (pair != null) { remainingParameters.Remove(pair.First); var filterForValue = pair.First.FilterForValue; var indexX = pair.Second; treePathInfo.Add(new EventTypeIndexBuilderIndexLookupablePair(indexX, filterForValue)); AddToIndex(remainingParameters, filterCallback, indexX, filterForValue, treePathInfo, lockFactory); return; } // No index found that matches any parameters, create a new one // Pick the next parameter for an index FilterValueSetParam parameterPickedForIndex = remainingParameters.RemoveFirst(); var index = IndexFactory.CreateIndex(parameterPickedForIndex.Lookupable, lockFactory, parameterPickedForIndex.FilterOperator); currentNode.Indizes.Add(index); treePathInfo.Add(new EventTypeIndexBuilderIndexLookupablePair(index, parameterPickedForIndex.FilterForValue)); AddToIndex(remainingParameters, filterCallback, index, parameterPickedForIndex.FilterForValue, treePathInfo, lockFactory); } }