public OrderByProcessorOrderedLimitForge(
     OrderByProcessorForgeImpl orderByProcessorForge,
     RowLimitProcessorFactoryForge rowLimitProcessorFactoryForge)
 {
     this.orderByProcessorForge = orderByProcessorForge;
     this.rowLimitProcessorFactoryForge = rowLimitProcessorFactoryForge;
 }
예제 #2
0
        protected internal static CodegenMethod CreateSortPropertiesWRollupCodegen(
            OrderByProcessorForgeImpl forge,
            CodegenClassScope classScope,
            CodegenNamedMethods namedMethods)
        {
            Consumer<CodegenMethod> code = method => {
                method.Block.DeclareVar<object[]>(
                        "sortProperties",
                        NewArrayByLength(typeof(object), ExprDotName(REF_ORDERCURRENTGENERATORS, "Count")))
                    .DeclareVar<int>("count", Constant(0));

                var forEach = method.Block.ForEach(typeof(GroupByRollupKey), "rollup", REF_ORDERCURRENTGENERATORS);

                if (forge.IsNeedsGroupByKeys) {
                    forEach.ExprDotMethod(
                        MEMBER_AGGREGATIONSVC,
                        "SetCurrentAccess",
                        ExprDotName(Ref("rollup"), "GroupKey"),
                        ExprDotName(REF_EXPREVALCONTEXT, "AgentInstanceId"),
                        ExprDotName(Ref("rollup"), "Level"));
                }

                forEach.DeclareVar<int>(
                    "num",
                    ExprDotMethodChain(Ref("rollup")).Get("Level").Get("LevelNumber"));
                var blocks = forEach.SwitchBlockOfLength(Ref("num"), forge.OrderByRollup.Length, false);
                for (var i = 0; i < blocks.Length; i++) {
                    var getSortKey = GenerateOrderKeyCodegen(
                        "GetSortKeyInternal_" + i,
                        forge.OrderByRollup[i],
                        classScope,
                        namedMethods);
                    blocks[i]
                        .AssignArrayElement(
                            "sortProperties",
                            Ref("count"),
                            LocalMethod(
                                getSortKey,
                                ExprDotName(Ref("rollup"), "Generator"),
                                REF_ISNEWDATA,
                                REF_EXPREVALCONTEXT));
                }

                forEach.IncrementRef("count");
                method.Block.MethodReturn(StaticMethod(typeof(CompatExtensions), "AsList", Ref("sortProperties")));
            };
            return namedMethods.AddMethod(
                typeof(IList<object>),
                "CreateSortPropertiesWRollup",
                CodegenNamedParam.From(
                    typeof(IList<GroupByRollupKey>), REF_ORDERCURRENTGENERATORS.Ref,
                    typeof(bool), REF_ISNEWDATA.Ref,
                    typeof(ExprEvaluatorContext), REF_EXPREVALCONTEXT.Ref,
                    typeof(AggregationService), MEMBER_AGGREGATIONSVC.Ref),
                typeof(OrderByProcessorImpl),
                classScope,
                code);
        }
예제 #3
0
 protected internal static void SortTwoKeysCodegen(
     OrderByProcessorForgeImpl forge,
     CodegenMethod method,
     CodegenClassScope classScope,
     CodegenNamedMethods namedMethods)
 {
     CodegenExpression comparator = classScope.AddOrGetDefaultFieldSharable(forge.IComparer);
     var compare = ExprDotMethod(comparator, "Compare", REF_ORDERFIRSTSORTKEY, REF_ORDERSECONDSORTKEY);
     method.Block.IfCondition(Relational(compare, LE, Constant(0)))
         .BlockReturn(NewArrayWithInit(typeof(EventBean), REF_ORDERFIRSTEVENT, REF_ORDERSECONDEVENT))
         .MethodReturn(NewArrayWithInit(typeof(EventBean), REF_ORDERSECONDEVENT, REF_ORDERFIRSTEVENT));
 }
