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