Exemple #1
0
        public void TestArrayLast()
        {
            var deque = new ArrayDeque <int>();

            Assert.That(deque.Count, Is.EqualTo(0));

            deque.Add(1);
            Assert.That(deque.Count, Is.EqualTo(1));
            Assert.That(deque.Last, Is.EqualTo(1));

            deque.Add(2);
            Assert.That(deque.Count, Is.EqualTo(2));
            Assert.That(deque.Last, Is.EqualTo(2));

            deque.Add(3);
            Assert.That(deque.Count, Is.EqualTo(3));
            Assert.That(deque.Last, Is.EqualTo(3));

            deque.Add(4);
            Assert.That(deque.Count, Is.EqualTo(4));
            Assert.That(deque.Last, Is.EqualTo(4));

            Assert.That(deque.RemoveFirst(), Is.EqualTo(1));
            Assert.That(deque.Count, Is.EqualTo(3));
            Assert.That(deque.Last, Is.EqualTo(4));

            Assert.That(deque.RemoveLast(), Is.EqualTo(4));
            Assert.That(deque.Count, Is.EqualTo(2));
            Assert.That(deque.Last, Is.EqualTo(3));
        }
        /// <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);
            }
        }
Exemple #3
0
 private void NextToken()
 {
     tokens.RemoveFirst(); // Pop();
     if (tokens.IsEmpty()) {
         lookahead = new Token(TokenType.END, "");
     }
     else {
         lookahead = tokens.First;
     }
 }
Exemple #4
0
        public override void Update(EventBean[] newData, EventBean[] oldData)
        {
            if (InstrumentationHelper.ENABLED)
            {
                InstrumentationHelper.Get().QViewProcessIRStream(this, _lengthWindowViewFactory.ViewName, newData, oldData);
            }

            // add data points to the window
            // we don't care about removed data from a prior view
            if (newData != null)
            {
                for (int ii = 0; ii < newData.Length; ii++)
                {
                    _events.Add(newData[ii]);
                }
            }

            // Check for any events that get pushed out of the window
            int expiredCount = _events.Count - _size;

            EventBean[] expiredArr = null;
            if (expiredCount > 0)
            {
                expiredArr = new EventBean[expiredCount];
                for (int i = 0; i < expiredCount; i++)
                {
                    expiredArr[i] = _events.RemoveFirst();
                }
            }

            // Update event buffer for access by expressions, if any
            if (_viewUpdatedCollection != null)
            {
                _viewUpdatedCollection.Update(newData, expiredArr);
            }

            // If there are child views, call Update method
            if (HasViews)
            {
                if (InstrumentationHelper.ENABLED)
                {
                    InstrumentationHelper.Get().QViewIndicate(this, _lengthWindowViewFactory.ViewName, newData, expiredArr);
                }
                UpdateChildren(newData, expiredArr);
                if (InstrumentationHelper.ENABLED)
                {
                    InstrumentationHelper.Get().AViewIndicate();
                }
            }

            if (InstrumentationHelper.ENABLED)
            {
                InstrumentationHelper.Get().AViewProcessIRStream();
            }
        }
Exemple #5
0
        /// <summary>
        /// Return and remove events in time-slots earlier (less) then the timestamp passed in, returning the list of events expired.
        /// </summary>
        /// <param name="expireBefore">is the timestamp from which on to keep events in the window</param>
        /// <returns>
        /// a list of events expired and removed from the window, or null if none expired
        /// </returns>
        public ArrayDeque <EventBean> ExpireEvents(long expireBefore)
        {
            if (_window.IsEmpty())
            {
                return(null);
            }

            var pair = _window.First;

            // If the first entry's timestamp is after the expiry date, nothing to expire
            if (pair.Timestamp >= expireBefore)
            {
                return(null);
            }

            var resultBeans = new ArrayDeque <EventBean>();

            // Repeat until the window is empty or the timestamp is above the expiry time
            do
            {
                if (pair.EventHolder != null)
                {
                    if (pair.EventHolder is EventBean)
                    {
                        resultBeans.Add((EventBean)pair.EventHolder);
                    }
                    else
                    {
                        resultBeans.AddAll((IList <EventBean>)pair.EventHolder);
                    }
                }

                _window.RemoveFirst();

                if (_window.IsEmpty())
                {
                    break;
                }

                pair = _window.First;
            } while (pair.Timestamp < expireBefore);

            if (_reverseIndex != null)
            {
                foreach (var expired in resultBeans)
                {
                    _reverseIndex.Remove(expired);
                }
            }

            _size -= resultBeans.Count;
            return(resultBeans);
        }
 public override void GetTraverseStatement(
     EventTypeIndexTraverse traverse,
     ICollection<int> statementIds,
     ArrayDeque<FilterItem> evaluatorStack)
 {
     evaluatorStack.AddFirst(new FilterItem(_advancedIndex.Expression, FilterOperator.ADVANCED_INDEX, this));
     PointRegionQuadTreeFilterIndexTraverse.Traverse(_quadTree, @object => {
         if (@object is FilterHandleSetNode filterHandleSetNode) {
             filterHandleSetNode.GetTraverseStatement(traverse, statementIds, evaluatorStack);
             return;
         }
         if (@object is FilterHandle filterHandle) {
             traverse.Invoke(evaluatorStack, filterHandle);
         }
     });
     evaluatorStack.RemoveFirst();
 }
