Ejemplo n.º 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="valueSet">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">lock factory</param>
        public static void Add(
            FilterValueSetParam[][] valueSet,
            FilterHandle filterCallback,
            FilterHandleSetNode topNode,
            FilterServiceGranularLockFactory lockFactory)
        {
            if (ExecutionPathDebugLog.IsDebugEnabled && log.IsDebugEnabled) {
                log.Debug(
                    ".add (" + Thread.CurrentThread.ManagedThreadId + ") Adding filter callback, " +
                    "  topNode=" + topNode +
                    "  filterCallback=" + filterCallback);
            }

            if (valueSet.Length == 0) {
                AddToNode(new ArrayDeque<FilterValueSetParam>(1), filterCallback, topNode, lockFactory);
            }
            else {
                var remainingParameters = new ArrayDeque<FilterValueSetParam>();
                for (var i = 0; i < valueSet.Length; i++) {
                    remainingParameters.Clear();
                    remainingParameters.AddAll(valueSet[i]);
                    AddToNode(remainingParameters, filterCallback, topNode, lockFactory);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>Add to the current node building up the tree path information.</summary>
        /// <param name="remainingParameters">any remaining parameters</param>
        /// <param name="filterCallback">the filter callback</param>
        /// <param name="currentNode">is the node to add to</param>
        /// <param name="lockFactory">the lock factory</param>
        private static void AddToNode(
            ArrayDeque<FilterValueSetParam> remainingParameters,
            FilterHandle filterCallback,
            FilterHandleSetNode currentNode,
            FilterServiceGranularLockFactory lockFactory)
        {
            // If no parameters are specified, add to current node, and done
            if (remainingParameters.IsEmpty()) {
                using (currentNode.NodeRWLock.WriteLock.Acquire())
                {
                    currentNode.Add(filterCallback);
                }

                return;
            }

            // Need to find an existing index that matches one of the filter parameters
            Pair<FilterValueSetParam, FilterParamIndexBase> pair;
            using (currentNode.NodeRWLock.ReadLock.Acquire())
            {
                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;
                    AddToIndex(remainingParameters, filterCallback, index, filterForValue, lockFactory);
                    return;
                }
            }

            // An index for any of the filter parameters was not found, create one
            using (currentNode.NodeRWLock.WriteLock.Acquire())
            {
                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 indexInner = pair.Second;
                    AddToIndex(remainingParameters, filterCallback, indexInner, filterForValue, lockFactory);
                    return;
                }

                // No index found that matches any parameters, create a new one
                // Pick the next parameter for an index
                var parameterPickedForIndex = remainingParameters.RemoveFirst();
                var index = IndexFactory.CreateIndex(parameterPickedForIndex.Lookupable, lockFactory, parameterPickedForIndex.FilterOperator);

                currentNode.Add(index);
                AddToIndex(remainingParameters, filterCallback, index, parameterPickedForIndex.FilterForValue, lockFactory);
            }
        }
        public void TestMultithreaded()
        {
            var topNode = new FilterHandleSetNode(new SlimReaderWriterLock());

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

            PerformMultithreadedTest(new FilterHandleSetNode(new SlimReaderWriterLock()), 2, 1000, 1);
            PerformMultithreadedTest(new FilterHandleSetNode(new SlimReaderWriterLock()), 3, 1000, 1);
            PerformMultithreadedTest(new FilterHandleSetNode(new SlimReaderWriterLock()), 4, 1000, 1);
        }
Ejemplo n.º 4
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 (eventTypesRWLock.WriteLock.Acquire()) {
                if (eventTypes.ContainsKey(eventType)) {
                    throw new IllegalStateException("Event type already in index, add not performed, type=" + eventType);
                }

                eventTypes.Put(eventType, rootNode);
            }
        }
 public SupportIndexTreeBuilderRunnable(
     EventType eventType,
     FilterHandleSetNode topNode,
     IList <FilterSpecActivatable> testFilterSpecs,
     IList <EventBean> matchedEvents,
     IList <EventBean> unmatchedEvents,
     IReaderWriterLockManager rwLockManager)
 {
     this.eventType       = eventType;
     this.topNode         = topNode;
     this.testFilterSpecs = testFilterSpecs;
     this.matchedEvents   = matchedEvents;
     this.unmatchedEvents = unmatchedEvents;
     this.lockFactory     = new FilterServiceGranularLockFactoryReentrant(rwLockManager);
 }