예제 #4
0
 protected internal static void SortWOrderKeysCodegen(
     OrderByProcessorForgeImpl forge,
     CodegenMethod method,
     CodegenClassScope classScope)
 {
     CodegenExpression comparator = classScope.AddOrGetDefaultFieldSharable(forge.IComparer);
     method.Block.MethodReturn(
         StaticMethod(
             typeof(OrderByProcessorUtil),
             "SortWOrderKeys",
             REF_OUTGOINGEVENTS,
             REF_ORDERKEYS,
             comparator));
 }
예제 #5
0
 public static void GetSortKeyRollupCodegen(
     OrderByProcessorForgeImpl forge,
     CodegenMethod method,
     CodegenClassScope classScope,
     CodegenNamedMethods namedMethods)
 {
     method.Block.DeclareVar<int>("num", ExprDotName(REF_ORDERROLLUPLEVEL, "LevelNumber"));
     var blocks = method.Block.SwitchBlockOfLength(Ref("num"), forge.OrderByRollup.Length, true);
     for (var i = 0; i < blocks.Length; i++) {
         var getSortKey = GenerateOrderKeyCodegen(
             "GetSortKeyInternal_" + i,
             forge.OrderByRollup[i],
             classScope,
             namedMethods);
         blocks[i].BlockReturn(LocalMethod(getSortKey, REF_EPS, REF_ISNEWDATA, REF_EXPREVALCONTEXT));
     }
 }
예제 #6
0
        public static void GetSortKeyCodegen(
            OrderByProcessorForgeImpl forge,
            CodegenMethod method,
            CodegenClassScope classScope,
            CodegenNamedMethods namedMethods)
        {
            string[] expressions = null;
            bool[] descending = null;
            if (classScope.IsInstrumented) {
                expressions = forge.ExpressionTexts;
                descending = forge.DescendingFlags;
            }

            method.Block.Apply(Instblock(classScope, "qOrderBy", REF_EPS, Constant(expressions), Constant(descending)));
            var getSortKey = GenerateOrderKeyCodegen("GetSortKeyInternal", forge.OrderBy, classScope, namedMethods);
            method.Block
                .DeclareVar<object>("key", LocalMethod(getSortKey, REF_EPS, REF_ISNEWDATA, REF_EXPREVALCONTEXT))
                .Apply(Instblock(classScope, "aOrderBy", Ref("key")))
                .MethodReturn(Ref("key"));
        }
예제 #7
0
 protected internal static void SortWGroupKeysCodegen(
     OrderByProcessorForgeImpl forge,
     CodegenMethod method,
     CodegenClassScope classScope,
     CodegenNamedMethods namedMethods)
 {
     var sortWGroupKeysInternal = SortWGroupKeysInternalCodegen(forge, classScope, namedMethods);
     method.Block.IfCondition(
             Or(EqualsNull(REF_OUTGOINGEVENTS), Relational(ArrayLength(REF_OUTGOINGEVENTS), LT, Constant(2))))
         .BlockReturn(REF_OUTGOINGEVENTS)
         .MethodReturn(
             LocalMethod(
                 sortWGroupKeysInternal,
                 REF_OUTGOINGEVENTS,
                 REF_GENERATINGEVENTS,
                 REF_ORDERGROUPBYKEYS,
                 REF_ISNEWDATA,
                 REF_EXPREVALCONTEXT,
                 MEMBER_AGGREGATIONSVC));
 }
예제 #8
0
 protected internal static CodegenMethod SortWGroupKeysInternalCodegen(
     OrderByProcessorForgeImpl forge,
     CodegenClassScope classScope,
     CodegenNamedMethods namedMethods)
 {
     var createSortProperties = CreateSortPropertiesCodegen(forge, classScope, namedMethods);
     CodegenExpression comparator = classScope.AddOrGetDefaultFieldSharable(forge.IComparer);
     Consumer<CodegenMethod> code = method => {
         method.Block.DeclareVar<IList<object>>(
                 "sortValuesMultiKeys",
                 LocalMethod(
                     createSortProperties,
                     REF_GENERATINGEVENTS,
                     Ref("groupByKeys"),
                     REF_ISNEWDATA,
                     REF_EXPREVALCONTEXT,
                     MEMBER_AGGREGATIONSVC))
             .MethodReturn(
                 StaticMethod(
                     typeof(OrderByProcessorUtil),
                     "SortGivenOutgoingAndSortKeys",
                     REF_OUTGOINGEVENTS,
                     Ref("sortValuesMultiKeys"),
                     comparator));
     };
     return namedMethods.AddMethod(
         typeof(EventBean[]),
         "SortWGroupKeysInternal",
         CodegenNamedParam.From(
             typeof(EventBean[]), REF_OUTGOINGEVENTS.Ref,
             typeof(EventBean[][]), REF_GENERATINGEVENTS.Ref,
             typeof(object[]), "groupByKeys",
             typeof(bool), REF_ISNEWDATA.Ref,
             typeof(ExprEvaluatorContext), REF_EXPREVALCONTEXT.Ref,
             typeof(AggregationService), MEMBER_AGGREGATIONSVC.Ref),
         typeof(OrderByProcessorImpl),
         classScope,
         code);
 }
