Skip to content

Commit

Permalink
[DROOLS-3999] perf improvement for dmn (apache#2341)
Browse files Browse the repository at this point in the history
  • Loading branch information
mariofusco committed May 10, 2019
1 parent e432320 commit c7f1ab6
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ public RuleUnitExecutorSession() {
session.ruleEventListenerSupport = new RuleEventListenerSupport();
}

public RuleUnitExecutorSession(KieBase kiebase) {
session = (StatefulKnowledgeSessionImpl) kiebase.newKieSession();
session.ruleUnitExecutor = this;
this.ruleUnitGuardSystem = new RuleUnitGuardSystem( this );
}

public RuleUnitExecutorSession(KieSession session) {
this.session = (( StatefulKnowledgeSessionImpl ) session);
this.session.ruleUnitExecutor = this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
public class RuleUnitDescription {
private final Class<? extends RuleUnit> ruleUnitClass;

private final Map<String, String> datasources = new HashMap<>();
private final Map<String, Class<?>> datasourceTypes = new HashMap<>();

private final Map<String, Method> varAccessors = new HashMap<>();
Expand All @@ -62,7 +61,7 @@ private String getEntryPointName(String name) {
}

public Optional<EntryPointId> getEntryPointId( String name ) {
return Optional.ofNullable( datasources.get( name ) ).map( ds -> new EntryPointId( getEntryPointName(name) ) );
return varAccessors.containsKey( name ) ? Optional.of( new EntryPointId( getEntryPointName(name) ) ) : Optional.empty();
}

public Optional<Class<?>> getDatasourceType( String name ) {
Expand All @@ -86,29 +85,29 @@ public Map<String, Method> getUnitVarAccessors() {
}

public boolean hasDataSource( String name ) {
return datasources.containsKey( name );
return varAccessors.containsKey( name );
}

public void bindDataSources( StatefulKnowledgeSessionImpl wm, RuleUnit ruleUnit ) {
datasources.forEach( (name, accessor) -> bindDataSource( wm, ruleUnit, name, accessor ) );
varAccessors.forEach( (name, method) -> bindDataSource( wm, ruleUnit, name, method ) );
}

private void bindDataSource( StatefulKnowledgeSessionImpl wm, RuleUnit ruleUnit, String name, String accessor ) {
private void bindDataSource( StatefulKnowledgeSessionImpl wm, RuleUnit ruleUnit, String name, Method method ) {
WorkingMemoryEntryPoint entryPoint = wm.getEntryPoint( getEntryPointName( name ) );
if (entryPoint != null) {
BindableDataProvider dataSource = findDataSource( ruleUnit, accessor );
BindableDataProvider dataSource = findDataSource( ruleUnit, method );
if (dataSource != null) {
dataSource.bind( ruleUnit, entryPoint );
}
}
}

public void unbindDataSources( StatefulKnowledgeSessionImpl wm, RuleUnit ruleUnit ) {
datasources.values().forEach( accessor -> unbindDataSource( ruleUnit, accessor ) );
varAccessors.values().forEach( method -> unbindDataSource( ruleUnit, method ) );
}

private void unbindDataSource( RuleUnit ruleUnit, String accessor ) {
BindableDataProvider dataSource = findDataSource( ruleUnit, accessor );
private void unbindDataSource( RuleUnit ruleUnit, Method method ) {
BindableDataProvider dataSource = findDataSource( ruleUnit, method );
if (dataSource != null) {
dataSource.unbind( ruleUnit );
}
Expand All @@ -126,9 +125,13 @@ public Object getValue(RuleUnit ruleUnit, String identifier) {
return null;
}

private BindableDataProvider findDataSource( RuleUnit ruleUnit, String accessor ) {
private BindableDataProvider findDataSource( RuleUnit ruleUnit, String name ) {
return findDataSource( ruleUnit, varAccessors.get( name ) );
}

private BindableDataProvider findDataSource( RuleUnit ruleUnit, Method m ) {
try {
Object value = ruleUnit.getClass().getMethod( accessor ).invoke( ruleUnit );
Object value = m.invoke( ruleUnit );
if (value == null) {
return null;
}
Expand All @@ -152,7 +155,6 @@ private void indexUnitVars() {
if ( m.getDeclaringClass() != RuleUnit.class && m.getParameterCount() == 0 && !"getUnitIdentity".equals(m.getName())) {
String id = getter2property(m.getName());
if (id != null && !id.equals( "class" )) {
datasources.put( id, m.getName() );
varAccessors.put( id, m );

Class<?> returnClass = m.getReturnType();
Expand All @@ -161,8 +163,8 @@ private void indexUnitVars() {
} else if (Iterable.class.isAssignableFrom( returnClass )) {
Type returnType = m.getGenericReturnType();
Class<?> sourceType = returnType instanceof ParameterizedType ?
(Class<?>) ( (ParameterizedType) returnType ).getActualTypeArguments()[0] :
Object.class;
(Class<?>) ( (ParameterizedType) returnType ).getActualTypeArguments()[0] :
Object.class;
datasourceTypes.put( id, sourceType );
} else {
datasourceTypes.put( id, returnClass );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.Collections;
import java.util.List;

import org.drools.core.impl.RuleUnitExecutorSession;
import org.drools.model.Model;
import org.drools.model.Rule;
import org.drools.model.impl.ModelImpl;
Expand Down Expand Up @@ -72,7 +73,7 @@ public EvaluatorResult evaluate( DMNRuntimeEventManager eventManager, DMNResult
List<FEELEvent> events = new ArrayList<>();
DMNRuntimeEventManagerUtils.fireBeforeEvaluateDecisionTable( eventManager, node.getName(), dTableModel.getDtName(), dmnResult );

RuleUnitExecutor executor = RuleUnitExecutor.create().bind( kieBase );
RuleUnitExecutor executor = new RuleUnitExecutorSession( kieBase );
EvaluationContext evalCtx = createEvaluationContext( events, eventManager, dmnResult );
evalCtx.enterFrame();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.kie.dmn.api.feel.runtime.events.FEELEvent;
import org.kie.dmn.core.compiler.DMNFEELHelper;
Expand Down Expand Up @@ -48,11 +49,12 @@ public Object getOutput(int row, int col) {
}

private Object[] initInputs(DMNFEELHelper feel) {
Map<String, Object> allValues = evalCtx.getAllValues();
for (int i = 0; i < inputs.length; i++) {
Object result = dTableModel.getColumns().get(i).evaluate( evalCtx );
inputs[i] = new FeelValue(result);

columnEvalCtxs[i] = feel.newEvaluationContext( Collections.singletonList( events::add ), evalCtx.getAllValues());
columnEvalCtxs[i] = feel.newEvaluationContext( Collections.singletonList( events::add ), allValues);
columnEvalCtxs[i].enterFrame();
columnEvalCtxs[i].setValue( "?", result );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import com.github.javaparser.ast.CompilationUnit;
Expand Down Expand Up @@ -55,7 +54,7 @@ public class FEELImpl
private final ClassLoader classLoader;
private final List<FEELProfile> profiles;
// pre-cached results from the above profiles...
private final Optional<ExecutionFrameImpl> customFrame;
private final ExecutionFrameImpl customFrame;
private final Collection<FEELFunction> customFunctions;
private final boolean doCompile;

Expand All @@ -74,16 +73,15 @@ public FEELImpl(List<FEELProfile> profiles) {
public FEELImpl(ClassLoader cl, List<FEELProfile> profiles) {
this.classLoader = cl;
this.profiles = Collections.unmodifiableList(profiles);
ExecutionFrameImpl frame = new ExecutionFrameImpl(null);
this.customFrame = new ExecutionFrameImpl(null);
Map<String, FEELFunction> functions = new HashMap<>();
for (FEELProfile p : profiles) {
for (FEELFunction f : p.getFEELFunctions()) {
frame.setValue(f.getName(), f);
customFrame.setValue(f.getName(), f);
functions.put(f.getName(), f);
}
}
doCompile = profiles.stream().anyMatch(DoCompileFEELProfile.class::isInstance);
customFrame = Optional.of(frame);
customFunctions = Collections.unmodifiableCollection(functions.values());
}

Expand Down Expand Up @@ -177,14 +175,13 @@ public EvaluationContextImpl newEvaluationContext(Collection<FEELEventListener>
public EvaluationContextImpl newEvaluationContext(ClassLoader cl, Collection<FEELEventListener> listeners, Map<String, Object> inputVariables) {
FEELEventListenersManager eventsManager = getEventsManager(listeners);
EvaluationContextImpl ctx = new EvaluationContextImpl(cl, eventsManager, inputVariables.size());
if (customFrame.isPresent()) {
ExecutionFrameImpl globalFrame = (ExecutionFrameImpl) ctx.pop();
ExecutionFrameImpl interveawedFrame = customFrame.get();
interveawedFrame.setParentFrame(ctx.peek());
globalFrame.setParentFrame(interveawedFrame);
ctx.push(interveawedFrame);
ctx.push(globalFrame);
}

ExecutionFrameImpl globalFrame = (ExecutionFrameImpl) ctx.pop();
customFrame.setParentFrame(ctx.peek());
globalFrame.setParentFrame(customFrame);
ctx.push(customFrame);
ctx.push(globalFrame);

ctx.setValues(inputVariables);
return ctx;
}
Expand Down

0 comments on commit c7f1ab6

Please sign in to comment.