Ejemplo n.º 6
0
        public void SetUp()
        {
            SupportBean testBean = new SupportBean();

            testEventBean = SupportEventBeanFactory
                            .GetInstance(container)
                            .CreateObject(testBean);
            testEventType = testEventBean.EventType;

            handleSetNode  = new FilterHandleSetNode(new SlimReaderWriterLock());
            filterCallback = new SupportFilterHandle();
            handleSetNode.Add(filterCallback);

            testIndex = new EventTypeIndex(new FilterServiceGranularLockFactoryReentrant(
                                               container.RWLockManager()));
            testIndex.Add(testEventType, handleSetNode);
        }
        private void PerformMultithreadedTest(
            FilterHandleSetNode topNode,
            int numberOfThreads,
            int numberOfRunnables,
            int numberOfSecondsSleep)
        {
            log.Info(".PerformMultithreadedTest Loading thread pool work queue,numberOfRunnables={0}", numberOfRunnables);

            var pool = Executors.NewMultiThreadedExecutor(numberOfThreads);

            //var pool = new ThreadPoolExecutor(0, numberOfThreads, 99999,
            //    TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

            for (var i = 0; i < numberOfRunnables; i++)
            {
                var runnable = new SupportIndexTreeBuilderRunnable(
                    eventType,
                    topNode,
                    testFilterSpecs,
                    matchedEvents,
                    unmatchedEvents,
                    container.RWLockManager());

                pool.Submit(() => runnable.Run());
            }

            log.Info(".PerformMultithreadedTest Starting thread pool, threads={0}", numberOfThreads);
            //pool.CorePoolSize = numberOfThreads;

            // Sleep X seconds
            Sleep(numberOfSecondsSleep);

            log.Info(".PerformMultithreadedTest Completed, numberOfRunnables={0}  numberOfThreads={1}  completed={2}",
                     numberOfRunnables,
                     numberOfThreads,
                     pool.NumExecuted);

            pool.Shutdown();
            pool.AwaitTermination(1, TimeUnit.SECONDS);

            Assert.IsTrue(pool.NumExecuted == numberOfRunnables);
        }
Ejemplo n.º 8
0
        private void MatchType(
            EventType eventType,
            EventBean eventBean,
            ICollection<FilterHandle> matches,
            ExprEvaluatorContext ctx)
        {
            FilterHandleSetNode rootNode = null;

            using (eventTypesRWLock.ReadLock.Acquire()) {
                rootNode = eventTypes.Get(eventType);
            }

            // If the top class node is null, no filters have yet been registered for this event type.
            // In this case, log a message and done.
            if (rootNode == null) {
                return;
            }

            rootNode.MatchEvent(eventBean, matches, ctx);
        }
Ejemplo n.º 9
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="valueSet">is the filter information</param>
        /// <param name="filterCallback">is the callback</param>
        /// <param name="lockFactory">lock factory</param>
        /// <param name="eventType">event type</param>
        public void Add(
            EventType eventType,
            FilterValueSetParam[][] valueSet,
            FilterHandle filterCallback,
            FilterServiceGranularLockFactory lockFactory)
        {
            // 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);
                    }
                }
            }

            // Now add to tree
            IndexTreeBuilderAdd.Add(valueSet, filterCallback, rootNode, lockFactory);
        }
Ejemplo n.º 10
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="filterCallback">filter callback  to be removed</param>
        /// <param name="topNode">The top tree node beneath which the filterCallback was added</param>
        /// <param name="eventType">event type</param>
        /// <param name="params">params</param>
        public static void Remove(
            EventType eventType,
            FilterHandle filterCallback,
            FilterValueSetParam[] @params,
            FilterHandleSetNode topNode)
        {
            if (ExecutionPathDebugLog.IsDebugEnabled && Log.IsDebugEnabled) {
                Log.Debug(
                    ".remove (" + Thread.CurrentThread.ManagedThreadId + ") Removing filterCallback " +
                    " type " + eventType.Name +
                    " topNode=" + topNode +
                    " filterCallback=" + filterCallback);
            }

            var isRemoved = RemoveFromNode(filterCallback, topNode, @params, 0);

            if (!isRemoved) {
                Log.Warn(
                    ".removeFromNode (" + Thread.CurrentThread.ManagedThreadId +
                    ") Could not find the filterCallback to be removed within the supplied node, params=" +
                    @params.RenderAny() + "  filterCallback=" + filterCallback);
            }
        }
        public void SetUp()
        {
            lockFactory = new FilterServiceGranularLockFactoryReentrant(
                container.RWLockManager());

            eventType = SupportEventTypeFactory
                        .GetInstance(container)
                        .CreateBeanType(typeof(SupportBean));
            topNode         = new FilterHandleSetNode(new SlimReaderWriterLock());
            filterCallbacks = new List <FilterHandle>();

            testFilterSpecs = new List <FilterSpecActivatable>();
            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));
        }