Exemple #7
0
        public override void Update(
            EventBean[] newData,
            EventBean[] oldData)
        {
            agentInstanceContext.AuditProvider.View(newData, oldData, agentInstanceContext, viewFactory);
            agentInstanceContext.InstrumentationProvider.QViewProcessIRStream(viewFactory, newData, oldData);

            // add data points to the window
            // we don't care about removed data from a prior view
            if (newData != null) {
                foreach (var @event in newData) {
                    events.Add(@event);
                }
            }

            // Check for any events that get pushed out of the window
            var expiredCount = events.Count - Size;
            EventBean[] expiredArr = null;
            if (expiredCount > 0) {
                expiredArr = new EventBean[expiredCount];
                for (var i = 0; i < expiredCount; i++) {
                    expiredArr[i] = events.RemoveFirst();
                }
            }

            // update event buffer for access by expressions, if any
            ViewUpdatedCollection?.Update(newData, expiredArr);

            // If there are child views, call update method
            if (Child != null) {
                agentInstanceContext.InstrumentationProvider.QViewIndicate(viewFactory, newData, expiredArr);
                Child.Update(newData, expiredArr);
                agentInstanceContext.InstrumentationProvider.AViewIndicate();
            }

            agentInstanceContext.InstrumentationProvider.AViewProcessIRStream();
        }
Exemple #8
0
        public static ExprDotNodeRealizedChain GetChainEvaluators(
            int?streamOfProviderIfApplicable,
            EPType inputType,
            IList <ExprChainedSpec> chainSpec,
            ExprValidationContext validationContext,
            bool isDuckTyping,
            ExprDotNodeFilterAnalyzerInput inputDesc)
        {
            var            methodEvals      = new List <ExprDotEval>();
            var            currentInputType = inputType;
            EnumMethodEnum?lastLambdaFunc   = null;
            var            lastElement      = chainSpec.IsEmpty() ? null : chainSpec[chainSpec.Count - 1];
            ExprDotNodeFilterAnalyzerDesc filterAnalyzerDesc = null;

            var chainSpecStack = new ArrayDeque <ExprChainedSpec>(chainSpec);

            while (!chainSpecStack.IsEmpty())
            {
                var chainElement = chainSpecStack.RemoveFirst();
                lastLambdaFunc = null;  // reset

                // compile parameters for chain element
                var paramEvals = new ExprEvaluator[chainElement.Parameters.Count];
                var paramTypes = new Type[chainElement.Parameters.Count];
                for (var i = 0; i < chainElement.Parameters.Count; i++)
                {
                    paramEvals[i] = chainElement.Parameters[i].ExprEvaluator;
                    paramTypes[i] = paramEvals[i].ReturnType;
                }

                // check if special 'size' method
                if (currentInputType is ClassMultiValuedEPType)
                {
                    var type = (ClassMultiValuedEPType)currentInputType;
                    if ((chainElement.Name.ToLower() == "size") && paramTypes.Length == 0 && Equals(lastElement, chainElement))
                    {
                        var sizeExpr = new ExprDotEvalArraySize();
                        methodEvals.Add(sizeExpr);
                        currentInputType = sizeExpr.TypeInfo;
                        continue;
                    }
                    if ((chainElement.Name.ToLower() == "get") && paramTypes.Length == 1 && paramTypes[0].GetBoxedType() == typeof(int?))
                    {
                        var componentType = type.Component;
                        var get           = new ExprDotEvalArrayGet(paramEvals[0], componentType);
                        methodEvals.Add(get);
                        currentInputType = get.TypeInfo;
                        continue;
                    }
                }

                // determine if there is a matching method
                var matchingMethod = false;
                var methodTarget   = GetMethodTarget(currentInputType);
                if (methodTarget != null)
                {
                    try
                    {
                        GetValidateMethodDescriptor(methodTarget, chainElement.Name, chainElement.Parameters, validationContext);
                        matchingMethod = true;
                    }
                    catch (ExprValidationException)
                    {
                        // expected
                    }
                }

                // resolve lambda
                if (chainElement.Name.IsEnumerationMethod() && (!matchingMethod || methodTarget.IsArray || methodTarget.IsImplementsInterface(typeof(ICollection <object>))))
                {
                    var enumerationMethod = EnumMethodEnumExtensions.FromName(chainElement.Name);
                    var eval = TypeHelper.Instantiate <ExprDotEvalEnumMethod>(enumerationMethod.GetImplementation());
                    eval.Init(streamOfProviderIfApplicable, enumerationMethod, chainElement.Name, currentInputType, chainElement.Parameters, validationContext);
                    currentInputType = eval.TypeInfo;
                    if (currentInputType == null)
                    {
                        throw new IllegalStateException("Enumeration method '" + chainElement.Name + "' has not returned type information");
                    }
                    methodEvals.Add(eval);
                    lastLambdaFunc = enumerationMethod;
                    continue;
                }

                // resolve datetime
                if (chainElement.Name.IsDateTimeMethod() && (!matchingMethod || methodTarget == typeof(DateTimeOffset?)))
                {
                    var datetimeMethod = DatetimeMethodEnumExtensions.FromName(chainElement.Name);
                    var datetimeImpl   = ExprDotEvalDTFactory.ValidateMake(
                        validationContext.StreamTypeService, chainSpecStack, datetimeMethod, chainElement.Name,
                        currentInputType, chainElement.Parameters, inputDesc,
                        validationContext.EngineImportService.TimeZone,
                        validationContext.EngineImportService.TimeAbacus);
                    currentInputType = datetimeImpl.ReturnType;
                    if (currentInputType == null)
                    {
                        throw new IllegalStateException("Date-time method '" + chainElement.Name + "' has not returned type information");
                    }
                    methodEvals.Add(datetimeImpl.Eval);
                    filterAnalyzerDesc = datetimeImpl.IntervalFilterDesc;
                    continue;
                }

                // try to resolve as property if the last method returned a type
                if (currentInputType is EventEPType)
                {
                    var inputEventType = ((EventEPType)currentInputType).EventType;
                    var type           = inputEventType.GetPropertyType(chainElement.Name);
                    var getter         = inputEventType.GetGetter(chainElement.Name);
                    if (type != null && getter != null)
                    {
                        var noduck = new ExprDotEvalProperty(getter, EPTypeHelper.SingleValue(type.GetBoxedType()));
                        methodEvals.Add(noduck);
                        currentInputType = EPTypeHelper.SingleValue(EPTypeHelper.GetClassSingleValued(noduck.TypeInfo));
                        continue;
                    }
                }

                // Finally try to resolve the method
                if (methodTarget != null)
                {
                    try
                    {
                        // find descriptor again, allow for duck typing
                        var desc       = GetValidateMethodDescriptor(methodTarget, chainElement.Name, chainElement.Parameters, validationContext);
                        var fastMethod = desc.FastMethod;
                        paramEvals = desc.ChildEvals;

                        ExprDotEval eval;
                        if (currentInputType is ClassEPType)
                        {
                            // if followed by an enumeration method, convert array to collection
                            if (fastMethod.ReturnType.IsArray && !chainSpecStack.IsEmpty() && chainSpecStack.First.Name.IsEnumerationMethod())
                            {
                                eval = new ExprDotMethodEvalNoDuckWrapArray(validationContext.StatementName, fastMethod, paramEvals);
                            }
                            else
                            {
                                eval = new ExprDotMethodEvalNoDuck(validationContext.StatementName, fastMethod, paramEvals);
                            }
                        }
                        else
                        {
                            eval = new ExprDotMethodEvalNoDuckUnderlying(validationContext.StatementName, fastMethod, paramEvals);
                        }
                        methodEvals.Add(eval);
                        currentInputType = eval.TypeInfo;
                    }
                    catch (Exception e)
                    {
                        if (!isDuckTyping)
                        {
                            throw new ExprValidationException(e.Message, e);
                        }
                        else
                        {
                            var duck = new ExprDotMethodEvalDuck(validationContext.StatementName, validationContext.EngineImportService, chainElement.Name, paramTypes, paramEvals);
                            methodEvals.Add(duck);
                            currentInputType = duck.TypeInfo;
                        }
                    }
                    continue;
                }

                var message = "Could not find event property, enumeration method or instance method named '" +
                              chainElement.Name + "' in " + currentInputType.ToTypeDescriptive();
                throw new ExprValidationException(message);
            }

            var intermediateEvals = methodEvals.ToArray();

            if (lastLambdaFunc != null)
            {
                ExprDotEval finalEval = null;
                if (currentInputType is EventMultiValuedEPType)
                {
                    var mvType        = (EventMultiValuedEPType)currentInputType;
                    var tableMetadata = validationContext.TableService.GetTableMetadataFromEventType(mvType.Component);
                    if (tableMetadata != null)
                    {
                        finalEval = new ExprDotEvalUnpackCollEventBeanTable(mvType.Component, tableMetadata);
                    }
                    else
                    {
                        finalEval = new ExprDotEvalUnpackCollEventBean(mvType.Component);
                    }
                }
                else if (currentInputType is EventEPType)
                {
                    var epType        = (EventEPType)currentInputType;
                    var tableMetadata = validationContext.TableService.GetTableMetadataFromEventType(epType.EventType);
                    if (tableMetadata != null)
                    {
                        finalEval = new ExprDotEvalUnpackBeanTable(epType.EventType, tableMetadata);
                    }
                    else
                    {
                        finalEval = new ExprDotEvalUnpackBean(epType.EventType);
                    }
                }
                if (finalEval != null)
                {
                    methodEvals.Add(finalEval);
                }
            }

            var unpackingEvals = methodEvals.ToArray();

            return(new ExprDotNodeRealizedChain(intermediateEvals, unpackingEvals, filterAnalyzerDesc));
        }
