示例#1
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TOld"></typeparam>
        /// <typeparam name="TNew"></typeparam>
        /// <typeparam name="TField1"></typeparam>
        /// <typeparam name="TField2"></typeparam>
        /// <param name="source"></param>
        /// <param name="initializer"></param>
        /// <param name="fieldSelector1"></param>
        /// <param name="fieldInitializer1"></param>
        /// <param name="fieldSelector2"></param>
        /// <param name="fieldInitializer2"></param>
        /// <returns></returns>
        public static IStreamable <TKey, TNew> Select <TKey, TOld, TNew, TField1, TField2>(
            this IStreamable <TKey, TOld> source,
            Expression <Func <TNew> > initializer,
            Expression <Func <TNew, TField1> > fieldSelector1,
            Expression <Func <TOld, TField1> > fieldInitializer1,
            Expression <Func <TNew, TField2> > fieldSelector2,
            Expression <Func <TOld, TField2> > fieldInitializer2) where TNew : new()
        {
            Invariant.IsNotNull(source, nameof(source));
            Invariant.IsNotNull(initializer, nameof(initializer));

            // Validate that the field selector formulas are actually selector expressions
            if (fieldSelector1.Body.NodeType != ExpressionType.MemberAccess)
            {
                throw new ArgumentException("Unable to determine destination field name from selector expression - expected a member selection expression.", nameof(fieldSelector1));
            }
            if (fieldSelector2.Body.NodeType != ExpressionType.MemberAccess)
            {
                throw new ArgumentException("Unable to determine destination field name from selector expression - expected a member selection expression.", nameof(fieldSelector2));
            }

            if (!(initializer.Body is NewExpression newExpression))
            {
                throw new ArgumentException("Initializer must return a constructor expression.", nameof(initializer));
            }

            return(source.Select(CreateAdjustColumnsExpression <TOld, TNew>(
                                     new Dictionary <string, LambdaExpression>
            {
                { ((MemberExpression)(fieldSelector1.Body)).Member.Name, fieldInitializer1 },
                { ((MemberExpression)(fieldSelector2.Body)).Member.Name, fieldInitializer2 },
            },
                                     newExpression)));
        }
示例#2
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));
            }
        }
示例#3
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TOld"></typeparam>
        /// <typeparam name="TNew"></typeparam>
        /// <param name="source"></param>
        /// <param name="initializer"></param>
        /// <param name="newColumnFormulas"></param>
        /// <returns></returns>
        public static IStreamable <TKey, TNew> Select <TKey, TOld, TNew>(
            this IStreamable <TKey, TOld> source,
            Expression <Func <TNew> > initializer,
            IDictionary <string, Expression <Func <TOld, object> > > newColumnFormulas = null) where TNew : new()
        {
            Invariant.IsNotNull(source, nameof(source));
            Invariant.IsNotNull(initializer, nameof(initializer));

            // Validate that the dictionary parameter references proper fields
            if (newColumnFormulas == null)
            {
                newColumnFormulas = new Dictionary <string, Expression <Func <TOld, object> > >();
            }
            Type newType = typeof(TNew);

            foreach (var pair in newColumnFormulas)
            {
                if (newType.GetTypeInfo().GetMember(pair.Key).Length == 0)
                {
                    throw new ArgumentException("Dictionary keys must refer to valid members of the destination type", nameof(newColumnFormulas));
                }
            }

            if (!(initializer.Body is NewExpression newExpression))
            {
                throw new ArgumentException("Initializer must return a constructor expression.", nameof(initializer));
            }

            return(source.Select(CreateAdjustColumnsExpression <TOld, TNew>(
                                     newColumnFormulas.ToDictionary(o => o.Key, o => (LambdaExpression)o.Value),
                                     newExpression)));
        }