Example #1
0
        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;
        }
Example #3
0
        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));
        }
Example #4
0
        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));
 }