예제 #1
0
        /// <summary>
        /// Add a filter callback according to the filter specification to the top node returning information to be used to remove the filter callback.
        /// </summary>
        /// <param name="filterValueSet">is the filter definition</param>
        /// <param name="filterCallback">is the callback to be added</param>
        /// <param name="topNode">node to be added to any subnode beneath it</param>
        /// <param name="lockFactory">The lock factory.</param>
        /// <returns>
        /// an encapsulation of information need to allow for safe removal of the filter tree.
        /// </returns>
        public static ArrayDeque <EventTypeIndexBuilderIndexLookupablePair>[] Add(
            FilterValueSet filterValueSet,
            FilterHandle filterCallback,
            FilterHandleSetNode topNode,
            FilterServiceGranularLockFactory lockFactory)
        {
            if ((ExecutionPathDebugLog.IsEnabled) && (Log.IsDebugEnabled))
            {
                Log.Debug(".add (" + Thread.CurrentThread.ManagedThreadId + ") Adding filter callback, " +
                          "  topNode=" + topNode +
                          "  filterCallback=" + filterCallback);
            }

            ArrayDeque <EventTypeIndexBuilderIndexLookupablePair>[] treePathInfo;
            if (filterValueSet.Parameters.Length == 0)
            {
                treePathInfo    = AllocateTreePath(1);
                treePathInfo[0] = new ArrayDeque <EventTypeIndexBuilderIndexLookupablePair>(1);
                AddToNode(new ArrayDeque <FilterValueSetParam>(1), filterCallback, topNode, treePathInfo[0], lockFactory);
            }
            else
            {
                treePathInfo = AllocateTreePath(filterValueSet.Parameters.Length);
                var remainingParameters = new ArrayDeque <FilterValueSetParam>(4);
                for (int i = 0; i < filterValueSet.Parameters.Length; i++)
                {
                    treePathInfo[i] = new ArrayDeque <EventTypeIndexBuilderIndexLookupablePair>(filterValueSet.Parameters[i].Length);
                    remainingParameters.Clear();
                    remainingParameters.AddAll(filterValueSet.Parameters[i]);
                    AddToNode(remainingParameters, filterCallback, topNode, treePathInfo[i], lockFactory);
                }
            }

            return(treePathInfo);
        }
예제 #2
0
        private void PerformMultithreadedTest(FilterHandleSetNode topNode,
                                              int numberOfThreads,
                                              int numberOfRunnables,
                                              int numberOfSecondsSleep)
        {
            Log.Info(".performMultithreadedTest Loading thread pool work queue,numberOfRunnables=" + numberOfRunnables);

            var pool = new DedicatedExecutorService("test", numberOfThreads, new ImperfectBlockingQueue <Runnable>());

            for (var i = 0; i < numberOfRunnables; i++)
            {
                var runnable = new IndexTreeBuilderRunnable(_eventType, topNode, _testFilterSpecs, _matchedEvents, _unmatchedEvents);
                pool.Submit(runnable.Run);
            }

            Log.Info(".performMultithreadedTest Starting thread pool, threads=" + numberOfThreads);

            // Sleep X seconds
            Sleep(numberOfSecondsSleep);

            Log.Info(".performMultithreadedTest Completed, numberOfRunnables=" + numberOfRunnables +
                     "  numberOfThreads=" + numberOfThreads +
                     "  completed=" + pool.NumExecuted);

            pool.Shutdown();
            pool.AwaitTermination(TimeSpan.FromSeconds(1));

            Assert.AreEqual(pool.NumExecuted, numberOfRunnables);
        }
예제 #3
0
 /// <summary>Returns the root node for the given event type, or null if this event type has not been seen before. </summary>
 /// <param name="eventType">is an event type</param>
 /// <returns>the subtree's root node</returns>
 public FilterHandleSetNode Get(EventType eventType)
 {
     using (_eventTypesLock.AcquireReadLock())
     {
         FilterHandleSetNode result = _eventTypes.Get(eventType);
         return(result);
     }
 }