Ejemplo n.º 12
0
 public void SetUp()
 {
     testEvaluator = new SupportEventEvaluator();
     testNode      = new FilterHandleSetNode(new SlimReaderWriterLock());
 }
Ejemplo n.º 13
0
        private static bool RemoveFromNode(
            FilterHandle filterCallback,
            FilterHandleSetNode currentNode,
            FilterValueSetParam[] @params,
            int currentLevel)
        {
            // No remaining filter parameters
            if (currentLevel == @params.Length) {
                using (currentNode.NodeRWLock.WriteLock.Acquire())
                {
                    return currentNode.Remove(filterCallback);
                }
            }

            if (currentLevel > @params.Length) {
                Log.Warn(
                    ".removeFromNode (" + Thread.CurrentThread.ManagedThreadId + ") Current level exceed parameter length, node=" + currentNode +
                    "  filterCallback=" + filterCallback);
                return false;
            }

            // Remove from index
            using (currentNode.NodeRWLock.WriteLock.Acquire())
            {
                FilterParamIndexBase indexFound = null;

                // find matching index
                foreach (var index in currentNode.Indizes)
                {
                    for (var i = 0; i < @params.Length; i++) {
                        var param = @params[i];
                        var indexMatch = false;
                        if (index is FilterParamIndexLookupableBase) {
                            var baseIndex = (FilterParamIndexLookupableBase) index;
                            if (param.Lookupable.Expression.Equals(baseIndex.Lookupable.Expression) &&
                                param.FilterOperator.Equals(baseIndex.FilterOperator)) {
                                indexMatch = true;
                            }
                        }
                        else if (index is FilterParamIndexBooleanExpr && param.FilterOperator == FilterOperator.BOOLEAN_EXPRESSION) {
                            indexMatch = true;
                        }


                        if (indexMatch) {
                            bool found = RemoveFromIndex(filterCallback, index, @params, currentLevel + 1, param.FilterForValue);
                            if (found) {
                                indexFound = index;
                                break;
                            }
                        }
                    }

                    if (indexFound != null)
                    {
                        break;
                    }
                }

                if (indexFound == null)
                {
                    return false;
                }

                // Remove the index if the index is now empty
                if (indexFound.IsEmpty)
                {
                    var isRemoved = currentNode.Remove(indexFound);

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

                return true;
            }
        }
Ejemplo n.º 14
0
        public void TestBuildWithMatch()
        {
            var topNode = new FilterHandleSetNode(new SlimReaderWriterLock());

            // Add some parameter-less expression
            var filterSpec = MakeFilterValues();

            IndexTreeBuilderAdd.Add(filterSpec, testFilterCallback[0], topNode, lockFactory);
            Assert.IsTrue(topNode.Contains(testFilterCallback[0]));

            // Attempt a match
            topNode.MatchEvent(eventBean, matches, null);
            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);
            IndexTreeBuilderAdd.Add(filterSpec, testFilterCallback[1], topNode, lockFactory);
            Assert.IsTrue(topNode.Indizes.Count == 1);
            Assert.IsTrue(topNode.Indizes[0].CountExpensive == 1);

            // Match again
            topNode.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 1);
            matches.Clear();

            // Add a filter that will match
            filterSpec = MakeFilterValues("IntPrimitive", FilterOperator.EQUAL, 50);
            IndexTreeBuilderAdd.Add(filterSpec, testFilterCallback[2], topNode, lockFactory);
            Assert.IsTrue(topNode.Indizes.Count == 1);
            Assert.IsTrue(topNode.Indizes[0].CountExpensive == 2);

            // match
            topNode.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 2);
            matches.Clear();

            // Add some filter against a double
            filterSpec = MakeFilterValues("DoublePrimitive", FilterOperator.LESS, 1.1);
            IndexTreeBuilderAdd.Add(filterSpec, testFilterCallback[3], topNode, lockFactory);
            Assert.IsTrue(topNode.Indizes.Count == 2);
            Assert.IsTrue(topNode.Indizes[0].CountExpensive == 2);
            Assert.IsTrue(topNode.Indizes[1].CountExpensive == 1);

            topNode.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 3);
            matches.Clear();

            filterSpec = MakeFilterValues("DoublePrimitive", FilterOperator.LESS_OR_EQUAL, 0.5);
            IndexTreeBuilderAdd.Add(filterSpec, testFilterCallback[4], topNode, lockFactory);
            Assert.IsTrue(topNode.Indizes.Count == 3);
            Assert.IsTrue(topNode.Indizes[0].CountExpensive == 2);
            Assert.IsTrue(topNode.Indizes[1].CountExpensive == 1);
            Assert.IsTrue(topNode.Indizes[2].CountExpensive == 1);

            topNode.MatchEvent(eventBean, matches, null);
            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");
            IndexTreeBuilderAdd.Add(filterSpec, testFilterCallback[5], topNode, lockFactory);
            Assert.IsTrue(topNode.Indizes.Count == 3);
            Assert.IsTrue(topNode.Indizes[0].CountExpensive == 2);
            Assert.IsTrue(topNode.Indizes[1].CountExpensive == 1);
            Assert.IsTrue(topNode.Indizes[2].CountExpensive == 1);
            var nextLevelSetNode = (FilterHandleSetNode)topNode.Indizes[1].Get(1.1d);

            Assert.IsTrue(nextLevelSetNode != null);
            Assert.IsTrue(nextLevelSetNode.Indizes.Count == 1);

            topNode.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 5);
            matches.Clear();

            filterSpec = MakeFilterValues("DoublePrimitive", FilterOperator.LESS, 1.1,
                                          "TheString", FilterOperator.EQUAL, "beta");
            IndexTreeBuilderAdd.Add(filterSpec, testFilterCallback[6], topNode, lockFactory);

            topNode.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 5);
            matches.Clear();

            filterSpec = MakeFilterValues("DoublePrimitive", FilterOperator.LESS, 1.1,
                                          "TheString", FilterOperator.EQUAL, "jack");
            IndexTreeBuilderAdd.Add(filterSpec, testFilterCallback[7], topNode, lockFactory);
            Assert.IsTrue(nextLevelSetNode.Indizes.Count == 1);
            var nodeTwo = (FilterHandleSetNode)nextLevelSetNode.Indizes[0].Get("jack");

            Assert.IsTrue(nodeTwo.FilterCallbackCount == 2);

            topNode.MatchEvent(eventBean, matches, null);
            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);
            IndexTreeBuilderAdd.Add(filterSpec, testFilterCallback[8], topNode, lockFactory);

            topNode.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 7);
            matches.Clear();

            // Add an filterSpec in the middle
            filterSpec = MakeFilterValues("LongPrimitive", FilterOperator.EQUAL, 10L,
                                          "TheString", FilterOperator.EQUAL, "jack");
            IndexTreeBuilderAdd.Add(filterSpec, testFilterCallback[9], topNode, lockFactory);

            filterSpec = MakeFilterValues("LongPrimitive", FilterOperator.EQUAL, 10L,
                                          "TheString", FilterOperator.EQUAL, "jim");
            IndexTreeBuilderAdd.Add(filterSpec, testFilterCallback[10], topNode, lockFactory);

            filterSpec = MakeFilterValues("LongPrimitive", FilterOperator.EQUAL, 10L,
                                          "TheString", FilterOperator.EQUAL, "joe");
            IndexTreeBuilderAdd.Add(filterSpec, testFilterCallback[11], topNode, lockFactory);

            topNode.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 8);
            matches.Clear();
        }