예제 #9
0
 protected internal static void SortRollupCodegen(
     OrderByProcessorForgeImpl forge,
     CodegenMethod method,
     CodegenClassScope classScope,
     CodegenNamedMethods namedMethods)
 {
     var createSortPropertiesWRollup = CreateSortPropertiesWRollupCodegen(forge, classScope, namedMethods);
     CodegenExpression comparator = classScope.AddOrGetDefaultFieldSharable(forge.IComparer);
     method.Block.DeclareVar<IList<object>>(
             "sortValuesMultiKeys",
             LocalMethod(
                 createSortPropertiesWRollup,
                 REF_ORDERCURRENTGENERATORS,
                 REF_ISNEWDATA,
                 MEMBER_AGENTINSTANCECONTEXT,
                 MEMBER_AGGREGATIONSVC))
         .MethodReturn(
             StaticMethod(
                 typeof(OrderByProcessorUtil),
                 "SortGivenOutgoingAndSortKeys",
                 REF_OUTGOINGEVENTS,
                 Ref("sortValuesMultiKeys"),
                 comparator));
 }
        public static OrderByProcessorFactoryForge GetProcessor(
            IList<SelectClauseExprCompiledSpec> selectionList,
            IList<OrderByItem> orderByList,
            RowLimitSpec rowLimitSpec,
            VariableCompileTimeResolver variableCompileTimeResolver,
            bool isSortUsingCollator,
            string optionalContextName,
            OrderByElementForge[][] orderByRollup)
        {
            // Get the order by expression nodes
            IList<ExprNode> orderByNodes = new List<ExprNode>();
            foreach (var element in orderByList) {
                orderByNodes.Add(element.ExprNode);
            }

            // No order-by clause
            if (orderByList.IsEmpty()) {
                Log.Debug(".getProcessor Using no OrderByProcessor");
                if (rowLimitSpec != null) {
                    var rowLimitProcessorFactory = new RowLimitProcessorFactoryForge(
                        rowLimitSpec,
                        variableCompileTimeResolver,
                        optionalContextName);
                    return new OrderByProcessorRowLimitOnlyForge(rowLimitProcessorFactory);
                }

                return null;
            }

            // Determine aggregate functions used in select, if any
            IList<ExprAggregateNode> selectAggNodes = new List<ExprAggregateNode>();
            foreach (var element in selectionList) {
                ExprAggregateNodeUtil.GetAggregatesBottomUp(element.SelectExpression, selectAggNodes);
            }

            // Get all the aggregate functions occuring in the order-by clause
            IList<ExprAggregateNode> orderAggNodes = new List<ExprAggregateNode>();
            foreach (var orderByNode in orderByNodes) {
                ExprAggregateNodeUtil.GetAggregatesBottomUp(orderByNode, orderAggNodes);
            }

            ValidateOrderByAggregates(selectAggNodes, orderAggNodes);

            // Tell the order-by processor whether to compute group-by
            // keys if they are not present
            var needsGroupByKeys = !selectionList.IsEmpty() && !orderAggNodes.IsEmpty();

            Log.Debug(".getProcessor Using OrderByProcessorImpl");
            var elements = ToElementArray(orderByList);
            var comparator = GetComparator(elements, isSortUsingCollator);
            var orderByProcessorForge = new OrderByProcessorForgeImpl(
                elements,
                needsGroupByKeys,
                orderByRollup,
                comparator);
            if (rowLimitSpec == null) {
                return orderByProcessorForge;
            }

            {
                var rowLimitProcessorFactory = new RowLimitProcessorFactoryForge(
                    rowLimitSpec,
                    variableCompileTimeResolver,
                    optionalContextName);
                return new OrderByProcessorOrderedLimitForge(orderByProcessorForge, rowLimitProcessorFactory);
            }
        }