예제 #4
0
        public void SetUp()
        {
            _container = SupportContainer.Reset();

            _lockFactory     = new FilterServiceGranularLockFactoryReentrant(_container.RWLockManager());
            _eventType       = SupportEventTypeFactory.CreateBeanType(typeof(SupportBean));
            _topNode         = new FilterHandleSetNode(_container.RWLockManager().CreateDefaultLock());
            _filterCallbacks = new List <FilterHandle>();
            _pathsAddedTo    = new List <ArrayDeque <EventTypeIndexBuilderIndexLookupablePair> >();

            _testFilterSpecs = new List <FilterSpecCompiled>();
            _matchedEvents   = new List <EventBean>();
            _unmatchedEvents = new List <EventBean>();

            // Any int and double value specified here must match only the current filter spec not any other filter spec
            _testFilterSpecs.Add(MakeSpec(new Object[] { "IntPrimitive", FilterOperator.GREATER_OR_EQUAL, 100000 }));
            _matchedEvents.Add(MakeEvent(9999999, -1));
            _unmatchedEvents.Add(MakeEvent(0, -1));

            _testFilterSpecs.Add(MakeSpec(new Object[] { "IntPrimitive", FilterOperator.GREATER_OR_EQUAL, 10,
                                                         "DoublePrimitive", FilterOperator.EQUAL, 0.5 }));
            _matchedEvents.Add(MakeEvent(10, 0.5));
            _unmatchedEvents.Add(MakeEvent(0, 0.5));

            _testFilterSpecs.Add(MakeSpec(new Object[] { "DoublePrimitive", FilterOperator.EQUAL, 0.8 }));
            _matchedEvents.Add(MakeEvent(-1, 0.8));
            _unmatchedEvents.Add(MakeEvent(-1, 0.1));

            _testFilterSpecs.Add(MakeSpec(new Object[] { "DoublePrimitive", FilterOperator.EQUAL, 99.99,
                                                         "IntPrimitive", FilterOperator.LESS, 1 }));
            _matchedEvents.Add(MakeEvent(0, 99.99));
            _unmatchedEvents.Add(MakeEvent(2, 0.5));

            _testFilterSpecs.Add(MakeSpec(new Object[] { "DoublePrimitive", FilterOperator.GREATER, .99,
                                                         "IntPrimitive", FilterOperator.EQUAL, 5001 }));
            _matchedEvents.Add(MakeEvent(5001, 1.1));
            _unmatchedEvents.Add(MakeEvent(5002, 0.98));

            _testFilterSpecs.Add(MakeSpec(new Object[] { "IntPrimitive", FilterOperator.LESS, -99000 }));
            _matchedEvents.Add(MakeEvent(-99001, -1));
            _unmatchedEvents.Add(MakeEvent(-98999, -1));

            _testFilterSpecs.Add(MakeSpec(new Object[] { "IntPrimitive", FilterOperator.GREATER_OR_EQUAL, 11,
                                                         "DoublePrimitive", FilterOperator.GREATER, 888.0 }));
            _matchedEvents.Add(MakeEvent(11, 888.001));
            _unmatchedEvents.Add(MakeEvent(10, 888));

            _testFilterSpecs.Add(MakeSpec(new Object[] { "IntPrimitive", FilterOperator.EQUAL, 973,
                                                         "DoublePrimitive", FilterOperator.EQUAL, 709.0 }));
            _matchedEvents.Add(MakeEvent(973, 709));
            _unmatchedEvents.Add(MakeEvent(0, 0.5));

            _testFilterSpecs.Add(MakeSpec(new Object[] { "IntPrimitive", FilterOperator.EQUAL, 973,
                                                         "DoublePrimitive", FilterOperator.EQUAL, 655.0 }));
            _matchedEvents.Add(MakeEvent(973, 655));
            _unmatchedEvents.Add(MakeEvent(33838, 655.5));
        }