Ejemplo n.º 15
0
        public void TestBuildMatchRemove()
        {
            var top = new FilterHandleSetNode(new SlimReaderWriterLock());

            // Add a parameter-less filter
            var filterSpecNoParams = MakeFilterValues();

            IndexTreeBuilderAdd.Add(filterSpecNoParams, testFilterCallback[0], top, lockFactory);

            // Try a match
            top.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 1);
            matches.Clear();

            // Remove filter
            IndexTreeBuilderRemove.Remove(eventType, testFilterCallback[0], filterSpecNoParams[0], top);

            // Match should not be found
            top.MatchEvent(eventBean, matches, null);
            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);

            IndexTreeBuilderAdd.Add(filterSpecOne, testFilterCallback[1], top, lockFactory);

            var filterSpecTwo = MakeFilterValues(
                "TheString", FilterOperator.EQUAL, "jack",
                "LongPrimitive", FilterOperator.EQUAL, 10L,
                "ShortPrimitive", FilterOperator.EQUAL, (short)20);

            IndexTreeBuilderAdd.Add(filterSpecTwo, testFilterCallback[2], top, lockFactory);

            var filterSpecThree = MakeFilterValues(
                "TheString", FilterOperator.EQUAL, "jack",
                "LongPrimitive", FilterOperator.EQUAL, 10L);

            IndexTreeBuilderAdd.Add(filterSpecThree, testFilterCallback[3], top, lockFactory);

            var filterSpecFour = MakeFilterValues(
                "TheString", FilterOperator.EQUAL, "jack");

            IndexTreeBuilderAdd.Add(filterSpecFour, testFilterCallback[4], top, lockFactory);

            var filterSpecFive = MakeFilterValues(
                "LongPrimitive", FilterOperator.EQUAL, 10L);

            IndexTreeBuilderAdd.Add(filterSpecFive, testFilterCallback[5], top, lockFactory);

            top.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 5);
            matches.Clear();

            // Remove some of the nodes
            IndexTreeBuilderRemove.Remove(eventType, testFilterCallback[2], filterSpecTwo[0], top);

            top.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 4);
            matches.Clear();

            // Remove some of the nodes
            IndexTreeBuilderRemove.Remove(eventType, testFilterCallback[4], filterSpecFour[0], top);

            top.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 3);
            matches.Clear();

            // Remove some of the nodes
            IndexTreeBuilderRemove.Remove(eventType, testFilterCallback[5], filterSpecFive[0], top);

            top.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 2);
            matches.Clear();

            // Remove some of the nodes
            IndexTreeBuilderRemove.Remove(eventType, testFilterCallback[1], filterSpecOne[0], top);

            top.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 1);
            matches.Clear();

            // Remove some of the nodes
            IndexTreeBuilderRemove.Remove(eventType, testFilterCallback[3], filterSpecThree[0], top);

            top.MatchEvent(eventBean, matches, null);
            Assert.IsTrue(matches.Count == 0);
            matches.Clear();
        }
