/// <summary> /// Filters the stream using the specified predicate /// </summary> /// <typeparam name="TObject">The type of the object.</typeparam> /// <typeparam name="TKey">The type of the key.</typeparam> /// <param name="source">The source.</param> /// <param name="filter">The filter.</param> /// <param name="parallelisationOptions">The parallelisation options.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException">source</exception> public static IObservable <IChangeSet <TObject, TKey> > Filter <TObject, TKey>(this IObservable <IChangeSet <TObject, TKey> > source, Func <TObject, bool> filter, ParallelisationOptions parallelisationOptions) { if (source == null) { throw new ArgumentNullException("source"); } if (filter == null) { return(source.Clone()); } return(Observable.Create <IChangeSet <TObject, TKey> >( observer => { var filterer = new PLinqFilteredUpdater <TObject, TKey>(filter, parallelisationOptions); return source .Select(filterer.Update) .NotEmpty() .SubscribeSafe(observer); })); }
/// <summary> /// Subscribes to each item when it is added to the stream and unsubcribes when it is removed. All items will be unsubscribed when the stream is disposed /// </summary> /// <typeparam name="TObject">The type of the object.</typeparam> /// <typeparam name="TKey">The type of the key.</typeparam> /// <param name="source">The source.</param> /// <param name="subscriptionFactory">The subsription function</param> /// <param name="parallelisationOptions">The parallelisation options.</param> /// <returns></returns> /// <exception cref="System.ArgumentNullException">source /// or /// subscriptionFactory</exception> /// <remarks> /// Subscribes to each item when it is added or updates and unsubcribes when it is removed /// </remarks> public static IObservable <IChangeSet <TObject, TKey> > SubscribeMany <TObject, TKey>(this IObservable <IChangeSet <TObject, TKey> > source, Func <TObject, TKey, IDisposable> subscriptionFactory, ParallelisationOptions parallelisationOptions) { if (source == null) { throw new ArgumentNullException("source"); } if (subscriptionFactory == null) { throw new ArgumentNullException("subscriptionFactory"); } if (parallelisationOptions == null) { throw new ArgumentNullException("parallelisationOptions"); } return(Observable.Create <IChangeSet <TObject, TKey> >( observer => { var published = source.Publish(); var subscriptions = published .Transform((t, k) => new SubscriptionContainer <TObject, TKey>(t, k, subscriptionFactory), parallelisationOptions) .DisposeMany() .Subscribe(); var result = published.SubscribeSafe(observer); var connected = published.Connect(); return Disposable.Create(() => { connected.Dispose(); subscriptions.Dispose(); result.Dispose(); }); })); }
/// <summary> /// Projects each update item to a new form using the specified transform function, /// providing an error handling action to safely handle transform errors without killing the stream. /// </summary> /// <typeparam name="TDestination">The type of the destination.</typeparam> /// <typeparam name="TSource">The type of the source.</typeparam> /// <typeparam name="TKey">The type of the key.</typeparam> /// <param name="source">The source.</param> /// <param name="transformFactory">The transform factory.</param> /// <param name="errorHandler">Provides the option to safely handle errors without killing the stream. /// If not specified the stream will terminate as per rx convention. /// </param> /// <param name="parallelisationOptions">The parallelisation options to be used on the transforms</param> /// <returns> /// A transformed update collection /// </returns> /// <exception cref="System.ArgumentNullException">source /// or /// transformFactory</exception> public static IObservable <IChangeSet <TDestination, TKey> > TransformSafe <TDestination, TSource, TKey>(this IObservable <IChangeSet <TSource, TKey> > source, Func <TSource, TKey, TDestination> transformFactory, Action <Error <TSource, TKey> > errorHandler, ParallelisationOptions parallelisationOptions) { if (source == null) { throw new ArgumentNullException("source"); } if (transformFactory == null) { throw new ArgumentNullException("transformFactory"); } if (errorHandler == null) { throw new ArgumentNullException("errorHandler"); } return(Observable.Create <IChangeSet <TDestination, TKey> >( observer => { var transformer = new PlinqTransformer <TDestination, TSource, TKey>(parallelisationOptions, errorHandler); return source .Select(updates => transformer.Transform(updates, transformFactory)) .NotEmpty() .SubscribeSafe(observer); })); }
internal static IEnumerable <T> Parallelise <T>(this IEnumerable <T> source, ParallelisationOptions option) { switch (option.Type) { case ParallelType.Parallelise: { var parallelise = source as T[] ?? source.ToArray(); if (option.Threshold >= 0 && parallelise.Length >= option.Threshold) { return(parallelise.AsParallel()); } return(parallelise); } case ParallelType.Ordered: { var parallelise = source as T[] ?? source.ToArray(); if (option.Threshold >= 0 && parallelise.Length >= option.Threshold) { return(parallelise.AsParallel().AsOrdered()); } return(parallelise); } default: return(source); } }
internal static ParallelQuery <KeyValuePair <TKey, TObject> > Parallelise <TObject, TKey>(this IEnumerable <KeyValuePair <TKey, TObject> > source, ParallelisationOptions option) { switch (option.Type) { case ParallelType.Parallelise: return(source.AsParallel()); case ParallelType.Ordered: return(source.AsParallel().AsOrdered()); default: throw new ArgumentException("Should not parallelise! Call ShouldParallelise() first"); } }
internal static bool ShouldParallelise <TObject, TKey>(this IEnumerable <KeyValuePair <TKey, TObject> > source, ParallelisationOptions option) { return((option.Type == ParallelType.Parallelise || option.Type == ParallelType.Ordered) && (option.Threshold >= 0 && source.Skip(option.Threshold).Any())); }
internal static bool ShouldParallelise <TObject, TKey>(this IChangeSet <TObject, TKey> source, ParallelisationOptions option) { return((option.Type == ParallelType.Parallelise || option.Type == ParallelType.Ordered) && (option.Threshold >= 0 && source.Count >= option.Threshold)); }