예제 #5
0
        // Remove an filterCallback from the current node, return true if the node is the node is empty now
        private static bool RemoveFromNode(
            FilterHandle filterCallback,
            FilterHandleSetNode currentNode,
            EventTypeIndexBuilderIndexLookupablePair[] treePathInfo,
            int treePathPosition)
        {
            var nextPair = treePathPosition < treePathInfo.Length ? treePathInfo[treePathPosition++] : null;

            // No remaining filter parameters
            if (nextPair == null)
            {
                using (currentNode.NodeRWLock.AcquireWriteLock())
                {
                    var isRemoved = currentNode.Remove(filterCallback);
                    var isEmpty   = currentNode.IsEmpty();

                    if (!isRemoved)
                    {
                        Log.Warn(".removeFromNode (" + Thread.CurrentThread.ManagedThreadId + ") Could not find the filterCallback to be removed within the supplied node , node=" +
                                 currentNode + "  filterCallback=" + filterCallback);
                    }

                    return(isEmpty);
                }
            }

            // Remove from index
            var nextIndex        = nextPair.Index;
            var filteredForValue = nextPair.Lookupable;

            using (currentNode.NodeRWLock.AcquireWriteLock())
            {
                var isEmpty = RemoveFromIndex(filterCallback, nextIndex, treePathInfo, treePathPosition, filteredForValue);

                if (!isEmpty)
                {
                    return(false);
                }

                // Remove the index if the index is now empty
                if (nextIndex.Count == 0)
                {
                    var isRemoved = currentNode.Remove(nextIndex);

                    if (!isRemoved)
                    {
                        Log.Warn(".removeFromNode (" + Thread.CurrentThread.ManagedThreadId + ") Could not find the index in index list for removal, index=" +
                                 nextIndex + "  filterCallback=" + filterCallback);
                        return(false);
                    }
                }

                return(currentNode.IsEmpty());
            }
        }
예제 #6
0
 /// <summary>
 /// Add a new event type to the index and use the specified node for the root node of
 /// its subtree. If the event type already existed, the method will throw an
 /// IllegalStateException.
 /// </summary>
 /// <param name="eventType">is the event type to be added to the index</param>
 /// <param name="rootNode">is the root node of the subtree for filter constant indizes and callbacks</param>
 public void Add(EventType eventType, FilterHandleSetNode rootNode)
 {
     using (_eventTypesLock.AcquireWriteLock())
     {
         if (_eventTypes.ContainsKey(eventType))
         {
             throw new IllegalStateException("Event type already in index, add not performed, type=" + eventType);
         }
         _eventTypes.Put(eventType, rootNode);
     }
 }
예제 #7
0
        public void TestMultithreaded()
        {
            var topNode = new FilterHandleSetNode(ReaderWriterLockManager.CreateDefaultLock());

            PerformMultithreadedTest(topNode, 2, 1000, 1);
            PerformMultithreadedTest(topNode, 3, 1000, 1);
            PerformMultithreadedTest(topNode, 4, 1000, 1);

            PerformMultithreadedTest(new FilterHandleSetNode(ReaderWriterLockManager.CreateDefaultLock()), 2, 1000, 1);
            PerformMultithreadedTest(new FilterHandleSetNode(ReaderWriterLockManager.CreateDefaultLock()), 3, 1000, 1);
            PerformMultithreadedTest(new FilterHandleSetNode(ReaderWriterLockManager.CreateDefaultLock()), 4, 1000, 1);
        }
예제 #8
0
        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);
        }
예제 #9
0
        /// <summary>
        /// Remove an filterCallback from the given top node. The IndexTreePath instance passed in must be the same as obtained when the same filterCallback was added.
        /// </summary>
        /// <param name="eventType">Type of the event.</param>
        /// <param name="filterCallback">filter callback  to be removed</param>
        /// <param name="treePathInfo">encapsulates information need to allow for safe removal of the filterCallback</param>
        /// <param name="topNode">The top tree node beneath which the filterCallback was added</param>
        public static void Remove(
            EventType eventType,
            FilterHandle filterCallback,
            EventTypeIndexBuilderIndexLookupablePair[] treePathInfo,
            FilterHandleSetNode topNode)
        {
            if ((ExecutionPathDebugLog.IsEnabled) && (Log.IsDebugEnabled))
            {
                Log.Debug(".remove (" + Thread.CurrentThread.ManagedThreadId + ") Removing filterCallback " +
                          " type " + eventType.Name +
                          "  topNode=" + topNode +
                          "  filterCallback=" + filterCallback);
            }

            RemoveFromNode(filterCallback, topNode, treePathInfo, 0);
        }
예제 #10
0
        /// <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);
            }
        }
예제 #11
0
 public void SetUp()
 {
     _testEvaluator = new SupportEventEvaluator();
     _testNode      = new FilterHandleSetNode(ReaderWriterLockManager.CreateDefaultLock());
 }
예제 #12
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();
        }
예제 #13
0
        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();
        }
예제 #14
0
        /// <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);
            }
        }
예제 #15
0
        /// <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);
            }
        }
예제 #16
0
 public void SetUp()
 {
     _container     = SupportContainer.Reset();
     _testEvaluator = new SupportEventEvaluator();
     _testNode      = new FilterHandleSetNode(_container.RWLockManager().CreateDefaultLock());
 }