Ejemplo n.º 16
0
        /// <summary>
        ///     Add to an index the value to filter for.
        /// </summary>
        /// <param name="index">is the index to add to</param>
        /// <param name="filterForValue">is the filter parameter value to add</param>
        /// <param name="remainingParameters">any remaining parameters</param>
        /// <param name="filterCallback">the filter callback</param>
        /// <param name="lockFactory">the lock factory</param>
        private static void AddToIndex(
            ArrayDeque<FilterValueSetParam> remainingParameters,
            FilterHandle filterCallback,
            FilterParamIndexBase index,
            object filterForValue,
            FilterServiceGranularLockFactory lockFactory)
        {
            EventEvaluator eventEvaluator;

            using (index.ReadWriteLock.ReadLock.Acquire())
            { 
                eventEvaluator = index.Get(filterForValue);

                // The filter parameter value already existed in bean, add and release locks
                if (eventEvaluator != null) {
                    var added = AddToEvaluator(remainingParameters, filterCallback, eventEvaluator, lockFactory);
                    if (added) {
                        return;
                    }
                }
            }

            // new filter parameter value, need a write lock
            using (index.ReadWriteLock.WriteLock.Acquire())
            {
                eventEvaluator = index.Get(filterForValue);

                // It may exist now since another thread could have added the entry
                if (eventEvaluator != null)
                {
                    var added = AddToEvaluator(remainingParameters, filterCallback, eventEvaluator, lockFactory);
                    if (added)
                    {
                        return;
                    }

                    // The found eventEvaluator must be converted to a new FilterHandleSetNode
                    var nextIndexInner = (FilterParamIndexBase) eventEvaluator;
                    var newNode = new FilterHandleSetNode(lockFactory.ObtainNew());
                    newNode.Add(nextIndexInner);
                    index.Remove(filterForValue);
                    index.Put(filterForValue, newNode);
                    AddToNode(remainingParameters, filterCallback, newNode, 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, lockFactory);
                    index.Put(filterForValue, node);
                    return;
                }

                // If there are remaining parameters, create a new index for the next parameter
                var parameterPickedForIndex = remainingParameters.RemoveFirst();

                var nextIndex = IndexFactory.CreateIndex(parameterPickedForIndex.Lookupable, lockFactory, parameterPickedForIndex.FilterOperator);

                index.Put(filterForValue, nextIndex);
                AddToIndex(remainingParameters, filterCallback, nextIndex, parameterPickedForIndex.FilterForValue, lockFactory);
            }
        }