예제 #1
0
        /// <summary>
        ///     Determine among the passed in filter parameters any parameter that matches the given index on property name and
        ///     filter operator type. Returns null if none of the parameters matches the index.
        /// </summary>
        /// <param name="parameters">is the filter parameter list</param>
        /// <param name="index">is a filter parameter constant value index</param>
        /// <returns>filter parameter, or null if no matching parameter found.</returns>
        public static FilterValueSetParam FindParameter(
            ArrayDeque<FilterValueSetParam> parameters,
            FilterParamIndexBase index)
        {
            if (index is FilterParamIndexLookupableBase) {
                var propBasedIndex = (FilterParamIndexLookupableBase) index;
                var indexLookupable = propBasedIndex.Lookupable;
                var indexOperator = propBasedIndex.FilterOperator;

                foreach (var parameter in parameters) {
                    var lookupable = parameter.Lookupable;
                    var paramOperator = parameter.FilterOperator;

                    if (lookupable.Equals(indexLookupable) &&
                        paramOperator.Equals(indexOperator)) {
                        return parameter;
                    }
                }
            }
            else {
                foreach (var parameter in parameters) {
                    var paramOperator = parameter.FilterOperator;

                    if (paramOperator.Equals(index.FilterOperator)) {
                        return parameter;
                    }
                }
            }

            return null;
        }
예제 #2
0
 private void Verify(FilterParamIndexBase index, long?testValue, bool[] expected)
 {
     testBean.LongBoxed = testValue;
     index.MatchEvent(testEventBean, matchesList, null);
     for (int i = 0; i < expected.Length; i++)
     {
         Assert.AreEqual(expected[i], testEvaluators[i].GetAndResetCountInvoked() == 1);
     }
 }
예제 #3
0
 private void VerifyDoubleBoxed(
     FilterParamIndexBase index,
     double testValue,
     int numExpected)
 {
     testBean.DoubleBoxed = testValue;
     index.MatchEvent(testEventBean, matchesList, null);
     Assert.AreEqual(numExpected, testEvaluator.GetAndResetCountInvoked());
 }
예제 #4
0
 private void VerifyLongPrimitive(
     FilterParamIndexBase index,
     long testValue,
     int numExpected)
 {
     testBean.LongPrimitive = testValue;
     index.MatchEvent(testEventBean, matchesList, null);
     Assert.AreEqual(numExpected, testEvaluator.GetAndResetCountInvoked());
 }
예제 #5
0
        public void TestCreateIndex()
        {
            // Create a "greater" index
            FilterParamIndexBase index = IndexFactory.CreateIndex(MakeLookupable("IntPrimitive"), lockFactory, FilterOperator.GREATER);

            Assert.IsTrue(index != null);
            Assert.IsTrue(index is FilterParamIndexCompare);
            Assert.IsTrue(GetPropName(index).Equals("IntPrimitive"));
            Assert.IsTrue(index.FilterOperator == FilterOperator.GREATER);

            // Create an "Equals" index
            index = IndexFactory.CreateIndex(MakeLookupable("string"), lockFactory, FilterOperator.EQUAL);

            Assert.IsTrue(index != null);
            Assert.IsTrue(index is FilterParamIndexEquals);
            Assert.IsTrue(GetPropName(index).Equals("string"));
            Assert.IsTrue(index.FilterOperator == FilterOperator.EQUAL);

            // Create an "not equals" index
            index = IndexFactory.CreateIndex(MakeLookupable("string"), lockFactory, FilterOperator.NOT_EQUAL);

            Assert.IsTrue(index != null);
            Assert.IsTrue(index is FilterParamIndexNotEquals);
            Assert.IsTrue(GetPropName(index).Equals("string"));
            Assert.IsTrue(index.FilterOperator == FilterOperator.NOT_EQUAL);

            // Create a range index
            index = IndexFactory.CreateIndex(MakeLookupable("DoubleBoxed"), lockFactory, FilterOperator.RANGE_CLOSED);
            Assert.IsTrue(index is FilterParamIndexDoubleRange);
            index = IndexFactory.CreateIndex(MakeLookupable("DoubleBoxed"), lockFactory, FilterOperator.NOT_RANGE_CLOSED);
            Assert.IsTrue(index is FilterParamIndexDoubleRangeInverted);

            // Create a in-index
            index = IndexFactory.CreateIndex(MakeLookupable("DoubleBoxed"), lockFactory, FilterOperator.IN_LIST_OF_VALUES);
            Assert.IsTrue(index is FilterParamIndexIn);
            index = IndexFactory.CreateIndex(MakeLookupable("DoubleBoxed"), lockFactory, FilterOperator.NOT_IN_LIST_OF_VALUES);
            Assert.IsTrue(index is FilterParamIndexNotIn);

            // Create a boolean-expression-index
            index = IndexFactory.CreateIndex(MakeLookupable("boolean"), lockFactory, FilterOperator.BOOLEAN_EXPRESSION);
            Assert.IsTrue(index is FilterParamIndexBooleanExpr);
            index = IndexFactory.CreateIndex(MakeLookupable("boolean"), lockFactory, FilterOperator.BOOLEAN_EXPRESSION);
            Assert.IsTrue(index is FilterParamIndexBooleanExpr);
        }