Exemple #9
0
        private void ProcessDispatches(
            ArrayDeque <NamedWindowConsumerLatch> dispatches,
            ArrayDeque <NamedWindowConsumerLatch> work,
            IDictionary <EPStatementAgentInstanceHandle, Object> dispatchesPerStmt)
        {
            if (dispatches.Count == 1)
            {
                var latch = dispatches.First();
                try
                {
                    latch.Await();
                    var newData = latch.DeltaData.NewData;
                    var oldData = latch.DeltaData.OldData;

                    foreach (var entry in latch.DispatchTo)
                    {
                        var handle = entry.Key;

                        handle.StatementHandle.MetricsHandle.Call(
                            _metricReportingService.PerformanceCollector,
                            () => { ProcessHandle(handle, entry.Value, newData, oldData); });

                        if ((_isPrioritized) && (handle.IsPreemptive))
                        {
                            break;
                        }
                    }
                }
                finally
                {
                    latch.Done();
                }

                return;
            }

            // Multiple different-result dispatches to same or different statements are needed in two situations:
            // a) an event comes in, triggers two insert-into statements inserting into the same named window and the window produces 2 results
            // b) a time batch is grouped in the named window, and a timer fires for both groups at the same time producing more then one result
            // c) two on-merge/update/delete statements fire for the same arriving event each updating the named window

            // Most likely all dispatches go to different statements since most statements are not joins of
            // named windows that produce results at the same time. Therefore sort by statement handle.
            // We need to process in N-element chains to preserve dispatches that are next to each other for the same thread.

            while (!dispatches.IsEmpty())
            {
                // the first latch always gets awaited
                var first = dispatches.RemoveFirst();
                first.Await();
                work.Add(first);

                // determine which further latches are in this chain and
                // add these, skipping await for any latches in the chain

                dispatches.RemoveWhere(
                    (next, continuation) =>
                {
                    NamedWindowConsumerLatch earlier = next.Earlier;
                    if (earlier == null || work.Contains(earlier))
                    {
                        work.Add(next);
                        return(true);
                    }
                    else
                    {
                        continuation.Value = false;
                        return(false);
                    }
                });

                ProcessDispatches(work, dispatchesPerStmt);
            }
        }
