// Obtain those method and state factories for each level private static AggregationLocalGroupByLevelForge GetLevel( int levelNumber, AggregationGroupByLocalGroupLevel level, ExprForge[][] methodForgesAll, AggregationForgeFactory[] methodFactoriesAll, AggregationStateFactoryForge[] accessForges, AggregationLocalGroupByColumnForge[] columns, bool defaultLevel, AggregationAccessorSlotPairForge[] accessors, ImportService importService, bool isFireAndForget, string statementName) { var partitionExpr = level.PartitionExpr; ExprForge[] partitionForges = ExprNodeUtilityQuery.GetForges(partitionExpr); IList<ExprForge[]> methodForges = new List<ExprForge[]>(); IList<AggregationForgeFactory> methodFactories = new List<AggregationForgeFactory>(); IList<AggregationStateFactoryForge> stateFactories = new List<AggregationStateFactoryForge>(); foreach (var expr in level.Expressions) { int column = expr.AggregationNode.Column; var methodOffset = -1; var methodAgg = true; AggregationAccessorSlotPairForge pair = null; if (column < methodForgesAll.Length) { methodForges.Add(methodForgesAll[column]); methodFactories.Add(methodFactoriesAll[column]); methodOffset = methodFactories.Count - 1; } else { // slot gives us the number of the state factory int absoluteSlot = accessors[column - methodForgesAll.Length].Slot; AggregationAccessorForge accessor = accessors[column - methodForgesAll.Length].AccessorForge; var factory = accessForges[absoluteSlot]; var relativeSlot = stateFactories.IndexOf(factory); if (relativeSlot == -1) { stateFactories.Add(factory); relativeSlot = stateFactories.Count - 1; } methodAgg = false; pair = new AggregationAccessorSlotPairForge(relativeSlot, accessor); } columns[column] = new AggregationLocalGroupByColumnForge( defaultLevel, partitionForges, methodOffset, methodAgg, pair, levelNumber); } return new AggregationLocalGroupByLevelForge( methodForges.ToArray(), methodFactories.ToArray(), stateFactories.ToArray(), partitionForges, defaultLevel); }
// Obtain those method and state factories for each level private static AggregationGroupByLocalGroupLevelDesc GetLevel( int levelNumber, AggregationGroupByLocalGroupLevel level, ExprForge[][] methodForgesAll, AggregationForgeFactory[] methodFactoriesAll, AggregationStateFactoryForge[] accessForges, AggregationLocalGroupByColumnForge[] columns, bool defaultLevel, AggregationAccessorSlotPairForge[] accessors, ExprNode[] groupByExpressions, MultiKeyClassRef optionalGroupByMultiKey, StatementRawInfo raw, SerdeCompileTimeResolver serdeResolver) { var partitionExpr = level.PartitionExpr; MultiKeyPlan multiKeyPlan; if (defaultLevel && optionalGroupByMultiKey != null) { // use default multi-key that is already generated multiKeyPlan = new MultiKeyPlan(EmptyList<StmtClassForgeableFactory>.Instance, optionalGroupByMultiKey); partitionExpr = groupByExpressions; } else { multiKeyPlan = MultiKeyPlanner.PlanMultiKey(partitionExpr, false, raw, serdeResolver); } IList<ExprForge[]> methodForges = new List<ExprForge[]>(); IList<AggregationForgeFactory> methodFactories = new List<AggregationForgeFactory>(); IList<AggregationStateFactoryForge> stateFactories = new List<AggregationStateFactoryForge>(); foreach (var expr in level.Expressions) { int column = expr.AggregationNode.Column; var methodOffset = -1; var methodAgg = true; AggregationAccessorSlotPairForge pair = null; if (column < methodForgesAll.Length) { methodForges.Add(methodForgesAll[column]); methodFactories.Add(methodFactoriesAll[column]); methodOffset = methodFactories.Count - 1; } else { // slot gives us the number of the state factory int absoluteSlot = accessors[column - methodForgesAll.Length].Slot; AggregationAccessorForge accessor = accessors[column - methodForgesAll.Length].AccessorForge; var factory = accessForges[absoluteSlot]; var relativeSlot = stateFactories.IndexOf(factory); if (relativeSlot == -1) { stateFactories.Add(factory); relativeSlot = stateFactories.Count - 1; } methodAgg = false; pair = new AggregationAccessorSlotPairForge(relativeSlot, accessor); } columns[column] = new AggregationLocalGroupByColumnForge( defaultLevel, partitionExpr, methodOffset, methodAgg, pair, levelNumber); } var forge = new AggregationLocalGroupByLevelForge( methodForges.ToArray(), methodFactories.ToArray(), stateFactories.ToArray(), partitionExpr, multiKeyPlan.ClassRef, defaultLevel); // NOTE: The original code tests for multiKeyPlan being null, but if it was null it would have caused // a null pointer exception on the previous statement since it dereferences ClassRef. var additionalForgeables = multiKeyPlan?.MultiKeyForgeables ?? EmptyList<StmtClassForgeableFactory>.Instance; return new AggregationGroupByLocalGroupLevelDesc(forge, additionalForgeables); }