public TimeSliceAsyncEnumerator(TimeSliceAsyncEnumerable <TValue, TAggr> source) { _source = source; _enumerator = _source._series.GetEnumerator(); _current = default(KeyValuePair <DateTime, TAggr>); _position = TimeSlicePosition.NotStarted; }
public async Task <bool> MoveNext(CancellationToken cancellationToken) { var e = _enumerator as IAsyncEnumerator <KeyValuePair <DateTime, TValue> >; if (e == null) { return(false); } switch (_position) { case TimeSlicePosition.NotStarted: if (await e.MoveNext(cancellationToken)) { var slice = StartOfSlice(_enumerator.Current.Key); _current = new KeyValuePair <DateTime, TAggr>(slice, _source._initState(_enumerator.Current.Value)); _position = TimeSlicePosition.Aggregating; goto case TimeSlicePosition.Aggregating; } return(false); case TimeSlicePosition.FinishedSync: case TimeSlicePosition.Aggregating: var prev = _current; while (await e.MoveNext(cancellationToken)) { var slice = StartOfSlice(_enumerator.Current.Key); if (slice == prev.Key) { _current = new KeyValuePair <DateTime, TAggr>(slice, _source._aggregator(prev.Value, _enumerator.Current.Value)); prev = _current; } else { _position = TimeSlicePosition.PassedToNext; return(true); } } _position = TimeSlicePosition.FinishedAsync; return(true); case TimeSlicePosition.PassedToNext: // here we have one unused value at the current position { var slice = StartOfSlice(_enumerator.Current.Key); _current = new KeyValuePair <DateTime, TAggr>(slice, _source._initState(_enumerator.Current.Value)); _position = TimeSlicePosition.Aggregating; goto case TimeSlicePosition.Aggregating; } case TimeSlicePosition.FinishedAsync: return(false); default: throw new ArgumentOutOfRangeException(); } }
public bool MoveNext() { switch (_position) { case TimeSlicePosition.NotStarted: if (_enumerator.MoveNext()) { var slice = StartOfSlice(_enumerator.Current.Key); _current = new KeyValuePair <DateTime, TAggr>(slice, _source._initState(_enumerator.Current.Value)); _position = TimeSlicePosition.Aggregating; goto case TimeSlicePosition.Aggregating; } _position = TimeSlicePosition.FinishedSync; return(false); case TimeSlicePosition.Aggregating: var prev = _current; while (_enumerator.MoveNext()) { var slice = StartOfSlice(_enumerator.Current.Key); if (slice == prev.Key) { _current = new KeyValuePair <DateTime, TAggr>(slice, _source._aggregator(prev.Value, _enumerator.Current.Value)); prev = _current; } else { _position = TimeSlicePosition.PassedToNext; return(true); } } _position = TimeSlicePosition.FinishedSync; // at least one move was OK, need to return true return(true); case TimeSlicePosition.PassedToNext: // here we have one unused value at the current position { var slice = StartOfSlice(_enumerator.Current.Key); _current = new KeyValuePair <DateTime, TAggr>(slice, _source._initState(_enumerator.Current.Value)); _position = TimeSlicePosition.Aggregating; goto case TimeSlicePosition.Aggregating; } case TimeSlicePosition.FinishedSync: return(false); default: throw new ArgumentOutOfRangeException(); } }