Search in sources :

Example 1 with GroupByPattern

use of org.drools.model.GroupByPattern in project drools by kiegroup.

the class KiePackagesBuilder method buildAccumulate.

private Accumulate buildAccumulate(RuleContext ctx, AccumulatePattern accPattern, RuleConditionElement source, Pattern pattern, Set<String> usedVariableName, Collection<Binding> bindings) {
    boolean isGroupBy = accPattern instanceof GroupByPattern;
    AccumulateFunction[] accFunctions = accPattern.getAccumulateFunctions();
    Declaration groupByDeclaration = null;
    Class selfType = (isGroupBy || accFunctions.length > 1) ? Object[].class : accFunctions[0].getResult().getType();
    InternalReadAccessor selfReader = new SelfReferenceClassFieldReader(selfType);
    int arrayIndexOffset = 0;
    if (isGroupBy) {
        if (accFunctions.length == 0) {
            // In this situation the result is anonymous, but it still uses element position 0.
            // For this reason the i used to populate hte array index must be offset by 1.
            accFunctions = new AccumulateFunction[] { new AccumulateFunction(null, CountAccumulateFunction::new) };
            arrayIndexOffset = 1;
        }
        // GroupBy  key is always the last element in the result array
        Variable groupVar = ((GroupByPattern<?, ?>) accPattern).getVarKey();
        groupByDeclaration = new Declaration(groupVar.getName(), new ArrayElementReader(selfReader, accFunctions.length, groupVar.getType()), pattern, true);
        pattern.addDeclaration(groupByDeclaration);
    }
    Accumulate accumulate;
    Accumulator[] accumulators = new Accumulator[accFunctions.length];
    List<Declaration> requiredDeclarationList = new ArrayList<>();
    for (int i = 0; i < accFunctions.length; i++) {
        Variable boundVar = processFunctions(ctx, accPattern, source, pattern, usedVariableName, bindings, isGroupBy, accFunctions[i], selfReader, accumulators, requiredDeclarationList, arrayIndexOffset, i);
        if (isGroupBy) {
            ctx.addGroupByDeclaration(((GroupByPattern) accPattern).getVarKey(), groupByDeclaration);
        }
    }
    if (accFunctions.length == 1) {
        accumulate = new SingleAccumulate(source, requiredDeclarationList.toArray(new Declaration[requiredDeclarationList.size()]), accumulators[0]);
    } else {
        if (source instanceof Pattern) {
            requiredDeclarationList.forEach(((Pattern) source)::addDeclaration);
        }
        accumulate = new MultiAccumulate(source, new Declaration[0], accumulators, // if this is a groupby +1 for the key
        accumulators.length + ((isGroupBy) ? 1 : 0));
    }
    if (isGroupBy) {
        GroupByPatternImpl groupBy = (GroupByPatternImpl) accPattern;
        Declaration[] groupingDeclarations = new Declaration[groupBy.getVars().length];
        for (int i = 0; i < groupBy.getVars().length; i++) {
            groupingDeclarations[i] = ctx.getDeclaration(groupBy.getVars()[i]);
        }
        accumulate = new LambdaGroupByAccumulate(accumulate, groupingDeclarations, groupBy.getGroupingFunction());
    }
    for (Variable boundVar : accPattern.getBoundVariables()) {
        ctx.addAccumulateSource(boundVar, accumulate);
    }
    return accumulate;
}
Also used : LambdaAccumulator(org.drools.modelcompiler.constraints.LambdaAccumulator) Accumulator(org.drools.core.spi.Accumulator) QueryCallPattern(org.drools.model.patterns.QueryCallPattern) AccumulatePattern(org.drools.model.AccumulatePattern) Pattern(org.drools.core.rule.Pattern) GroupByPattern(org.drools.model.GroupByPattern) PrototypeVariable(org.drools.model.PrototypeVariable) Variable(org.drools.model.Variable) MultiAccumulate(org.drools.core.rule.MultiAccumulate) ArrayList(java.util.ArrayList) SingleAccumulate(org.drools.core.rule.SingleAccumulate) SingleConstraint(org.drools.model.SingleConstraint) QueryNameConstraint(org.drools.core.rule.constraint.QueryNameConstraint) LambdaConstraint(org.drools.modelcompiler.constraints.LambdaConstraint) UnificationConstraint(org.drools.modelcompiler.constraints.UnificationConstraint) EntryPoint(org.drools.model.EntryPoint) AbstractConstraint(org.drools.modelcompiler.constraints.AbstractConstraint) Constraint(org.drools.model.Constraint) CombinedConstraint(org.drools.modelcompiler.constraints.CombinedConstraint) AbstractSingleConstraint(org.drools.model.constraints.AbstractSingleConstraint) DSL.entryPoint(org.drools.model.DSL.entryPoint) LambdaGroupByAccumulate(org.drools.modelcompiler.constraints.LambdaGroupByAccumulate) MultiAccumulate(org.drools.core.rule.MultiAccumulate) SingleAccumulate(org.drools.core.rule.SingleAccumulate) Accumulate(org.drools.core.rule.Accumulate) GroupByPattern(org.drools.model.GroupByPattern) LambdaGroupByAccumulate(org.drools.modelcompiler.constraints.LambdaGroupByAccumulate) SelfReferenceClassFieldReader(org.drools.core.base.extractors.SelfReferenceClassFieldReader) GroupByPatternImpl(org.drools.model.patterns.GroupByPatternImpl) InternalReadAccessor(org.drools.core.spi.InternalReadAccessor) ArrayElementReader(org.drools.core.base.extractors.ArrayElementReader) Declaration(org.drools.core.rule.Declaration) WindowDeclaration(org.drools.core.rule.WindowDeclaration) TypeDeclarationUtil.createTypeDeclaration(org.drools.modelcompiler.util.TypeDeclarationUtil.createTypeDeclaration) TypeDeclaration(org.drools.core.rule.TypeDeclaration) CountAccumulateFunction(org.drools.core.base.accumulators.CountAccumulateFunction) AccumulateFunction(org.drools.model.functions.accumulate.AccumulateFunction)

