예제 #1
0
        public override IEnumerable <IntervalEvent <TRegister> > GenerateOutput(IEnumerable <IntervalEvent <TInput> > events, WindowDescriptor windowDescriptor)
        {
            SortedDictionary <DateTimeOffset, EventSet <TInput> > allEvents = new SortedDictionary <DateTimeOffset, EventSet <TInput> >();

            foreach (IntervalEvent <TInput> evt in events)
            {
                if (evt.StartTime.AddTicks(1) != evt.EndTime)
                {
                    // This condition implies an event that is not a point event. This AFA
                    // operator supports only point events, hence we raise an exception.
                    throw new InvalidOperationException("Received an event that is not a point event. The AFA operator only supports point events.");
                }

                EventSet <TInput> eventSet;
                if (!allEvents.TryGetValue(evt.StartTime, out eventSet))
                {
                    eventSet = new EventSet <TInput>(evt.StartTime);
                    allEvents.Add(evt.StartTime, eventSet);
                }

                eventSet.Add(evt);
            }

            List <IntervalEvent <TRegister> > result = new List <IntervalEvent <TRegister> >();
            LinkedList <Run> previousRuns            = null;

            foreach (var item in allEvents)
            {
                previousRuns = this.Insert(result, windowDescriptor.EndTime, previousRuns, item.Value);
            }

            return(result);
        }
예제 #2
0
        internal bool TryApplyTransition(EventSet <TInput> inputEvents, int fromState, int toState, TRegister oldRegister, out TRegister newRegister)
        {
            TransitionDelegate <TInput, TRegister> arc;

            if (this._transitionInfo.ContainsKey(fromState) && this._transitionInfo[fromState].TryGetValue(toState, out arc))
            {
                return(arc(inputEvents.Events.AsReadOnly(), oldRegister, out newRegister));
            }

            newRegister = default(TRegister);
            return(false);
        }
예제 #3
0
        private LinkedList <Run> Insert(List <IntervalEvent <TRegister> > result, DateTimeOffset endTime, LinkedList <Run> previousRuns, EventSet <TInput> inputEvents)
        {
            // Insert assumes that EventSets are fed in increasing order of timestamps
            LinkedList <Run> currentRuns = new LinkedList <Run>();

            // Create new runs from existing runs that end at immediately preceeding sequence number
            if (previousRuns != null)
            {
                foreach (Run previousRun in previousRuns)
                {
                    ApplyTransition(result, endTime, previousRun, inputEvents, currentRuns);
                }
            }

            // Create new runs starting from the new sequence number
            Run run = new Run(_descriptor.StartState, _descriptor.DefaultRegister);

            ApplyTransition(result, endTime, run, inputEvents, currentRuns);

            if (currentRuns.Count == 0)
            {
                currentRuns = null;
            }

            return(currentRuns);
        }
예제 #4
0
        private void ApplyTransition(List <IntervalEvent <TRegister> > result, DateTimeOffset endTime, Run previousRun, EventSet <TInput> inputEvents, LinkedList <Run> currentRuns)
        {
            int fromState = previousRun.State;

            List <int> toStates = _descriptor.GetToStates(fromState);

            foreach (int toState in toStates)
            {
                TRegister targetRegister;
                if (_descriptor.TryApplyTransition(inputEvents, fromState, toState, previousRun.Register, out targetRegister))
                {
                    Run newRun = new Run(toState, targetRegister);

                    if (_descriptor.IsFinalState(toState))
                    {
                        // If we have reached a final state, include the register value in result.
                        IntervalEvent <TRegister> outputEvent = CreateIntervalEvent();
                        outputEvent.Payload   = newRun.Register;
                        outputEvent.StartTime = inputEvents.StartTime;
                        outputEvent.EndTime   = endTime;
                        result.Add(outputEvent);
                    }

                    currentRuns.AddLast(newRun);
                }
            }
        }