예제 #11
0
        public static CodegenMethod DetermineLocalMinMaxCodegen(
            OrderByProcessorForgeImpl forge,
            CodegenClassScope classScope,
            CodegenNamedMethods namedMethods)
        {
            var elements = forge.OrderBy;
            CodegenExpression comparator = classScope.AddOrGetDefaultFieldSharable(forge.IComparer);

            Consumer<CodegenMethod> code = method => {
                method.Block.DeclareVar<object>("localMinMax", ConstantNull())
                    .DeclareVar<EventBean>("outgoingMinMaxBean", ConstantNull())
                    .DeclareVar<int>("count", Constant(0));

                if (elements.Length == 1) {
                    var forEach = method.Block.ForEach(typeof(EventBean[]), "eventsPerStream", REF_GENERATINGEVENTS);

                    forEach.DeclareVar<object>(
                            "sortKey",
                            LocalMethod(
                                CodegenLegoMethodExpression.CodegenExpression(
                                    elements[0].ExprNode.Forge,
                                    method,
                                    classScope,
                                    true),
                                Ref("eventsPerStream"),
                                REF_ISNEWDATA,
                                REF_EXPREVALCONTEXT))
                        .IfCondition(
                            Or(
                                EqualsNull(Ref("localMinMax")),
                                Relational(
                                    ExprDotMethod(comparator, "Compare", Ref("localMinMax"), Ref("sortKey")),
                                    GT,
                                    Constant(0))))
                        .AssignRef("localMinMax", Ref("sortKey"))
                        .AssignRef("outgoingMinMaxBean", ArrayAtIndex(REF_OUTGOINGEVENTS, Ref("count")))
                        .BlockEnd()
                        .IncrementRef("count");
                }
                else {
                    method.Block.DeclareVar<object[]>(
                            "values",
                            NewArrayByLength(typeof(object), Constant(elements.Length)))
                        .DeclareVar<HashableMultiKey>(
                            "valuesMk",
                            NewInstance<HashableMultiKey>(Ref("values")));

                    var forEach = method.Block.ForEach(typeof(EventBean[]), "eventsPerStream", REF_GENERATINGEVENTS);

                    if (forge.IsNeedsGroupByKeys) {
                        forEach.ExprDotMethod(
                            MEMBER_AGGREGATIONSVC,
                            "SetCurrentAccess",
                            ArrayAtIndex(Ref("groupByKeys"), Ref("count")),
                            ExprDotMethod(REF_EXPREVALCONTEXT, "GetAgentInstanceId", ConstantNull()));
                    }

                    for (var i = 0; i < elements.Length; i++) {
                        forEach.AssignArrayElement(
                            "values",
                            Constant(i),
                            LocalMethod(
                                CodegenLegoMethodExpression.CodegenExpression(
                                    elements[i].ExprNode.Forge,
                                    method,
                                    classScope,
                                    true),
                                Ref("eventsPerStream"),
                                REF_ISNEWDATA,
                                REF_EXPREVALCONTEXT));
                    }

                    forEach.IfCondition(
                            Or(
                                EqualsNull(Ref("localMinMax")),
                                Relational(
                                    ExprDotMethod(comparator, "Compare", Ref("localMinMax"), Ref("valuesMk")),
                                    GT,
                                    Constant(0))))
                        .AssignRef("localMinMax", Ref("valuesMk"))
                        .AssignRef("values", NewArrayByLength(typeof(object), Constant(elements.Length)))
                        .AssignRef("valuesMk", NewInstance<HashableMultiKey>(Ref("values")))
                        .AssignRef("outgoingMinMaxBean", ArrayAtIndex(REF_OUTGOINGEVENTS, Ref("count")))
                        .BlockEnd()
                        .IncrementRef("count");
                }

                method.Block.MethodReturn(Ref("outgoingMinMaxBean"));
            };

            return namedMethods.AddMethod(
                typeof(EventBean),
                "DetermineLocalMinMax",
                CodegenNamedParam.From(
                    typeof(EventBean[]), REF_OUTGOINGEVENTS.Ref,
                    typeof(EventBean[][]), REF_GENERATINGEVENTS.Ref,
                    typeof(bool), NAME_ISNEWDATA,
                    typeof(ExprEvaluatorContext), NAME_EXPREVALCONTEXT,
                    typeof(AggregationService), MEMBER_AGGREGATIONSVC.Ref),
                typeof(OrderByProcessorImpl),
                classScope,
                code);
        }