Exemple #10
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);
            }
        }
Exemple #11
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);
            }
        }
Exemple #12
0
        // Called based on schedule evaluation registered when a variable changes (new data is null).
        // Called when new data arrives.
        private void Expire(
            EventBean[] newData,
            EventBean[] oldData)
        {
            OneEventCollection expired = null;
            if (oldData != null) {
                expired = new OneEventCollection();
                expired.Add(oldData);
            }

            var expiredCount = 0;
            if (!window.IsEmpty()) {
                var newest = window.Last;

                while (true) {
                    var first = window.First;

                    var pass = CheckEvent(first, newest, expiredCount);
                    if (!pass) {
                        if (expired == null) {
                            expired = new OneEventCollection();
                        }

                        var removed = window.RemoveFirst().TheEvent;
                        expired.Add(removed);
                        if (aggregationService != null) {
                            removedEvents[0] = removed;
                            aggregationService.ApplyLeave(removedEvents, null, agentInstanceContext);
                        }

                        expiredCount++;
                        InternalHandleExpired(first);
                    }
                    else {
                        break;
                    }

                    if (window.IsEmpty()) {
                        aggregationService?.ClearResults(agentInstanceContext);

                        break;
                    }
                }
            }

            // Check for any events that get pushed out of the window
            EventBean[] expiredArr = null;
            if (expired != null) {
                expiredArr = expired.ToArray();
            }

            // update event buffer for access by expressions, if any
            viewUpdatedCollection?.Update(newData, expiredArr);

            // If there are child views, call update method
            if (child != null) {
                agentInstanceContext.InstrumentationProvider.QViewIndicate(factory, newData, expiredArr);
                child.Update(newData, expiredArr);
                agentInstanceContext.InstrumentationProvider.AViewIndicate();
            }
        }
