Beispiel #1
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;
            }
        }
Beispiel #2
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);
            }
        }