public override AsyncIterator <TResult> Where(Func <TResult, CancellationToken, Task <bool> > asyncPredicate) { Contract.NotNull(asyncPredicate); // note: the only possible optimization here is if TSource == TResult, then we can combine both predicates // remember: limit/offset are applied AFTER the filtering, so can only combine if they are null if (m_limit == null && (m_offset == null || m_offset.Value == 0) && typeof(TSource) == typeof(TResult)) //BUGBUG: type comparison maybe should check derived classes also ? { var asyncFilter = new AsyncFilterExpression <TSource>((Func <TSource, CancellationToken, Task <bool> >)(Delegate) asyncPredicate); if (m_filter != null) { asyncFilter = m_filter.AndAlso(asyncFilter); } //BUGBUG: if the query already has a select, it should be evaluated BEFORE the new filter, // but currently WhereSelectAsyncIterator<> filters before transformations ! return(new WhereSelectAsyncIterator <TSource, TResult>( m_source, asyncFilter, m_transform, m_limit, m_offset )); } // no easy optimization... return(base.Where(asyncPredicate)); }
public WhereAsyncIterator(IAsyncEnumerable <TSource> source, AsyncFilterExpression <TSource> filter) : base(source) { Contract.Debug.Requires(filter != null, "there can be only one kind of filter specified"); m_filter = filter; }
public override AsyncIterator <TResult> Where(Func <TResult, bool> predicate) { Contract.NotNull(predicate); // note: the only possible optimization here is if TSource == TResult, then we can combine both predicates // remember: limit/offset are applied AFTER the filtering, so can only combine if they are null // also, since transform is done after filtering, we can only optimize if transform is null (not allowed!) or the identity function if (m_limit == null && (m_offset == null || m_offset.Value == 0) && typeof(TSource) == typeof(TResult) && //BUGBUG: type comparison maybe should check derived classes also ? m_transform.IsIdentity()) { var filter = new AsyncFilterExpression <TSource>((Func <TSource, bool>)(Delegate) predicate); if (m_filter != null) { filter = m_filter.AndAlso(filter); } //BUGBUG: if the query already has a select, it should be evaluated BEFORE the new filter, // but currently WhereSelectAsyncIterator<> filters before transformations ! return(new WhereSelectAsyncIterator <TSource, TResult>( m_source, filter, m_transform, m_limit, m_offset )); } // no easy optimization... return(base.Where(predicate)); }
public WhereSelectAsyncIterator( IAsyncEnumerable <TSource> source, AsyncFilterExpression <TSource>?filter, AsyncTransformExpression <TSource, TResult> transform, int?limit, int?offset ) : base(source) { Contract.Debug.Requires(transform != null); // must do at least something Contract.Debug.Requires((limit ?? 0) >= 0 && (offset ?? 0) >= 0); // bounds cannot be negative m_filter = filter; m_transform = transform; m_limit = limit; m_offset = offset; }
internal static WhereAsyncIterator <TResult> Filter <TResult>( [NotNull] IAsyncEnumerable <TResult> source, [NotNull] AsyncFilterExpression <TResult> filter) { return(new WhereAsyncIterator <TResult>(source, filter)); }