Exemple #13
0
        public static ExprDotNodeRealizedChain GetChainEvaluators(
            int? streamOfProviderIfApplicable,
            EPType inputType,
            IList<ExprChainedSpec> chainSpec,
            ExprValidationContext validationContext,
            bool isDuckTyping,
            ExprDotNodeFilterAnalyzerInput inputDesc)
        {
            IList<ExprDotForge> methodForges = new List<ExprDotForge>();
            var currentInputType = inputType;
            EnumMethodEnum? lastLambdaFunc = null;
            var lastElement = chainSpec.IsEmpty() ? null : chainSpec[chainSpec.Count - 1];
            FilterExprAnalyzerAffector filterAnalyzerDesc = null;

            Deque<ExprChainedSpec> chainSpecStack = new ArrayDeque<ExprChainedSpec>(chainSpec);
            while (!chainSpecStack.IsEmpty()) {
                var chainElement = chainSpecStack.RemoveFirst();
                lastLambdaFunc = null; // reset

                // compile parameters for chain element
                var paramForges = new ExprForge[chainElement.Parameters.Count];
                var paramTypes = new Type[chainElement.Parameters.Count];
                for (var i = 0; i < chainElement.Parameters.Count; i++) {
                    paramForges[i] = chainElement.Parameters[i].Forge;
                    paramTypes[i] = paramForges[i].EvaluationType;
                }

                // check if special 'size' method
                if (currentInputType is ClassMultiValuedEPType) {
                    var type = (ClassMultiValuedEPType) currentInputType;
                    if (chainElement.Name.Equals("size", StringComparison.InvariantCultureIgnoreCase) &&
                        paramTypes.Length == 0 &&
                        lastElement == chainElement) {
                        var sizeExpr = new ExprDotForgeArraySize();
                        methodForges.Add(sizeExpr);
                        currentInputType = sizeExpr.TypeInfo;
                        continue;
                    }

                    if (chainElement.Name.Equals("get", StringComparison.InvariantCultureIgnoreCase) &&
                        paramTypes.Length == 1 &&
                        Boxing.GetBoxedType(paramTypes[0]) == typeof(int?)) {
                        var componentType = Boxing.GetBoxedType(type.Component);
                        var get = new ExprDotForgeArrayGet(paramForges[0], componentType);
                        methodForges.Add(get);
                        currentInputType = get.TypeInfo;
                        continue;
                    }
                }

                // determine if there is a matching method
                var matchingMethod = false;
                var methodTarget = GetMethodTarget(currentInputType);
                if (methodTarget != null) {
                    try {
                        GetValidateMethodDescriptor(
                            methodTarget,
                            chainElement.Name,
                            chainElement.Parameters,
                            validationContext);
                        matchingMethod = true;
                    }
                    catch (ExprValidationException) {
                        // expected
                    }
                }

                if (EnumMethodEnumExtensions.IsEnumerationMethod(chainElement.Name) &&
                    (!matchingMethod || methodTarget.IsArray || methodTarget.IsGenericCollection())) {
                    var enumerationMethod = EnumMethodEnumExtensions.FromName(chainElement.Name);
                    if (enumerationMethod == null) {
                        throw new EPException("unable to determine enumeration method from name");
                    }

                    var eval = TypeHelper.Instantiate<ExprDotForgeEnumMethod>(
                        enumerationMethod.Value.GetImplementation());
                    eval.Init(
                        streamOfProviderIfApplicable,
                        enumerationMethod.Value,
                        chainElement.Name,
                        currentInputType,
                        chainElement.Parameters,
                        validationContext);
                    currentInputType = eval.TypeInfo;
                    if (currentInputType == null) {
                        throw new IllegalStateException(
                            "Enumeration method '" + chainElement.Name + "' has not returned type information");
                    }

                    methodForges.Add(eval);
                    lastLambdaFunc = enumerationMethod;
                    continue;
                }

                // resolve datetime
                if (DatetimeMethodEnumHelper.IsDateTimeMethod(chainElement.Name) &&
                    (!matchingMethod ||
                     methodTarget == typeof(DateTimeEx) ||
                     methodTarget == typeof(DateTimeOffset) ||
                     methodTarget == typeof(DateTime))) {
                    var dateTimeMethod = DatetimeMethodEnumHelper.FromName(chainElement.Name);
                    var datetimeImpl = ExprDotDTFactory.ValidateMake(
                        validationContext.StreamTypeService,
                        chainSpecStack,
                        dateTimeMethod,
                        chainElement.Name,
                        currentInputType,
                        chainElement.Parameters,
                        inputDesc,
                        validationContext.ImportService.TimeAbacus,
                        null,
                        validationContext.TableCompileTimeResolver);
                    currentInputType = datetimeImpl.ReturnType;
                    if (currentInputType == null) {
                        throw new IllegalStateException(
                            "Date-time method '" + chainElement.Name + "' has not returned type information");
                    }

                    methodForges.Add(datetimeImpl.Forge);
                    filterAnalyzerDesc = datetimeImpl.IntervalFilterDesc;
                    continue;
                }

                // try to resolve as property if the last method returned a type
                if (currentInputType is EventEPType) {
                    var inputEventType = (EventTypeSPI) ((EventEPType) currentInputType).EventType;
                    var type = inputEventType.GetPropertyType(chainElement.Name);
                    var getter = inputEventType.GetGetterSPI(chainElement.Name);
                    if (type != null && getter != null) {
                        var noduck = new ExprDotForgeProperty(
                            getter,
                            EPTypeHelper.SingleValue(Boxing.GetBoxedType(type)));
                        methodForges.Add(noduck);
                        currentInputType = EPTypeHelper.SingleValue(EPTypeHelper.GetClassSingleValued(noduck.TypeInfo));
                        continue;
                    }
                }

                // Finally try to resolve the method
                if (methodTarget != null) {
                    try {
                        // find descriptor again, allow for duck typing
                        var desc = GetValidateMethodDescriptor(
                            methodTarget,
                            chainElement.Name,
                            chainElement.Parameters,
                            validationContext);
                        paramForges = desc.ChildForges;
                        ExprDotForge forge;
                        if (currentInputType is ClassEPType) {
                            // if followed by an enumeration method, convert array to collection
                            if (desc.ReflectionMethod.ReturnType.IsArray &&
                                !chainSpecStack.IsEmpty() &&
                                EnumMethodEnumExtensions.IsEnumerationMethod(chainSpecStack.First.Name)) {
                                forge = new ExprDotMethodForgeNoDuck(
                                    validationContext.StatementName,
                                    desc.ReflectionMethod,
                                    paramForges,
                                    ExprDotMethodForgeNoDuck.DuckType.WRAPARRAY);
                            }
                            else {
                                forge = new ExprDotMethodForgeNoDuck(
                                    validationContext.StatementName,
                                    desc.ReflectionMethod,
                                    paramForges,
                                    ExprDotMethodForgeNoDuck.DuckType.PLAIN);
                            }
                        }
                        else {
                            forge = new ExprDotMethodForgeNoDuck(
                                validationContext.StatementName,
                                desc.ReflectionMethod,
                                paramForges,
                                ExprDotMethodForgeNoDuck.DuckType.UNDERLYING);
                        }

                        methodForges.Add(forge);
                        currentInputType = forge.TypeInfo;
                    }
                    catch (Exception e) {
                        if (!isDuckTyping) {
                            throw new ExprValidationException(e.Message, e);
                        }

                        var duck = new ExprDotMethodForgeDuck(
                            validationContext.StatementName,
                            validationContext.ImportService,
                            chainElement.Name,
                            paramTypes,
                            paramForges);
                        methodForges.Add(duck);
                        currentInputType = duck.TypeInfo;
                    }

                    continue;
                }

                var message = "Could not find event property, enumeration method or instance method named '" +
                                 chainElement.Name +
                                 "' in " +
                                 EPTypeHelper.ToTypeDescriptive(currentInputType);
                throw new ExprValidationException(message);
            }

            var intermediateEvals = methodForges.ToArray();

            if (lastLambdaFunc != null) {
                ExprDotForge finalEval = null;
                if (currentInputType is EventMultiValuedEPType) {
                    var mvType = (EventMultiValuedEPType) currentInputType;
                    var tableMetadata =
                        validationContext.TableCompileTimeResolver.ResolveTableFromEventType(mvType.Component);
                    if (tableMetadata != null) {
                        finalEval = new ExprDotForgeUnpackCollEventBeanTable(mvType.Component, tableMetadata);
                    }
                    else {
                        finalEval = new ExprDotForgeUnpackCollEventBean(mvType.Component);
                    }
                }
                else if (currentInputType is EventEPType) {
                    var epType = (EventEPType) currentInputType;
                    var tableMetadata =
                        validationContext.TableCompileTimeResolver.ResolveTableFromEventType(epType.EventType);
                    if (tableMetadata != null) {
                        finalEval = new ExprDotForgeUnpackBeanTable(epType.EventType, tableMetadata);
                    }
                    else {
                        finalEval = new ExprDotForgeUnpackBean(epType.EventType);
                    }
                }

                if (finalEval != null) {
                    methodForges.Add(finalEval);
                }
            }

            var unpackingForges = methodForges.ToArray();
            return new ExprDotNodeRealizedChain(intermediateEvals, unpackingForges, filterAnalyzerDesc);
        }