Example 2 with GroupByPattern

use of org.drools.model.GroupByPattern in project drools by kiegroup.

the class KiePackagesBuilder method buildAccumulate.

private RuleConditionElement buildAccumulate(RuleContext ctx, GroupElement group, AccumulatePattern accumulatePattern) {
    Pattern pattern = null;
    boolean isGroupBy = accumulatePattern instanceof GroupByPattern;
    if (accumulatePattern.getAccumulateFunctions() != null) {
        if (!isGroupBy && accumulatePattern.getAccumulateFunctions().length == 1) {
            // non groupby with single accumulates can be optimized to directly return the result, rather than place in an array of 1
            pattern = ctx.getPattern(accumulatePattern.getAccumulateFunctions()[0].getResult());
        } else if (accumulatePattern.getAccumulateFunctions().length > 0 && ctx.getPattern(accumulatePattern.getAccumulateFunctions()[0].getResult()) != null) {
            // Illegal executable model. Cannot have groupby or multi accumulate mapped to a single result object.
            throw new RuntimeException("Only single accumulate functions, with no group by can optimize the result pattern to be the function return value");
        }
    }
    boolean existingPattern = pattern != null;
    if (!existingPattern) {
        ObjectType type = !isGroupBy && accumulatePattern.getAccumulateFunctions().length == 1 ? new ClassObjectType(accumulatePattern.getAccumulateFunctions()[0].getResult().getType()) : // groupby or multi function accumulate
        JAVA_CLASS_ARRAY_TYPE;
        pattern = new Pattern(ctx.getNextPatternIndex(), type);
    }
    PatternImpl<?> sourcePattern = (PatternImpl<?>) accumulatePattern.getPattern();
    Set<String> usedVariableName = new LinkedHashSet<>();
    if (sourcePattern != null) {
        for (Variable v : sourcePattern.getInputVariables()) {
            usedVariableName.add(v.getName());
        }
    }
    RuleConditionElement source;
    if (accumulatePattern.isQuerySource()) {
        source = buildQueryPattern(ctx, ((QueryCallPattern) accumulatePattern.getCondition()));
    } else if (accumulatePattern.isCompositePatterns()) {
        CompositePatterns compositePatterns = (CompositePatterns) accumulatePattern.getCondition();
        GroupElement allSubConditions = new GroupElement(conditionToGroupElementType(compositePatterns.getType()));
        for (Condition c : compositePatterns.getSubConditions()) {
            recursivelyAddConditions(ctx, group, allSubConditions, c);
        }
        source = allSubConditions.getChildren().size() == 1 ? allSubConditions.getChildren().get(0) : allSubConditions;
    } else {
        source = buildPattern(ctx, group, accumulatePattern);
    }
    Collection<Binding> bindings = new ArrayList<>();
    if (sourcePattern != null) {
        bindings.addAll(sourcePattern.getBindings());
        bindings.add(new SelfPatternBiding<>(sourcePattern.getPatternVariable()));
    } else {
        // No pattern is associated. It likely uses inner bindings
        addInnerBindings(bindings, accumulatePattern.getAccumulateFunctions(), accumulatePattern.getCondition());
    }
    pattern.setSource(buildAccumulate(ctx, accumulatePattern, source, pattern, usedVariableName, bindings));
    return existingPattern ? null : pattern;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) EvalCondition(org.drools.core.rule.EvalCondition) Condition(org.drools.model.Condition) Binding(org.drools.model.Binding) QueryCallPattern(org.drools.model.patterns.QueryCallPattern) AccumulatePattern(org.drools.model.AccumulatePattern) Pattern(org.drools.core.rule.Pattern) GroupByPattern(org.drools.model.GroupByPattern) PrototypeVariable(org.drools.model.PrototypeVariable) Variable(org.drools.model.Variable) ClassObjectType(org.drools.core.base.ClassObjectType) GroupElement(org.drools.core.rule.GroupElement) ArrayList(java.util.ArrayList) RuleConditionElement(org.drools.core.rule.RuleConditionElement) FactTemplateObjectType(org.drools.core.facttemplates.FactTemplateObjectType) ObjectType(org.drools.core.spi.ObjectType) ClassObjectType(org.drools.core.base.ClassObjectType) CompositePatterns(org.drools.model.patterns.CompositePatterns) GroupByPattern(org.drools.model.GroupByPattern) GroupByPatternImpl(org.drools.model.patterns.GroupByPatternImpl) PatternImpl(org.drools.model.patterns.PatternImpl) ExistentialPatternImpl(org.drools.model.patterns.ExistentialPatternImpl)