예제 #6
0
 /// <summary>
 /// Remove an index, returning true if it was found and removed or false if not in collection.
 /// NOTE: the client to this method must use the read-write lock of this object to lock, if
 /// required by the client code.
 /// </summary>
 /// <param name="index">is the index to remove</param>
 /// <returns>true if found, false if not existing</returns>
 public bool Remove(FilterParamIndexBase index)
 {
     CheckIndizesIsModifiable();
     return(_indizes.Remove(index));
 }
예제 #7
0
 /// <summary>
 /// Add an index. The same index can be added twice - there is no checking done.
 /// NOTE: the client to this method must use the read-write lock of this object
 /// to lock, if required by the client code.
 /// </summary>
 /// <param name="index">index to add</param>
 public void Add(FilterParamIndexBase index)
 {
     CheckIndizesIsModifiable();
     _indizes.Add(index);
 }
예제 #8
0
        private string GetPropName(FilterParamIndexBase index)
        {
            FilterParamIndexLookupableBase propIndex = (FilterParamIndexLookupableBase)index;

            return(propIndex.Lookupable.Expression);
        }
예제 #9
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;
            }
        }
예제 #10
0
        private static bool RemoveFromIndex(
            FilterHandle filterCallback,
            FilterParamIndexBase index,
            FilterValueSetParam[] @params,
            int currentLevel,
            object filterForValue)
        {
            using (index.ReadWriteLock.WriteLock.Acquire())
            {
                EventEvaluator eventEvaluator = index.Get(filterForValue);

                if (eventEvaluator == null)
                {
                    // This is possible as there can be another path
                    return false;
                }

                if (eventEvaluator is FilterHandleSetNode)
                {
                    var node = (FilterHandleSetNode) eventEvaluator;
                    var found = RemoveFromNode(filterCallback, node, @params, currentLevel);
                    if (!found)
                    {
                        return false;
                    }

                    var isEmpty = node.IsEmpty();
                    if (isEmpty)
                    {
                        // Since we are holding a write lock to this index, there should not be a chance that
                        // another thread had been adding anything to this FilterHandleSetNode
                        index.Remove(filterForValue);
                    }

                    return true;
                }

                var nextIndex = (FilterParamIndexBase) eventEvaluator;
                FilterParamIndexBase indexFound = null;
                if (nextIndex is FilterParamIndexLookupableBase)
                {
                    var baseIndex = (FilterParamIndexLookupableBase) nextIndex;
                    for (var i = 0; i < @params.Length; i++)
                    {
                        var param = @params[i];
                        if (param.Lookupable.Expression.Equals(baseIndex.Lookupable.Expression) &&
                            param.FilterOperator.Equals(baseIndex.FilterOperator))
                        {
                            var found = RemoveFromIndex(filterCallback, baseIndex, @params, currentLevel + 1, param.FilterForValue);
                            if (found)
                            {
                                indexFound = baseIndex;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    var booleanIndex = (FilterParamIndexBooleanExpr) nextIndex;
                    for (var i = 0; i < @params.Length; i++)
                    {
                        var param = @params[i];
                        // if boolean-expression then match only if this is the last parameter,
                        // all others considered are higher order and sort ahead
                        if (param.FilterOperator.Equals(FilterOperator.BOOLEAN_EXPRESSION))
                        {
                            bool found = booleanIndex.RemoveMayNotExist(param.FilterForValue);
                            if (found)
                            {
                                indexFound = booleanIndex;
                                break;
                            }
                        }
                    }
                }

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

                var indexIsEmpty = nextIndex.IsEmpty;
                if (indexIsEmpty)
                {
                    // Since we are holding a write lock to this index, there should not be a chance that
                    // another thread had been adding anything to this FilterHandleSetNode
                    index.Remove(filterForValue);
                }

                return true;
            }
        }
예제 #11
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);
            }
        }