Exemple #14
0
        public static ExprDotNodeRealizedChain GetChainEvaluators(
            int?streamOfProviderIfApplicable,
            EPType inputType,
            IList <Chainable> chainSpec,
            ExprValidationContext validationContext,
            bool isDuckTyping,
            ExprDotNodeFilterAnalyzerInput inputDesc)
        {
            var                        methodForges       = new List <ExprDotForge>();
            var                        currentInputType   = inputType;
            EnumMethodDesc             lastLambdaFunc     = null;
            var                        lastElement        = chainSpec.IsEmpty() ? null : chainSpec[chainSpec.Count - 1];
            FilterExprAnalyzerAffector filterAnalyzerDesc = null;

            Deque <Chainable> chainSpecStack = new ArrayDeque <Chainable>(chainSpec);

            while (!chainSpecStack.IsEmpty())
            {
                var chainElement     = chainSpecStack.RemoveFirst();
                var parameters       = chainElement.GetParametersOrEmpty();
                var chainElementName = chainElement.GetRootNameOrEmptyString();
                var last             = chainSpecStack.IsEmpty();
                lastLambdaFunc = null;                 // reset

                // compile parameters for chain element
                var paramForges = new ExprForge[parameters.Count];
                var paramTypes  = new Type[parameters.Count];
                for (var i = 0; i < parameters.Count; i++)
                {
                    paramForges[i] = parameters[i].Forge;
                    paramTypes[i]  = paramForges[i].EvaluationType;
                }

                // check if special 'size' method
                if (currentInputType is ClassMultiValuedEPType)
                {
                    var type = (ClassMultiValuedEPType)currentInputType;
                    if (string.Equals(chainElementName, "size", StringComparison.InvariantCultureIgnoreCase) &&
                        paramTypes.Length == 0 &&
                        lastElement == chainElement)
                    {
                        ExprDotForge size;
                        var          containerType = ((ClassMultiValuedEPType)currentInputType).Container;
                        if (containerType.IsArray)
                        {
                            size = new ExprDotForgeSizeArray();
                        }
                        else
                        {
                            size = new ExprDotForgeSizeCollection();
                        }

                        methodForges.Add(size);
                        currentInputType = size.TypeInfo;
                        continue;
                    }

                    if (string.Equals(chainElementName, "get", StringComparison.InvariantCultureIgnoreCase) &&
                        paramTypes.Length == 1 &&
                        paramTypes[0].GetBoxedType() == typeof(int?))
                    {
                        ExprDotForge get;
                        var          componentType = type.Component.GetBoxedType();
                        if (type.Container.IsArray)
                        {
                            get = new ExprDotForgeGetArray(paramForges[0], componentType);
                        }
                        else
                        {
                            get = new ExprDotForgeGetCollection(paramForges[0], componentType);
                        }

                        methodForges.Add(get);
                        currentInputType = get.TypeInfo;
                        continue;
                    }

                    if (chainElement is ChainableArray && type.Container.IsArray)
                    {
                        var array     = (ChainableArray)chainElement;
                        var typeInfo  = currentInputType;
                        var indexExpr = ChainableArray.ValidateSingleIndexExpr(
                            array.Indexes,
                            () => "operation on type " + typeInfo.ToTypeDescriptive());
                        var componentType = type.Component.GetBoxedType();
                        var get           = new ExprDotForgeGetArray(indexExpr.Forge, componentType);
                        methodForges.Add(get);
                        currentInputType = get.TypeInfo;
                        continue;
                    }
                }

                // determine if there is a matching method or property
                var methodTarget   = GetMethodTarget(currentInputType);
                var matchingMethod = false;
                if (methodTarget != null && (!(chainElement is ChainableArray)))
                {
                    try {
                        GetValidateMethodDescriptor(methodTarget, chainElementName, parameters, validationContext);
                        matchingMethod = true;
                    }
                    catch (ExprValidationException) {
                        // expected
                    }
                }

                if (EnumMethodResolver.IsEnumerationMethod(chainElementName, validationContext.ImportService) &&
                    (!matchingMethod || methodTarget.IsArray || methodTarget.IsGenericCollection()))
                {
                    var enumerationMethod = EnumMethodResolver.FromName(chainElementName, validationContext.ImportService);
                    if (enumerationMethod == null)
                    {
                        throw new EPException("unable to determine enumeration method from name");
                    }

                    var eval = enumerationMethod.Factory.Invoke(chainElement.GetParametersOrEmpty().Count);
                    if (currentInputType is ClassEPType classEpType && classEpType.Clazz.IsGenericCollection() && !classEpType.Clazz.IsArray)
                    {
                        currentInputType = EPTypeHelper.CollectionOfSingleValue(typeof(object), null);
                    }

                    eval.Init(streamOfProviderIfApplicable, enumerationMethod, chainElementName, currentInputType, parameters, validationContext);
                    currentInputType = eval.TypeInfo;
                    if (currentInputType == null)
                    {
                        throw new IllegalStateException("Enumeration method '" + chainElementName + "' has not returned type information");
                    }

                    methodForges.Add(eval);
                    lastLambdaFunc = enumerationMethod;
                    continue;
                }

                // resolve datetime
                if (DatetimeMethodResolver.IsDateTimeMethod(chainElementName, validationContext.ImportService) &&
                    (!matchingMethod ||
                     methodTarget == typeof(DateTimeEx) ||
                     methodTarget == typeof(DateTimeOffset) ||
                     methodTarget == typeof(DateTime)))
                {
                    var datetimeMethod = DatetimeMethodResolver.FromName(chainElementName, validationContext.ImportService);
                    var datetimeImpl   = ExprDotDTFactory.ValidateMake(
                        validationContext.StreamTypeService,
                        chainSpecStack,
                        datetimeMethod,
                        chainElementName,
                        currentInputType,
                        parameters,
                        inputDesc,
                        validationContext.ImportService.TimeAbacus,
                        validationContext.TableCompileTimeResolver,
                        validationContext.ImportService,
                        validationContext.StatementRawInfo);
                    currentInputType = datetimeImpl.ReturnType;
                    if (currentInputType == null)
                    {
                        throw new IllegalStateException(
                                  "Date-time method '" + chainElementName + "' has not returned type information");
                    }

                    methodForges.Add(datetimeImpl.Forge);
                    filterAnalyzerDesc = datetimeImpl.IntervalFilterDesc;
                    continue;
                }

                // try to resolve as property if the last method returned a type
                if (currentInputType is EventEPType)
                {
                    if (chainElement is ChainableArray)
                    {
                        throw new ExprValidationException("Could not perform array operation on type " + currentInputType.ToTypeDescriptive());
                    }

                    var          inputEventType = (EventTypeSPI)((EventEPType)currentInputType).EventType;
                    var          type           = inputEventType.GetPropertyType(chainElementName);
                    var          getter         = inputEventType.GetGetterSPI(chainElementName);
                    var          fragmentType   = inputEventType.GetFragmentType(chainElementName);
                    ExprDotForge forge;
                    if (type != null && getter != null)
                    {
                        if (fragmentType == null || last)
                        {
                            forge            = new ExprDotForgeProperty(getter, EPTypeHelper.SingleValue(type.GetBoxedType()));
                            currentInputType = forge.TypeInfo;
                        }
                        else
                        {
                            if (!fragmentType.IsIndexed)
                            {
                                currentInputType = EPTypeHelper.SingleEvent(fragmentType.FragmentType);
                            }
                            else
                            {
                                currentInputType = EPTypeHelper.ArrayOfEvents(fragmentType.FragmentType);
                            }

                            forge = new ExprDotForgePropertyFragment(getter, currentInputType);
                        }

                        methodForges.Add(forge);
                        continue;
                    }
                }

                if (currentInputType is EventMultiValuedEPType eventMultiValuedEpType && chainElement is ChainableArray chainableArray)
                {
                    var inputEventType = (EventTypeSPI)eventMultiValuedEpType.Component;
                    var typeInfo       = currentInputType;
                    var indexExpr      = ChainableArray.ValidateSingleIndexExpr(
                        chainableArray.Indexes,
                        () => "operation on type " + typeInfo.ToTypeDescriptive());
                    currentInputType = EPTypeHelper.SingleEvent(inputEventType);
                    var forge = new ExprDotForgeEventArrayAtIndex(currentInputType, indexExpr);
                    methodForges.Add(forge);
                    continue;
                }

                // Finally try to resolve the method
                if (methodTarget != null && !(chainElement is ChainableArray))
                {
                    try {
                        // find descriptor again, allow for duck typing
                        var desc = GetValidateMethodDescriptor(methodTarget, chainElementName, parameters, validationContext);
                        paramForges = desc.ChildForges;
                        ExprDotForge forge;
                        if (currentInputType is ClassEPType)
                        {
                            // if followed by an enumeration method, convert array to collection
                            if (desc.ReflectionMethod.ReturnType.IsArray &&
                                !chainSpecStack.IsEmpty() &&
                                EnumMethodResolver.IsEnumerationMethod(chainSpecStack.First.GetRootNameOrEmptyString(), validationContext.ImportService))
                            {
                                forge = new ExprDotMethodForgeNoDuck(
                                    validationContext.StatementName,
                                    desc.ReflectionMethod,
                                    paramForges,
                                    ExprDotMethodForgeNoDuck.DuckType.WRAPARRAY);
                            }
                            else
                            {
                                forge = new ExprDotMethodForgeNoDuck(
                                    validationContext.StatementName,
                                    desc.ReflectionMethod,
                                    paramForges,
                                    ExprDotMethodForgeNoDuck.DuckType.PLAIN);
                            }
                        }
                        else
                        {
                            forge = new ExprDotMethodForgeNoDuck(
                                validationContext.StatementName,
                                desc.ReflectionMethod,
                                paramForges,
                                ExprDotMethodForgeNoDuck.DuckType.UNDERLYING);
                        }

                        methodForges.Add(forge);
                        currentInputType = forge.TypeInfo;
                    }
                    catch (Exception e) {
                        if (!isDuckTyping)
                        {
                            throw new ExprValidationException(e.Message, e);
                        }

                        var duck = new ExprDotMethodForgeDuck(
                            validationContext.StatementName,
                            validationContext.ImportService,
                            chainElementName,
                            paramTypes,
                            paramForges);
                        methodForges.Add(duck);
                        currentInputType = duck.TypeInfo;
                    }

                    continue;
                }

                string message;
                if (!(chainElement is ChainableArray))
                {
                    message = "Could not find event property or method named '" + chainElementName + "' in " + currentInputType.ToTypeDescriptive();
                }
                else
                {
                    message = "Could not perform array operation on type " + currentInputType.ToTypeDescriptive();
                }

                throw new ExprValidationException(message);
            }

            var intermediateEvals = methodForges.ToArray();

            if (lastLambdaFunc != null)
            {
                ExprDotForge finalEval = null;
                if (currentInputType is EventMultiValuedEPType mvType)
                {
                    var tableMetadata = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(mvType.Component);
                    if (tableMetadata != null)
                    {
                        finalEval = new ExprDotForgeUnpackCollEventBeanTable(mvType.Component, tableMetadata);
                    }
                    else
                    {
                        finalEval = new ExprDotForgeUnpackCollEventBean(mvType.Component);
                    }
                }
                else if (currentInputType is EventEPType epType)
                {
                    var tableMetadata = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(epType.EventType);
                    if (tableMetadata != null)
                    {
                        finalEval = new ExprDotForgeUnpackBeanTable(epType.EventType, tableMetadata);
                    }
                    else
                    {
                        finalEval = new ExprDotForgeUnpackBean(epType.EventType);
                    }
                }

                if (finalEval != null)
                {
                    methodForges.Add(finalEval);
                }
            }

            var unpackingForges = methodForges.ToArray();

            return(new ExprDotNodeRealizedChain(intermediateEvals, unpackingForges, filterAnalyzerDesc));
        }
