Ejemplo n.º 1
0
        /// <summary>
        /// Adjusts the lifetime of incoming events to implement, when used in combination with aggregates, hopping windows. In this implementation each incoming
        /// event results in a single outgoing event, which means that subsequent aggregates only produce output when the input changes. For instance, if a single
        /// point event is received and the windowSize, period, and offset are 100, 2, and 0 respectively, a single aggregate output is produced with a lifetime of
        /// 100 ticks.
        /// </summary>
        /// <typeparam name="TKey">Type of (mapping) key in the stream</typeparam>
        /// <typeparam name="TPayload">Type of payload in the stream</typeparam>
        /// <param name="source">Input stream</param>
        /// <param name="windowSize">Window size</param>
        /// <param name="period">Period (or hop size)</param>
        /// <param name="offset">Offset from the start of time</param>
        /// <returns>Result (output) stream</returns>
        public static IStreamable <TKey, TPayload> HoppingWindowLifetime <TKey, TPayload>(
            this IStreamable <TKey, TPayload> source,
            long windowSize,
            long period,
            long offset = 0)
        {
            if (period > windowSize)
            {
                return(source
                       .Select((vs, e) => new { StartTime = vs, Payload = e })
                       .Where(x => (((x.StartTime + period - offset) % period) > (period - windowSize)) || ((x.StartTime + period - offset) % period == 0))
                       .Select(x => x.Payload)
                       .AlterEventLifetime(vs => AdjustStartTime(vs, offset, period), windowSize)
                       .SetProperty().IsConstantHop(true, period, offset));
            }

            if (windowSize % period == 0)
            {
                return(source.AlterEventLifetime(vs => AdjustStartTime(vs, offset, period), windowSize)
                       .SetProperty().IsConstantHop(true, period, offset));
            }
            else
            {
                return(source.AlterEventLifetime(
                           vs => AdjustStartTime(vs, offset, period),
                           vs => AdjustStartTime(vs + windowSize, offset, period) - AdjustStartTime(vs, offset, period))
                       .SetProperty().IsConstantHop(true, period, offset));
            }
        }