Aggregations

ArrayList (java.util.ArrayList)2 Pattern (org.drools.core.rule.Pattern)2 AccumulatePattern (org.drools.model.AccumulatePattern)2 GroupByPattern (org.drools.model.GroupByPattern)2 PrototypeVariable (org.drools.model.PrototypeVariable)2 Variable (org.drools.model.Variable)2 GroupByPatternImpl (org.drools.model.patterns.GroupByPatternImpl)2 QueryCallPattern (org.drools.model.patterns.QueryCallPattern)2 LinkedHashSet (java.util.LinkedHashSet)1 ClassObjectType (org.drools.core.base.ClassObjectType)1 CountAccumulateFunction (org.drools.core.base.accumulators.CountAccumulateFunction)1 ArrayElementReader (org.drools.core.base.extractors.ArrayElementReader)1 SelfReferenceClassFieldReader (org.drools.core.base.extractors.SelfReferenceClassFieldReader)1 FactTemplateObjectType (org.drools.core.facttemplates.FactTemplateObjectType)1 Accumulate (org.drools.core.rule.Accumulate)1 Declaration (org.drools.core.rule.Declaration)1 EvalCondition (org.drools.core.rule.EvalCondition)1 GroupElement (org.drools.core.rule.GroupElement)1 MultiAccumulate (org.drools.core.rule.MultiAccumulate)1 RuleConditionElement (org.drools.core.rule.RuleConditionElement)1