Esempio n. 1
0
        /// <summary>
        /// Visits a <see cref="TakeOperator" /> node.
        /// </summary>
        /// <param name="op">Node to visit.</param>
        /// <returns>Result of visiting the node.</returns>
        protected internal override QueryOperator VisitTake(TakeOperator op)
        {
            var src   = VisitAndConvert <MonadMember>(op.Source);
            var count = Visit(op.Count);

            if (src != op.Source || count != op.Count)
            {
                return(MakeTake(op, src, count));
            }

            return(op);
        }
        /// <summary>
        /// Visits a <see cref="TakeOperator" /> operator and coalesces it with any possible child operators.
        /// </summary>
        /// <param name="op">The operator to visit.</param>
        /// <returns>The coalesced operator.</returns>
        protected internal override QueryOperator VisitTake(TakeOperator op)
        {
            var source = VisitAndConvert <MonadMember>(op.Source);
            var count  = Visit(op.Count);

            // Take coalescing
            var srcOperator = source.QueryNodeType == QueryNodeType.Operator ? (QueryOperator)source : null;
            var srcTake     = srcOperator != null && srcOperator.NodeType == OperatorType.Take ? (TakeOperator)srcOperator : null;

            if (srcTake != null)
            {
                if (TryExtractNullaryLambdaBody(count, out Expression count1) &&
                    count1.NodeType == ExpressionType.Constant &&
                    TryExtractNullaryLambdaBody(srcTake.Count, out Expression count2) &&
                    count2.NodeType == ExpressionType.Constant)
                {
                    var c1 = (int)((ConstantExpression)count1).Value;
                    var c2 = (int)((ConstantExpression)count2).Value;

                    return(op.QueryExpressionFactory.Take(
                               op.ElementType,
                               srcTake.Source,
                               DefaultQueryExpressionFactory.Instance.LambdaAbstraction(
                                   Expression.Lambda(
                                       Expression.Constant(
                                           Math.Min(c1, c2)
                                           )
                                       ),
                                   Array.Empty <QueryTree>()
                                   )
                               ));
                }

                var p1 = Expression.Parameter(typeof(int));
                var p2 = Expression.Parameter(typeof(int));
                return(op.QueryExpressionFactory.Take(
                           op.ElementType,
                           srcTake.Source,
                           DefaultQueryExpressionFactory.Instance.LambdaAbstraction(
                               Expression.Lambda(
                                   Expression.Call(s_Min, p1, p2),
                                   p1,
                                   p2
                                   ),
                               new[] { srcTake.Count, count }
                               )
                           ));
            }

            return(op.Update(source, count));
        }
Esempio n. 3
0
 /// <summary>
 /// Makes a <see cref="TakeOperator" /> with the given children.
 /// </summary>
 /// <param name="node">Original query expression.</param>
 /// <param name="source">Source query expression.</param>
 /// <param name="count">Count query expression.</param>
 /// <returns>Representation of the original query expression.</returns>
 protected sealed override QueryOperator MakeTake(TakeOperator node, MonadMember source, QueryTree count)
 {
     return(node.QueryExpressionFactory.Take(node.ElementType, source, count));
 }
Esempio n. 4
0
 /// <summary>
 /// Creates a textual representation of the TakeOperator with the given children.
 /// </summary>
 /// <param name="node">Original query expression.</param>
 /// <param name="source">Source query expression.</param>
 /// <param name="count">Count query expression.</param>
 /// <returns>Representation of the original query expression.</returns>
 protected override string MakeTake(TakeOperator node, string source, string count)
 {
     return(string.Format(CultureInfo.InvariantCulture, "@Take({0}, {1})", source, count));
 }
Esempio n. 5
0
 /// <summary>
 /// Makes a <see cref="TakeOperator" /> with the given children.
 /// </summary>
 /// <param name="node">Original query expression.</param>
 /// <param name="source">Source query expression.</param>
 /// <param name="elementType">Element type for the resulting operator.</param>
 /// <param name="count">Count query expression.</param>
 /// <returns>Representation of the original query expression.</returns>
 protected virtual QueryOperator MakeTake(TakeOperator node, Type elementType, MonadMember source, QueryTree count)
 {
     return(node.QueryExpressionFactory.Take(elementType, source, count));
 }