Ejemplo n.º 1
0
 internal ParallelUnorderedRunOn(IParallelFlux <T> source, Scheduler scheduler,
                                 int prefetch)
 {
     this.source    = source;
     this.scheduler = scheduler;
     this.prefetch  = prefetch;
 }
 /// <summary>
 /// aps the source values on each 'rail' to another value.
 /// </summary>
 /// <remarks>
 /// Note that the same predicate may be called from multiple threads concurrently.
 /// </remarks>
 /// <typeparam name="T">The value type.</typeparam>
 /// <typeparam name="R">The result value type.</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="mapper">the mapper function turning Ts into Us</param>
 /// <returns>the new IParallelPublisher instance</returns>
 public static IParallelFlux <R> Map <T, R>(this IParallelFlux <T> source, Func <T, R> mapper)
 {
     if (source.IsOrdered)
     {
         return(new ParallelOrderedMap <T, R>((ParallelOrderedFlux <T>)source, mapper));
     }
     return(new ParallelUnorderedMap <T, R>(source, mapper));
 }
 /// <summary>
 /// Filters the source values on each 'rail'.
 /// </summary>
 /// <remarks>
 /// Note that the same predicate may be called from multiple threads concurrently.
 /// </remarks>
 /// <typeparam name="T">The value type.</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="predicate">the function returning true to keep a value or false to drop a value</param>
 /// <returns>the new IParallelPublisher instance</returns>
 public static IParallelFlux <T> Filter <T>(this IParallelFlux <T> source, Func <T, bool> predicate)
 {
     if (source.IsOrdered)
     {
         return(new ParallelOrderedFilter <T>((ParallelOrderedFlux <T>)source, predicate));
     }
     return(new ParallelUnorderedFilter <T>(source, predicate));
 }
 /// <summary>
 /// Merges the values from each 'rail' in a round-robin or same-order fashion and
 /// exposes it as a regular Publisher sequence, running with a give prefetch value
 /// for the rails.
 /// </summary>
 /// <typeparam name="T">The value type.</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="prefetch">the prefetch amount to use for each rail</param>
 /// <returns>The new IFlux instance</returns>
 public static IFlux <T> Sequential <T>(this IParallelFlux <T> source, int prefetch)
 {
     if (source.IsOrdered)
     {
         return(new ParallelOrderedJoin <T>((ParallelOrderedFlux <T>)source, prefetch));
     }
     return(new ParallelUnorderedJoin <T>(source, prefetch));
 }
 /// <summary>
 /// Specifies where each 'rail' will observe its incoming values with
 /// no work-stealing and a given prefetch amount.
 /// </summary>
 /// <remarks>
 /// This operator uses the default prefetch size returned by {@code Px.bufferSize()}.
 /// <p/>
 /// The operator will call {@code Scheduler.createWorker()} as many
 /// times as this ParallelPublisher's parallelism level is.
 /// <p/>
 /// No assumptions are made about the Scheduler's parallelism level,
 /// if the Scheduler's parallelism level is lwer than the ParallelPublisher's,
 /// some rails may end up on the same thread/worker.
 /// <p/>
 /// This operator doesn't require the Scheduler to be trampolining as it
 /// does its own built-in trampolining logic.
 /// </remarks>
 /// <typeparam name="T">The value type.</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="scheduler">The scheduler whose workers to use.</param>
 /// <param name="prefetch">the number of values to request on each 'rail' from the source</param>
 /// <returns>the new IParallelPublisher instance</returns>
 public static IParallelFlux <T> RunOn <T>(this IParallelFlux <T> source, Scheduler scheduler, int prefetch)
 {
     if (source.IsOrdered)
     {
         return(new ParallelOrderedRunOn <T>((ParallelOrderedFlux <T>)source, scheduler, prefetch));
     }
     return(new ParallelUnorderedRunOn <T>(source, scheduler, prefetch));
 }
 /// <summary>
 /// Call the specified consumer with the exception passing through any 'rail'.
 /// </summary>
 /// <typeparam name="T">The value type.</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="onError">The action to call</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <T> DoOnError <T>(this IParallelFlux <T> source, Action <Exception> onError)
 {
     // return PublisherPeek<T>.withOnError(source, onError);
     if (source.IsOrdered)
     {
     }
     // TODO implement DoOnError
     throw new NotImplementedException();
 }
 /// <summary>
 /// Call the specified consumer with the current element passing through any 'rail'
 /// after it has been delivered to downstream within the rail.
 /// </summary>
 /// <typeparam name="T">The value type.</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="onAfterNext">the action to call</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <T> DoAfterNext <T>(this IParallelFlux <T> source, Action <T> onAfterNext)
 {
     // return PublisherPeek<T>.withOnAfterNext(source, onAfterNext);
     if (source.IsOrdered)
     {
     }
     // TODO implement DoAfterNext
     throw new NotImplementedException();
 }
 /// <summary>
 /// Removes any ordering information from this Parallel sequence,
 /// if not already unordered.
 /// </summary>
 /// <typeparam name="T">the value type</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <T> Unordered <T>(this IParallelFlux <T> source)
 {
     if (!source.IsOrdered)
     {
         return(source);
     }
     // TODO implement Unordered
     throw new NotImplementedException();
 }
 /// <summary>
 /// Call the specified consumer with the request amount if any rail receives a request.
 /// </summary>
 /// <typeparam name="T">The value type.</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="onRequest">the action to call</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <T> DoOnRequest <T>(this IParallelFlux <T> source, Action <long> onRequest)
 {
     // return PublisherPeek<T>.withOnRequest(source, onRequest);
     if (source.IsOrdered)
     {
     }
     // TODO implement DoOnRequest
     throw new NotImplementedException();
 }
 /// <summary>
 /// Call the specified callback before the terminal event is delivered on each 'rail'.
 /// </summary>
 /// <typeparam name="T">The value type.</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="onTerminate">The action to call</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <T> DoOnTerminate <T>(this IParallelFlux <T> source, Action onTerminate)
 {
     // return PublisherPeek<T>.withOnTerminate(source, onTerminate);
     if (source.IsOrdered)
     {
     }
     // TODO implement DoOnTerminate
     throw new NotImplementedException();
 }
 /// <summary>
 /// Call the specified callback when a 'rail' receives a Subscription from its upstream.
 /// </summary>
 /// <typeparam name="T">The value type.</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="onSubscribe">The action to call</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <T> DoOnSubscribe <T>(this IParallelFlux <T> source, Action <ISubscription> onSubscribe)
 {
     // return PublisherPeek<T>.withOnSubscribe(source, onSubscribe);
     if (source.IsOrdered)
     {
     }
     // TODO implement DoOnSubscribe
     throw new NotImplementedException();
 }
 /// <summary>
 /// Turns this Parallel sequence into an ordered sequence via local indexing,
 /// if not already ordered.
 /// </summary>
 /// <typeparam name="T">the value type</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="global">hould the indexing local (per rail) or globar FIFO?</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <T> Ordered <T>(this IParallelFlux <T> source, bool global = false)
 {
     if (source.IsOrdered)
     {
         return(source);
     }
     // TODO implement Ordered
     throw new NotImplementedException();
 }
 /// <summary>
 /// Call the specified consumer with a specific exception class passing through any 'rail'.
 /// </summary>
 /// <typeparam name="T">The value type.</typeparam>
 /// <typeparam name="E">The exception type</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="onError">The action to call</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <T> DoOnError <T, E>(this IParallelFlux <T> source, Action <E> onError) where E : Exception
 {
     return(DoOnError(source, e =>
     {
         if (e is E)
         {
             onError(e as E);
         }
     }));
 }
 /// <summary>
 /// Call the specified predicate with a errors passing through any 'rail'
 /// and if it returns true, call the action with it.
 /// </summary>
 /// <typeparam name="T">The value type.</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="predicate">The predicate to call with any errors passing through.</param>
 /// <param name="onError">The action to call</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <T> DoOnError <T>(this IParallelFlux <T> source, Func <Exception, bool> predicate, Action <Exception> onError)
 {
     return(DoOnError(source, e =>
     {
         if (predicate(e))
         {
             onError(e);
         }
     }));
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Validate that the parallelism of the IParallelFlux equals to the number of elements in
 /// the ISubscriber array. If not, each ISubscriber is notified with an ArgumentException.
 /// </summary>
 /// <typeparam name="T">The element type of the parallel flux</typeparam>
 /// <typeparam name="U">The element type of the ISubscriber array (could be T or IOrderedItem{T})</typeparam>
 /// <param name="pf">The parent IParallelFlux instance</param>
 /// <param name="subscribers">The ISubscriber array</param>
 /// <returns>True if the subscribers were valid</returns>
 internal static bool Validate <T, U>(this IParallelFlux <T> pf, ISubscriber <U>[] subscribers)
 {
     if (pf.Parallelism != subscribers.Length)
     {
         Exception ex = new ArgumentException("Parallelism(" + pf.Parallelism + ") != Subscriber count (" + subscribers.Length + ")");
         foreach (ISubscriber <U> s in subscribers)
         {
             EmptySubscription <U> .Error(s, ex);
         }
         return(false);
     }
     return(true);
 }
        /// <summary>
        /// Sorts the 'rails' of this ParallelPublisher and returns a Publisher that sequentially
        /// picks the smallest next value from the rails.
        /// </summary>
        /// <remarks>
        /// This operator requires a finite source IParallelPublisher.
        /// </remarks>
        /// <typeparam name="T">The value type.</typeparam>
        /// <param name="source">The source IParallelPublisher instance.</param>
        /// <param name="comparer">the IComparer to use</param>
        /// <param name="capacityHint">the expected number of total elements</param>
        /// <returns>The new IFlux instance</returns>
        public static IFlux <T> Sorted <T>(this IParallelFlux <T> source, IComparer <T> comparer, int capacityHint = 16)
        {
            int ch = capacityHint / source.Parallelism + 1;
            IParallelFlux <List <T> > lists = source.Reduce(() => new List <T>(ch), (a, b) =>
            {
                a.Add(b);
                return(a);
            })
                                              .Map(v =>
            {
                v.Sort(comparer);
                return(v);
            });

            return(new ParallelSortedJoin <T>(lists, comparer));
        }
 /// <summary>
 /// Generates and flattens Publishers on each 'rail', optionally delaying errors
 /// and having a total number of simultaneous subscriptions to the inner IPublishers.
 /// </summary>
 /// <typeparam name="T">the value type</typeparam>
 /// <typeparam name="R">The result type</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="mapper">the function to map each rail's value into a IPublisher</param>
 /// <param name="maxConcurrency">the maximum number of simultaneous subscriptions to the generated inner IPublishers</param>
 /// <param name="delayErrors">should the errors from the main and the inner sources delayed till everybody terminates?</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <R> FlatMap <T, R>(this IParallelFlux <T> source, Func <T, IPublisher <R> > mapper, int maxConcurrency, bool delayErrors = false)
 {
     return(FlatMap(source, mapper, maxConcurrency, Flux.BufferSize, delayErrors));
 }
Ejemplo n.º 18
0
 internal ParallelReduce(IParallelFlux <T> source, Func <R> initialFactory, Func <R, T, R> reducer)
 {
     this.source         = source;
     this.initialFactory = initialFactory;
     this.reducer        = reducer;
 }
 internal ParallelUnorderedJoin(IParallelFlux <T> source, int prefetch)
 {
     this.source   = source;
     this.prefetch = prefetch;
 }
 /// <summary>
 /// Generates and concatenates Publishers on each 'rail', optionally delaying errors
 /// and using the given prefetch amount for generating IPublishers upfront.
 /// </summary>
 /// <typeparam name="T">the value type</typeparam>
 /// <typeparam name="R">The result type</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="mapper">the function to map each rail's value into a IPublisher</param>
 /// <param name="prefetch">the number of items to prefetch from each inner IPublisher</param>
 /// <param name="errorMode">the error handling, i.e., when to report errors from the main
 /// source and the inner Publishers (immediate, boundary, end)</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <R> ConcatMap <T, R>(this IParallelFlux <T> source, Func <T, IPublisher <R> > mapper, int prefetch, ConcatErrorMode errorMode = ConcatErrorMode.Immediate)
 {
     // TODO implement ConcatMap
     throw new NotImplementedException();
 }
 /// <summary>
 /// Sorts the 'rails' according to the comparator and returns a full sorted list as a Publisher.
 /// </summary>
 /// <remarks>
 /// This operator requires a finite source IParallelPublisher.
 /// </remarks>
 /// <typeparam name="T">The value type.</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="comparer">the IComparer to use</param>
 /// <param name="capacityHint">the expected number of total elements</param>
 /// <returns>The new IFlux instance</returns>
 public static IMono <IList <T> > ToSortedList <T>(this IParallelFlux <T> source, IComparer <T> comparer, int capacityHint = 16)
 {
     return(Sorted <T>(source, comparer, capacityHint).CollectList(capacityHint));
 }
 /// <summary>
 /// Collect the elements in each rail into a collection supplied via a collectionSupplier
 /// and collected into with a collector action, emitting the collection at the end.
 /// </summary>
 /// <typeparam name="T">The value type.</typeparam>
 /// <typeparam name="C">the collection type</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="initialCollection">the supplier of the collection in each rail</param>
 /// <param name="collector">the collector, taking the per-rali collection and the current item</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <C> Collect <T, C>(this IParallelFlux <T> source, Func <C> initialCollection, Action <C, T> collector)
 {
     return(Reduce <T, C>(source, initialCollection, (a, b) => { collector(a, b); return a; }));
 }
Ejemplo n.º 23
0
 internal ParallelReduceFull(IParallelFlux <T> source, Func <T, T, T> reducer)
 {
     this.source  = source;
     this.reducer = reducer;
 }
 internal ParallelUnorderedMap(IParallelFlux <T> source, Func <T, R> mapper)
 {
     this.source = source;
     this.mapper = mapper;
 }
 /// <summary>
 /// Perform a fluent transformation to a value via a converter function which
 /// receives this ParallelPublisher.
 /// </summary>
 /// <typeparam name="T">the value type</typeparam>
 /// <typeparam name="R">The result type</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="converter">the converter function from IParallelPublisher to some type</param>
 /// <returns>the value returned by the converter function</returns>
 public static R As <T, R>(this IParallelFlux <T> source, Func <IParallelFlux <T>, R> converter)
 {
     return(converter(source));
 }
 /// <summary>
 /// Exposes the 'rails' as individual GroupedPublisher instances, keyed by the rail index (zero based).
 /// </summary>
 /// <remarks>
 /// Each group can be consumed only once; requests and cancellation compose through. Note
 /// that cancelling only one rail may result in undefined behavior.
 /// </remarks>
 /// <typeparam name="T">The value type.</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <returns>The new IFlux instance with the inner IGroupedFlux instances.</returns>
 public static IFlux <IGroupedFlux <int, T> > Groups <T>(this IParallelFlux <T> source)
 {
     return(new ParallelGroups <T>(source));
 }
 internal ParallelSortedJoin(IParallelFlux <IList <T> > source, IComparer <T> comparer)
 {
     this.source   = source;
     this.comparer = comparer;
 }
 /// <summary>
 /// Generates and flattens Publishers on each 'rail', optionally delaying errors,
 /// having a total number of simultaneous subscriptions to the inner Publishers
 /// and using the given prefetch amount for the inner Publishers.
 /// </summary>
 /// <typeparam name="T">the value type</typeparam>
 /// <typeparam name="R">The result type</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="mapper">the function to map each rail's value into a IPublisher</param>
 /// <param name="maxConcurrency">the maximum number of simultaneous subscriptions to the generated inner IPublishers</param>
 /// <param name="prefetch">the number of items to prefetch from each inner IPublisher</param>
 /// <param name="delayErrors">should the errors from the main and the inner sources delayed till everybody terminates?</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <R> FlatMap <T, R>(this IParallelFlux <T> source, Func <T, IPublisher <R> > mapper, int maxConcurrency, int prefetch, bool delayErrors = false)
 {
     // TODO implement FlatMap
     throw new NotImplementedException();
 }
Ejemplo n.º 29
0
 internal ParallelGroups(IParallelFlux <T> source)
 {
     this.source = source;
 }
 /// <summary>
 /// Generates and concatenates Publishers on each 'rail', signalling errors immediately
 /// and using the given prefetch amount for generating Publishers upfront.
 /// </summary>
 /// <typeparam name="T">the value type</typeparam>
 /// <typeparam name="R">The result type</typeparam>
 /// <param name="source">The source IParallelPublisher instance.</param>
 /// <param name="mapper">the function to map each rail's value into a IPublisher</param>
 /// <param name="errorMode">the error handling, i.e., when to report errors from the main
 /// source and the inner Publishers (immediate, boundary, end)</param>
 /// <returns>The new IParallelFlux instance</returns>
 public static IParallelFlux <R> ConcatMap <T, R>(this IParallelFlux <T> source, Func <T, IPublisher <R> > mapper, ConcatErrorMode errorMode = ConcatErrorMode.Immediate)
 {
     return(ConcatMap(source, mapper, 2, errorMode));
 }