/// <summary> /// Sample stream by clock signal with a relative time interval window. /// </summary> /// <typeparam name="T">Type of source/output messages.</typeparam> /// <typeparam name="TClock">Type of clock signal messages.</typeparam> /// <param name="source">Source stream.</param> /// <param name="clock">Clock signal stream.</param> /// <param name="matchWindow">Relative time interval window in which to sample.</param> /// <param name="policy">Delivery policy.</param> /// <returns>Output stream.</returns> public static IProducer <T> Sample <T, TClock>( this IProducer <T> source, IProducer <TClock> clock, RelativeTimeInterval matchWindow, DeliveryPolicy policy = null) { return(Sample(source, clock, Match.Best <T>(matchWindow), policy)); }
/// <summary> /// Sample stream by interval with a relative time interval window. /// </summary> /// <typeparam name="T">Type of source/output messages.</typeparam> /// <param name="source">Source stream.</param> /// <param name="samplingInterval">Interval at which to sample.</param> /// <param name="matchWindow">Relative time interval window in which to sample.</param> /// <param name="deliveryPolicy">An optional delivery policy.</param> /// <returns>Output stream.</returns> public static IProducer <T> Sample <T>( this IProducer <T> source, TimeSpan samplingInterval, RelativeTimeInterval matchWindow, DeliveryPolicy deliveryPolicy = null) { return(Sample(source, samplingInterval, Match.Best <T>(matchWindow), deliveryPolicy)); }
/// <summary> /// Samples a stream at interpolation points given by a clock stream, by selecting the nearest /// message within a relative time interval to the interpolation point. /// </summary> /// <typeparam name="T">Type of source and output messages.</typeparam> /// <typeparam name="TClock">Type of messages on the clock stream.</typeparam> /// <param name="source">Source stream.</param> /// <param name="clock">Clock stream that dictates the interpolation points.</param> /// <param name="relativeTimeInterval">The relative time interval within which to search for the nearest message.</param> /// <param name="sourceDeliveryPolicy">An optional delivery policy for the source stream.</param> /// <param name="clockDeliveryPolicy">An optional delivery policy for the clock stream.</param> /// <returns>Sampled stream.</returns> public static IProducer <T> Sample <T, TClock>( this IProducer <T> source, IProducer <TClock> clock, RelativeTimeInterval relativeTimeInterval, DeliveryPolicy sourceDeliveryPolicy = null, DeliveryPolicy clockDeliveryPolicy = null) { return(source.Interpolate(clock, Reproducible.Nearest <T>(relativeTimeInterval), sourceDeliveryPolicy, clockDeliveryPolicy)); }
/// <summary> /// Samples a stream at interpolation points given by a clock stream, by selecting the nearest /// message within a relative time interval to the interpolation point. /// </summary> /// <typeparam name="T">Type of source and output messages.</typeparam> /// <typeparam name="TClock">Type of messages on the clock stream.</typeparam> /// <param name="source">Source stream.</param> /// <param name="clock">Clock stream that dictates the interpolation points.</param> /// <param name="relativeTimeInterval">The relative time interval within which to search for the nearest message. /// If the parameter is not specified the <see cref="RelativeTimeInterval.Infinite"/>relative time interval is /// used,resulting in sampling the nearest point to the clock signal on the source stream.</param> /// <param name="sourceDeliveryPolicy">An optional delivery policy for the source stream.</param> /// <param name="clockDeliveryPolicy">An optional delivery policy for the clock stream.</param> /// <param name="name">An optional name for the stream operator.</param> /// <returns>Sampled stream.</returns> public static IProducer <T> Sample <T, TClock>( this IProducer <T> source, IProducer <TClock> clock, RelativeTimeInterval relativeTimeInterval = null, DeliveryPolicy <T> sourceDeliveryPolicy = null, DeliveryPolicy <TClock> clockDeliveryPolicy = null, string name = nameof(Sample)) { relativeTimeInterval ??= RelativeTimeInterval.Infinite; return(source.Interpolate(clock, Reproducible.Nearest <T>(relativeTimeInterval), sourceDeliveryPolicy, clockDeliveryPolicy, name)); }
/// <summary> /// Process windows of messages by relative time interval. /// </summary> /// <typeparam name="TSource">Type of source messages.</typeparam> /// <typeparam name="TOutput">Type of output messages.</typeparam> /// <param name="source">Source stream of messages.</param> /// <param name="relativeTimeInterval">The relative time interval over which to gather messages.</param> /// <param name="selector">Selector function.</param> /// <param name="deliveryPolicy">An optional delivery policy.</param> /// <param name="name">An optional name for the stream operator.</param> /// <returns>Output stream.</returns> public static IProducer <TOutput> Window <TSource, TOutput>( this IProducer <TSource> source, RelativeTimeInterval relativeTimeInterval, Func <IEnumerable <Message <TSource> >, TOutput> selector, DeliveryPolicy <TSource> deliveryPolicy = null, string name = nameof(Window)) { var window = new RelativeTimeWindow <TSource, TOutput>(source.Out.Pipeline, relativeTimeInterval, selector, name); return(PipeTo(source, window, deliveryPolicy)); }
/// <summary> /// Sample a stream at a given sampling interval, by selecting the nearest message /// within a relative time interval to the interpolation point. /// </summary> /// <typeparam name="T">Type of source (and output) messages.</typeparam> /// <param name="source">Source stream.</param> /// <param name="samplingInterval">Interval at which to apply the interpolator.</param> /// <param name="relativeTimeInterval">The relative time interval within which to search for the nearest message.</param> /// <param name="alignmentDateTime">If non-null, this parameter specifies a time to align the sampling messages with. If the paramater /// is non-null, the messages will have originating times that align with (i.e., are an integral number of intervals away from) the /// specified alignment time.</param> /// <param name="deliveryPolicy">An optional delivery policy.</param> /// <returns>Sampled stream.</returns> public static IProducer <T> Sample <T>( this IProducer <T> source, TimeSpan samplingInterval, RelativeTimeInterval relativeTimeInterval, DateTime?alignmentDateTime = null, DeliveryPolicy deliveryPolicy = null) { return(source.Interpolate( samplingInterval, Reproducible.Nearest <T>(relativeTimeInterval), alignmentDateTime, deliveryPolicy)); }
/// <summary> /// Sample a stream at a given sampling interval, by selecting the nearest message /// within a relative time interval to the interpolation point. /// </summary> /// <typeparam name="T">Type of source (and output) messages.</typeparam> /// <param name="source">Source stream.</param> /// <param name="samplingInterval">Interval at which to apply the interpolator.</param> /// <param name="relativeTimeInterval">The relative time interval within which to search for the nearest message. /// If the parameter is not specified the <see cref="RelativeTimeInterval.Infinite"/>relative time interval is /// used,resulting in sampling the nearest point to the clock signal on the source stream.</param> /// <param name="alignmentDateTime">If non-null, this parameter specifies a time to align the sampling messages with. If the parameter /// is non-null, the messages will have originating times that align with (i.e., are an integral number of intervals away from) the /// specified alignment time.</param> /// <param name="deliveryPolicy">An optional delivery policy.</param> /// <param name="name">An optional name for the stream operator.</param> /// <returns>Sampled stream.</returns> public static IProducer <T> Sample <T>( this IProducer <T> source, TimeSpan samplingInterval, RelativeTimeInterval relativeTimeInterval = null, DateTime?alignmentDateTime = null, DeliveryPolicy <T> deliveryPolicy = null, string name = nameof(Sample)) { relativeTimeInterval ??= RelativeTimeInterval.Infinite; return(source.Interpolate( samplingInterval, Reproducible.Nearest <T>(relativeTimeInterval), alignmentDateTime, deliveryPolicy, name)); }
/// <summary> /// Get a window of messages relative to the current message. /// </summary> /// <typeparam name="T">Type of source messages.</typeparam> /// <param name="source">Source stream of messages.</param> /// <param name="relativeTimeInterval">The relative time interval over which to gather messages.</param> /// <param name="policy">Delivery policy.</param> /// <returns>Output stream.</returns> public static IProducer <IEnumerable <Message <T> > > Window <T>(this IProducer <T> source, RelativeTimeInterval relativeTimeInterval, DeliveryPolicy policy = null) { var window = new Window <T>(source.Out.Pipeline, relativeTimeInterval); source.PipeTo(window.In, policy ?? DeliveryPolicy.Immediate); return(window.Out); }
/// <summary> /// Get windows of messages by relative time interval. /// </summary> /// <typeparam name="T">Type of source messages.</typeparam> /// <param name="source">Source stream of messages.</param> /// <param name="relativeTimeInterval">The relative time interval over which to gather messages.</param> /// <param name="deliveryPolicy">An optional delivery policy.</param> /// <returns>Output stream.</returns> public static IProducer <IEnumerable <T> > Window <T>(this IProducer <T> source, RelativeTimeInterval relativeTimeInterval, DeliveryPolicy deliveryPolicy = null) { return(Window(source, relativeTimeInterval, GetMessageData, deliveryPolicy)); }
/// <summary> /// Reproducible interpolator that selects the value with an originating time nearest to the interpolation time, /// within a specified <see cref="RelativeTimeInterval"/>, or default if no such value is found. /// </summary> /// <typeparam name="T">The message type.</typeparam> /// <param name="relativeTimeInterval">The relative time interval within which to search for the nearest message.</param> /// <param name="defaultValue">An optional default value to use.</param> /// <returns>The reproducible interpolator.</returns> public static ReproducibleInterpolator <T> NearestOrDefault <T>(RelativeTimeInterval relativeTimeInterval, T defaultValue = default) { return(new NearestReproducibleInterpolator <T>(relativeTimeInterval, true, defaultValue)); }
/// <inheritdoc/> public bool Equals(RelativeTimeInterval other) { return ((this.LeftEndpoint.Point, this.LeftEndpoint.Inclusive, this.LeftEndpoint.Bounded, this.RightEndpoint.Point, this.RightEndpoint.Inclusive, this.RightEndpoint.Bounded) == (other.LeftEndpoint.Point, other.LeftEndpoint.Inclusive, other.LeftEndpoint.Bounded, other.RightEndpoint.Point, other.RightEndpoint.Inclusive, other.RightEndpoint.Bounded)); }
/// <summary> /// Get windows of messages by relative time interval. /// </summary> /// <typeparam name="TSource">Type of source messages.</typeparam> /// <param name="source">Source stream of messages.</param> /// <param name="relativeTimeInterval">The relative time interval over which to gather messages.</param> /// <param name="deliveryPolicy">An optional delivery policy.</param> /// <returns>Output stream.</returns> public static IProducer <TSource[]> Window <TSource>(this IProducer <TSource> source, RelativeTimeInterval relativeTimeInterval, DeliveryPolicy <TSource> deliveryPolicy = null) { return(Window(source, relativeTimeInterval, GetMessageData, deliveryPolicy)); }
/// <summary> /// Reproducible interpolator that selects the value with an originating time nearest to the interpolation time, /// within a specified <see cref="RelativeTimeInterval"/>. /// </summary> /// <typeparam name="T">The message type.</typeparam> /// <param name="relativeTimeInterval">The relative time interval within which to search for the nearest message.</param> /// <returns>The reproducible interpolator.</returns> public static ReproducibleInterpolator <T> Nearest <T>(RelativeTimeInterval relativeTimeInterval) { return(new NearestReproducibleInterpolator <T>(relativeTimeInterval, false)); }
/// <summary> /// Process windows of messages by relative time interval. /// </summary> /// <typeparam name="T">Type of source messages.</typeparam> /// <typeparam name="U">Type of output messages.</typeparam> /// <param name="source">Source stream of messages.</param> /// <param name="relativeTimeInterval">The relative time interval over which to gather messages.</param> /// <param name="selector">Selector function.</param> /// <param name="deliveryPolicy">An optional delivery policy.</param> /// <returns>Output stream.</returns> public static IProducer <U> Window <T, U>(this IProducer <T> source, RelativeTimeInterval relativeTimeInterval, Func <IEnumerable <Message <T> >, U> selector, DeliveryPolicy deliveryPolicy = null) { var window = new RelativeTimeWindow <T, U>(source.Out.Pipeline, relativeTimeInterval, selector); return(PipeTo(source, window, deliveryPolicy)); }
private static Func <DateTime, IEnumerable <Message <T> >, bool, MatchResult <T> > NearestValueFn <T>(RelativeTimeInterval window, bool requireNextValue, bool orDefault) { return((DateTime matchTime, IEnumerable <Message <T> > messages, bool final) => { var count = messages.Count(); // If no messages available, signal insufficient data if (count == 0) { return MatchResult <T> .InsufficientData(DateTime.MinValue); } Message <T> bestMatch = default(Message <T>); TimeSpan bestDistance = TimeSpan.MaxValue; DateTime upperBound = (window.Right < TimeSpan.Zero) ? matchTime + window.Right : matchTime; int i = 0; foreach (var message in messages) { TimeSpan delta = message.OriginatingTime - matchTime; TimeSpan distance = delta.Duration(); // Only consider messages that occur within the lookback window. if (delta >= window.Left) { // We stop searching either when we reach a message that is beyond the lookahead // window or when the distance (absolute delta) exceeds the best distance. if ((delta > window.Right) || (distance > bestDistance)) { break; } // keep track of the best match so far and its delta bestMatch = message; bestDistance = distance; } i++; } // If bestDistance is anything other than MaxValue, we found a nearest matching message. if (bestDistance < TimeSpan.MaxValue) { // Check if we need to satisfy additional conditions // if the best match is the last available message if (requireNextValue && (i == count) && !final) { // We need to guarantee that bestMatch is indeed the best match. If it has an // originating time that occurs at or after the match time (or the // upper boundary of the window, whichever occurs earlier in time), then this // must be true as we will never see a closer match in any of the messages // that may arrive in the future. However if it is before the match time, // then we will need to see a message beyond the match/window time to // be sure that there is no closer match (i.e. as long as we haven't seen a // message at or past the match/window time, it is always possible that // a future message will show up with a distance that is closer to the // match time. if (bestMatch.OriginatingTime < upperBound) { // Signal insufficient data to continue waiting for more messages. return MatchResult <T> .InsufficientData(DateTime.MinValue); } } // Return the matching message value as the matched result. // All messages before the matching message are obsolete. return MatchResult <T> .Create(bestMatch.Data, bestMatch.OriginatingTime); } var last = messages.Last(); if (last.OriginatingTime >= upperBound) { // If no nearest match was found and the match time occurs before or coincident with // the last message, then no future message will alter the result and we can therefore conclude // that no matched value exists at that time. // In that case, either return DoesNotExist or the default value (according to the parameter) return orDefault ? MatchResult <T> .Create(default(T), upperBound) : MatchResult <T> .DoesNotExist(upperBound); } else { // Otherwise signal insufficient data. return MatchResult <T> .InsufficientData(DateTime.MinValue); } }); }
/// <summary> /// Match that takes the value with an originating time nearest to the match /// time, within a window which looks both forward and backward in time. /// </summary> /// <typeparam name="T">The message type.</typeparam> /// <param name="window"> /// The window within which to search for the message that is closest to the match time. /// May extend up to TimeSpan.MinValue and TimeSpan.MaxValue relative to the match time. /// </param> /// <remarks> /// The next value at or after the match time is required for a matched value to be created. /// This ensures correctness regardless of execution timing. /// </remarks> /// <returns>The interpolator for the match.</returns> public static Interpolator <T> Best <T>(RelativeTimeInterval window) { return(NearestValue <T>(window, true, false)); }
/// <summary> /// Initializes a new instance of the <see cref="TimeInterval"/> class. /// </summary> /// <param name="origin">Origin around which interval is to be created</param> /// <param name="relative">Time span interval specifying relative endpoints, bounding and inclusivity.</param> public TimeInterval(DateTime origin, RelativeTimeInterval relative) : base( relative.LeftEndpoint.Bounded ? new IntervalEndpoint <DateTime>(origin + relative.Left, relative.LeftEndpoint.Inclusive) : new IntervalEndpoint <DateTime>(DateTime.MinValue), relative.RightEndpoint.Bounded ? new IntervalEndpoint <DateTime>(origin + relative.Right, relative.RightEndpoint.Inclusive) : new IntervalEndpoint <DateTime>(DateTime.MaxValue)) { }
/// <summary> /// Get windows of messages by relative time interval. /// </summary> /// <typeparam name="TSource">Type of source messages.</typeparam> /// <param name="source">Source stream of messages.</param> /// <param name="relativeTimeInterval">The relative time interval over which to gather messages.</param> /// <param name="deliveryPolicy">An optional delivery policy.</param> /// <param name="name">An optional name for the stream operator.</param> /// <returns>Output stream.</returns> public static IProducer <TSource[]> Window <TSource>( this IProducer <TSource> source, RelativeTimeInterval relativeTimeInterval, DeliveryPolicy <TSource> deliveryPolicy = null, string name = nameof(Window)) => Window(source, relativeTimeInterval, GetMessageData, deliveryPolicy, name);
/// <summary> /// Match that takes the value with an originating time nearest to the match /// time (see remarks), within a window which looks both forward and backward in time. /// If no message is available in that specified window, it returns the default(T) value. /// </summary> /// <typeparam name="T">The message type.</typeparam> /// <param name="window"> /// The window within which to search for the message that is closest to the match time. /// May extend up to TimeSpan.MinValue and TimeSpan.MaxValue relative to the match time. /// </param> /// <remarks> /// The next value at or after the match time *is not* required for a matched value to be created. /// This *does not* ensure correctness regardless of execution timing. /// </remarks> /// <returns>The interpolator for the match.</returns> public static Interpolator <T> AnyOrDefault <T>(RelativeTimeInterval window) { return(NearestValue <T>(window, false, true)); }
/// <summary> /// Initializes a new instance of the <see cref="Interpolator{T}"/> class. /// </summary> /// <param name="match">Function producing match results over a message window.</param> /// <param name="window">Message window interval.</param> /// <param name="requireNextValue">Whether the next value is required as confirmation of proper match.</param> /// <param name="orDefault">Whether to return a default value upon failure to find a suitable match.</param> public Interpolator(Func <DateTime, IEnumerable <Message <T> >, bool, MatchResult <T> > match, RelativeTimeInterval window, bool requireNextValue, bool orDefault) { this.Window = window; this.RequireNextValue = requireNextValue; this.OrDefault = orDefault; this.matchFn = match; }
/// <summary> /// Greedy interpolator that selects the available value with an originating time nearest to the interpolation time, /// within a specified <see cref="RelativeTimeInterval"/>. /// </summary> /// <typeparam name="T">The message type.</typeparam> /// <param name="relativeTimeInterval">The relative time interval within which to search for the nearest message.</param> /// <returns>The greedy interpolator.</returns> public static GreedyInterpolator <T> Nearest <T>(RelativeTimeInterval relativeTimeInterval) { return(new NearestAvailableInterpolator <T>(relativeTimeInterval, false)); }
/// <summary> /// Process windows of messages by relative time interval. /// </summary> /// <typeparam name="TSource">Type of source messages.</typeparam> /// <typeparam name="TOutput">Type of output messages.</typeparam> /// <param name="source">Source stream of messages.</param> /// <param name="relativeTimeInterval">The relative time interval over which to gather messages.</param> /// <param name="selector">Selector function.</param> /// <param name="waitForCompleteWindow">Whether to wait for the full window before output.</param> /// <param name="deliveryPolicy">An optional delivery policy.</param> /// <returns>Output stream.</returns> public static IProducer <TOutput> Window <TSource, TOutput>(this IProducer <TSource> source, RelativeTimeInterval relativeTimeInterval, Func <IEnumerable <Message <TSource> >, TOutput> selector, bool waitForCompleteWindow, DeliveryPolicy <TSource> deliveryPolicy = null) { var window = new RelativeTimeWindow <TSource, TOutput>(source.Out.Pipeline, relativeTimeInterval, selector, waitForCompleteWindow); return(PipeTo(source, window, deliveryPolicy)); }
/// <summary> /// Greedy interpolator that selects the available value with an originating time nearest to the interpolation time, /// within a specified <see cref="RelativeTimeInterval"/>, or default if no such value is found. /// </summary> /// <typeparam name="T">The message type.</typeparam> /// <param name="relativeTimeInterval">The relative time interval within which to search for the nearest message.</param> /// <param name="defaultValue">An optional default value to use.</param> /// <returns>The greedy interpolator.</returns> public static GreedyInterpolator <T> NearestOrDefault <T>(RelativeTimeInterval relativeTimeInterval, T defaultValue = default) { return(new NearestAvailableInterpolator <T>(relativeTimeInterval, true, defaultValue)); }
private static Interpolator <T> NearestValue <T>(RelativeTimeInterval window, bool requireNextValue, bool orDefault) { return(new Interpolator <T>(NearestValueFn <T>(window, requireNextValue, orDefault), window, requireNextValue, orDefault)); }