Exemple #15
0
        // Called based on schedule evaluation registered when a variable changes (new data is null).
        // Called when new data arrives.
        private void Expire(EventBean[] newData, EventBean[] oldData)
        {
            OneEventCollection expired = null;

            if (oldData != null)
            {
                expired = new OneEventCollection();
                expired.Add(oldData);
            }
            int expiredCount = 0;

            if (!_window.IsEmpty())
            {
                ExpressionWindowTimestampEventPair newest = _window.Last;

                while (true)
                {
                    ExpressionWindowTimestampEventPair first = _window.First;

                    bool pass = CheckEvent(first, newest, expiredCount);
                    if (!pass)
                    {
                        if (expired == null)
                        {
                            expired = new OneEventCollection();
                        }
                        EventBean removed = _window.RemoveFirst().TheEvent;
                        expired.Add(removed);
                        if (AggregationService != null)
                        {
                            _removedEvents[0] = removed;
                            AggregationService.ApplyLeave(_removedEvents, null, AgentInstanceContext);
                        }
                        expiredCount++;
                        InternalHandleExpired(first);
                    }
                    else
                    {
                        break;
                    }

                    if (_window.IsEmpty())
                    {
                        if (AggregationService != null)
                        {
                            AggregationService.ClearResults(AgentInstanceContext);
                        }
                        break;
                    }
                }
            }

            // Check for any events that get pushed out of the window
            EventBean[] expiredArr = null;
            if (expired != null)
            {
                expiredArr = expired.ToArray();
            }

            // update event buffer for access by expressions, if any
            if (ViewUpdatedCollection != null)
            {
                ViewUpdatedCollection.Update(newData, expiredArr);
            }

            // If there are child views, call update method
            if (HasViews)
            {
                if (InstrumentationHelper.ENABLED)
                {
                    InstrumentationHelper.Get().QViewIndicate(this, _dataWindowViewFactory.ViewName, newData, expiredArr);
                }
                UpdateChildren(newData, expiredArr);
                if (InstrumentationHelper.ENABLED)
                {
                    InstrumentationHelper.Get().AViewIndicate();
                }
            }
        }
