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); }
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); }
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); }
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); } } }