예제 #12
0
        protected internal static CodegenMethod CreateSortPropertiesCodegen(
            OrderByProcessorForgeImpl forge,
            CodegenClassScope classScope,
            CodegenNamedMethods namedMethods)
        {
            Consumer<CodegenMethod> code = method => {
                string[] expressions = null;
                bool[] descending = null;
                if (classScope.IsInstrumented) {
                    expressions = forge.ExpressionTexts;
                    descending = forge.DescendingFlags;
                }

                method.Block.DeclareVar<object[]>(
                    "sortProperties",
                    NewArrayByLength(typeof(object), ArrayLength(REF_GENERATINGEVENTS)));

                var elements = forge.OrderBy;
                var forEach = method.Block.DeclareVar<int>("count", Constant(0))
                    .ForEach(typeof(EventBean[]), "eventsPerStream", REF_GENERATINGEVENTS);

                if (forge.IsNeedsGroupByKeys) {
                    forEach.ExprDotMethod(
                        MEMBER_AGGREGATIONSVC,
                        "SetCurrentAccess",
                        ArrayAtIndex(Ref("groupByKeys"), Ref("count")),
                        ExprDotName(REF_EXPREVALCONTEXT, "AgentInstanceId"),
                        ConstantNull());
                }

                forEach.Apply(
                    Instblock(
                        classScope,
                        "qOrderBy",
                        Ref("eventsPerStream"),
                        Constant(expressions),
                        Constant(descending)));
                if (elements.Length == 1) {
                    forEach.AssignArrayElement(
                        "sortProperties",
                        Ref("count"),
                        LocalMethod(
                            CodegenLegoMethodExpression.CodegenExpression(
                                elements[0].ExprNode.Forge,
                                method,
                                classScope,
                                true),
                            Ref("eventsPerStream"),
                            REF_ISNEWDATA,
                            REF_EXPREVALCONTEXT));
                }
                else {
                    forEach.DeclareVar<object[]>(
                        "values",
                        NewArrayByLength(typeof(object), Constant(forge.OrderBy.Length)));
                    for (var i = 0; i < forge.OrderBy.Length; i++) {
                        forEach.AssignArrayElement(
                            "values",
                            Constant(i),
                            LocalMethod(
                                CodegenLegoMethodExpression.CodegenExpression(
                                    elements[i].ExprNode.Forge,
                                    method,
                                    classScope,
                                    true),
                                Ref("eventsPerStream"),
                                REF_ISNEWDATA,
                                REF_EXPREVALCONTEXT));
                    }

                    forEach.AssignArrayElement(
                        "sortProperties",
                        Ref("count"),
                        NewInstance<HashableMultiKey>(Ref("values")));
                }

                forEach.Apply(Instblock(classScope, "aOrderBy", Ref("sortProperties")))
                    .IncrementRef("count");
                method.Block.MethodReturn(StaticMethod(typeof(CompatExtensions), "AsList", Ref("sortProperties")));
            };
            return namedMethods.AddMethod(
                typeof(IList<object>),
                "CreateSortProperties",
                CodegenNamedParam.From(
                    typeof(EventBean[][]), REF_GENERATINGEVENTS.Ref,
                    typeof(object[]), "groupByKeys",
                    typeof(bool), REF_ISNEWDATA.Ref,
                    typeof(ExprEvaluatorContext), REF_EXPREVALCONTEXT.Ref,
                    typeof(AggregationService), MEMBER_AGGREGATIONSVC.Ref),
                typeof(OrderByProcessorImpl),
                classScope,
                code);
        }