Exemple #16
0
        private void ProcessDispatches(
            ArrayDeque<NamedWindowConsumerLatch> dispatches,
            ArrayDeque<NamedWindowConsumerLatch> work,
            IDictionary<EPStatementAgentInstanceHandle, object> dispatchesPerStmt)
        {
            if (dispatches.Count == 1) {
                var latch = dispatches.First;
                try {
                    latch.Await();
                    var newData = latch.DeltaData.NewData;
                    var oldData = latch.DeltaData.OldData;

                    if (metricReportingService.IsMetricsReportingEnabled) {
                        foreach (var entry in latch.DispatchTo) {
                            var handle = entry.Key;
                            if (handle.StatementHandle.MetricsHandle.IsEnabled) {
                                var performanceMetric = PerformanceMetricsHelper.Call(
                                    () => ProcessHandle(handle, entry.Value, newData, oldData), 1);
                                metricReportingService.AccountTime(
                                    handle.StatementHandle.MetricsHandle,
                                    performanceMetric, performanceMetric.NumInput);
                            }
                            else {
                                ProcessHandle(handle, entry.Value, newData, oldData);
                            }

                            if (isPrioritized && handle.IsPreemptive) {
                                break;
                            }
                        }
                    }
                    else {
                        foreach (var entry in latch.DispatchTo) {
                            var handle = entry.Key;
                            ProcessHandle(handle, entry.Value, newData, oldData);

                            if (isPrioritized && handle.IsPreemptive) {
                                break;
                            }
                        }
                    }
                }
                finally {
                    latch.Done();
                }

                return;
            }

            // Multiple different-result dispatches to same or different statements are needed in two situations:
            // a) an event comes in, triggers two insert-into statements inserting into the same named window and the window produces 2 results
            // b) a time batch is grouped in the named window, and a timer fires for both groups at the same time producing more then one result
            // c) two on-merge/update/delete statements fire for the same arriving event each updating the named window
            // Most likely all dispatches go to different statements since most statements are not joins of
            // named windows that produce results at the same time. Therefore sort by statement handle.
            // We need to process in N-element chains to preserve dispatches that are next to each other for the same thread.
            while (!dispatches.IsEmpty()) {
                // the first latch always gets awaited
                var first = dispatches.RemoveFirst();
                first.Await();
                work.Add(first);

                // determine which further latches are in this chain and add these, skipping await for any latches in the chain

                dispatches.RemoveWhere(
                    (next, continuation) => {
                        var result = next.Earlier == null || work.Contains(next.Earlier);
                        continuation.Value = !result;
                        return result;
                    },
                    work.Add);

#if false
                var enumerator = dispatches.GetEnumerator();
                while (enumerator.MoveNext()) {
                    var next = enumerator.Current;
                    var earlier = next.Earlier;
                    if (earlier == null || work.Contains(earlier)) {
                        work.Add(next);
                        enumerator.Remove();
                    }
                    else {
                        break;
                    }
                }
#endif

                ProcessDispatches(work, dispatchesPerStmt);
            }
        }
Exemple #17
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);
            }
        }