Skip to content

Commit

Permalink
[DROOLS-1445] add declarations required by accumulate functions into …
Browse files Browse the repository at this point in the history
…accumulate node left mask (apache#1120)
  • Loading branch information
mariofusco committed Feb 28, 2017
1 parent 8b5348b commit fa39028
Show file tree
Hide file tree
Showing 11 changed files with 79 additions and 39 deletions.
Expand Up @@ -15,6 +15,24 @@

package org.drools.compiler.integrationtests;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
import java.io.StringReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.drools.compiler.Cheese;
import org.drools.compiler.Cheesery;
import org.drools.compiler.CommonTestMethodBase;
Expand Down Expand Up @@ -55,30 +73,13 @@
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.builder.conf.PropertySpecificOption;
import org.kie.internal.io.ResourceFactory;
import org.kie.internal.runtime.StatefulKnowledgeSession;
import org.kie.internal.utils.KieHelper;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
import java.io.StringReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import static org.hamcrest.CoreMatchers.is;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
Expand Down Expand Up @@ -2790,6 +2791,16 @@ public void testFromAccumulateWithoutSeparator() throws Exception {
@Test
public void testAccFunctionOpaqueJoins() throws Exception {
// DROOLS-661
testAccFunctionOpaqueJoins(PropertySpecificOption.ALLOWED);
}

@Test
public void testAccFunctionOpaqueJoinsWithPropertyReactivity() throws Exception {
// DROOLS-1445
testAccFunctionOpaqueJoins(PropertySpecificOption.ALWAYS);
}

private void testAccFunctionOpaqueJoins(PropertySpecificOption propertySpecificOption) throws Exception {
String str = "package org.test; " +
"import java.util.*; " +
"global List list; " +
Expand Down Expand Up @@ -2845,7 +2856,7 @@ public void testAccFunctionOpaqueJoins() throws Exception {
" list2.add( $tot ); " +
"end ";

KieHelper helper = new KieHelper();
KieHelper helper = new KieHelper( propertySpecificOption );
KieSession ks = helper.addContent( str, ResourceType.DRL ).build().newKieSession();
List list = new ArrayList();
ks.setGlobal( "list", list );
Expand Down
Expand Up @@ -60,7 +60,7 @@ public static List<String> getSettableProperties(InternalWorkingMemory workingMe
}

public static List<String> getSettableProperties( InternalKnowledgeBase kBase, ObjectTypeNode objectTypeNode ) {
return PropertySpecificUtil.getSettableProperties( kBase, getNodeClass( objectTypeNode ) );
return PropertySpecificUtil.getAccessibleProperties( kBase, getNodeClass( objectTypeNode ) );
}

public static Class<?> getNodeClass( ObjectTypeNode objectTypeNode ) {
Expand Down
Expand Up @@ -57,7 +57,7 @@
import static org.drools.core.common.DefaultFactHandle.determineIdentityHashCode;
import static org.drools.core.reteoo.PropertySpecificUtil.allSetButTraitBitMask;
import static org.drools.core.reteoo.PropertySpecificUtil.calculatePositiveMask;
import static org.drools.core.reteoo.PropertySpecificUtil.getSettableProperties;
import static org.drools.core.reteoo.PropertySpecificUtil.getAccessibleProperties;

public class CursoredDataSource<T> implements InternalDataSource<T> {

Expand Down Expand Up @@ -111,7 +111,7 @@ private FactHandle insertIntoWm( T object ) {
public void update(FactHandle handle, T object, String... modifiedProperties) {
BitMask mask = modifiedProperties == null || modifiedProperties.length == 0 ?
allSetButTraitBitMask() :
calculatePositiveMask(asList(modifiedProperties), getSettableProperties(workingMemory.getKnowledgeBase(), object.getClass()));
calculatePositiveMask( asList(modifiedProperties), getAccessibleProperties( workingMemory.getKnowledgeBase(), object.getClass() ) );
internalUpdate((DataSourceFactHandle) handle, object, mask, Object.class, null);
}

Expand Down
Expand Up @@ -142,7 +142,7 @@ protected void computeModificationMasks( InternalKnowledgeBase knowledgeBase ) {

protected List<String> getAccessibleProperties( Object o, InternalKnowledgeBase knowledgeBase ) {
if ( knowledgeBase != null ) {
return PropertySpecificUtil.getSettableProperties( knowledgeBase, o.getClass() );
return PropertySpecificUtil.getAccessibleProperties( knowledgeBase, o.getClass() );
} else {
return ClassUtils.getAccessibleProperties( o.getClass() );
}
Expand Down
Expand Up @@ -116,7 +116,7 @@ public void initDeclaredMask(BuildContext context) {
// if property specific is not on, then accept all modification propagations
setDeclaredMask( AllSetBitMask.get() );
} else {
List<String> settableProperties = getSettableProperties(context.getKnowledgeBase(), objectClass);
List<String> settableProperties = getAccessibleProperties( context.getKnowledgeBase(), objectClass );
setDeclaredMask( calculatePositiveMask(pattern.getListenedProperties(), settableProperties) );
setNegativeMask( calculateNegativeMask(pattern.getListenedProperties(), settableProperties) );
}
Expand Down
Expand Up @@ -21,14 +21,17 @@
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.drools.core.RuleBaseConfiguration;
import org.drools.core.base.ClassObjectType;
import org.drools.core.common.BetaConstraints;
import org.drools.core.common.InternalFactHandle;
import org.drools.core.common.InternalWorkingMemory;
import org.drools.core.common.Memory;
import org.drools.core.common.WorkingMemoryAction;
import org.drools.core.impl.InternalKnowledgeBase;
import org.drools.core.marshalling.impl.PersisterHelper;
import org.drools.core.marshalling.impl.ProtobufInputMarshaller;
import org.drools.core.marshalling.impl.ProtobufInputMarshaller.TupleKey;
Expand All @@ -37,10 +40,16 @@
import org.drools.core.reteoo.builder.BuildContext;
import org.drools.core.rule.Accumulate;
import org.drools.core.rule.ContextEntry;
import org.drools.core.rule.Declaration;
import org.drools.core.rule.TypeDeclaration;
import org.drools.core.spi.Accumulator;
import org.drools.core.spi.AlphaNodeFieldConstraint;
import org.drools.core.spi.ObjectType;
import org.drools.core.spi.PropagationContext;
import org.drools.core.util.AbstractBaseLinkedListNode;
import org.drools.core.util.bitmask.BitMask;

import static org.drools.core.reteoo.PropertySpecificUtil.calculatePositiveMask;

/**
* AccumulateNode
Expand Down Expand Up @@ -82,11 +91,31 @@ public AccumulateNode(final int id,
this.unwrapRightObject = unwrapRightObject;
this.tupleMemoryEnabled = context.isTupleMemoryEnabled();

addAccFunctionDeclarationsToLeftMask( context.getKnowledgeBase(), leftInput, accumulate );

hashcode = this.leftInput.hashCode() ^
this.rightInput.hashCode() ^
this.accumulate.hashCode() ^
this.resultBinder.hashCode() ^
Arrays.hashCode( this.resultConstraints );

}

private void addAccFunctionDeclarationsToLeftMask( InternalKnowledgeBase kbase, LeftTupleSource leftInput, Accumulate accumulate ) {
BitMask leftMask = getLeftInferredMask();
ObjectType leftObjectType = leftInput.getObjectType();
if (leftObjectType instanceof ClassObjectType ) {
TypeDeclaration typeDeclaration = kbase.getExactTypeDeclaration( ((ClassObjectType) leftObjectType).getClassType() );
if (typeDeclaration != null && typeDeclaration.isPropertyReactive()) {
List<String> accessibleProperties = typeDeclaration.getAccessibleProperties();
for ( Declaration decl : accumulate.getRequiredDeclarations() ) {
if ( leftObjectType.equals( decl.getPattern().getObjectType() ) ) {
leftMask = leftMask.setAll( calculatePositiveMask( decl.getPattern().getListenedProperties(), accessibleProperties ) );
}
}
}
}
setLeftInferredMask( leftMask );
}

public void readExternal( ObjectInput in ) throws IOException,
Expand Down
Expand Up @@ -169,10 +169,10 @@ protected void initDeclaredMask(BuildContext context,
Class objectClass = ((ClassObjectType) objectType).getClassType();
if (isPropertyReactive(context, objectClass)) {
rightListenedProperties = pattern.getListenedProperties();
List<String> settableProperties = getSettableProperties(context.getKnowledgeBase(), objectClass);
rightDeclaredMask = calculatePositiveMask(rightListenedProperties, settableProperties);
rightDeclaredMask = rightDeclaredMask.setAll(constraints.getListenedPropertyMask(settableProperties));
rightNegativeMask = calculateNegativeMask(rightListenedProperties, settableProperties);
List<String> accessibleProperties = getAccessibleProperties( context.getKnowledgeBase(), objectClass );
rightDeclaredMask = calculatePositiveMask(rightListenedProperties, accessibleProperties);
rightDeclaredMask = rightDeclaredMask.setAll(constraints.getListenedPropertyMask(accessibleProperties));
rightNegativeMask = calculateNegativeMask(rightListenedProperties, accessibleProperties);
} else {
// if property reactive is not on, then accept all modification propagations
rightDeclaredMask = AllSetBitMask.get();
Expand Down
Expand Up @@ -115,7 +115,7 @@ private BitMask calculateSinkMask(BuildContext context) {
Class objectClass = ((ClassWireable) objectType).getClassType();
return isPropertyReactive( context, objectClass ) ?
calculatePositiveMask( pattern.getListenedProperties(),
getSettableProperties( context.getKnowledgeBase(), objectClass ) ) :
getAccessibleProperties( context.getKnowledgeBase(), objectClass ) ) :
AllSetBitMask.get();
}

Expand Down
Expand Up @@ -254,7 +254,7 @@ protected void initDeclaredMask(BuildContext context,
// TODO: at the moment if pattern is null (e.g. for eval node) we cannot calculate the mask, so we leave it to 0
if ( pattern != null ) {
Collection<String> leftListenedProperties = pattern.getListenedProperties();
List<String> settableProperties = getSettableProperties( context.getKnowledgeBase(), objectClass );
List<String> settableProperties = getAccessibleProperties( context.getKnowledgeBase(), objectClass );
leftDeclaredMask = calculatePositiveMask( leftListenedProperties, settableProperties );
leftNegativeMask = calculateNegativeMask( leftListenedProperties, settableProperties );
setLeftListenedProperties(leftListenedProperties);
Expand Down
Expand Up @@ -16,6 +16,12 @@

package org.drools.core.reteoo;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.List;

import org.drools.core.base.ClassObjectType;
import org.drools.core.common.BaseNode;
import org.drools.core.common.DefaultFactHandle;
Expand All @@ -32,13 +38,7 @@
import org.drools.core.util.bitmask.BitMask;
import org.drools.core.util.bitmask.EmptyBitMask;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.List;

import static org.drools.core.reteoo.PropertySpecificUtil.getSettableProperties;
import static org.drools.core.reteoo.PropertySpecificUtil.getAccessibleProperties;

/**
* A source of <code>FactHandle</code>s for an <code>ObjectSink</code>.
Expand Down Expand Up @@ -152,7 +152,7 @@ public void initDeclaredMask(BuildContext context) {
// if property specific is not on, then accept all modification propagations
declaredMask = AllSetBitMask.get();
} else {
List<String> settableProperties = getSettableProperties(context.getKnowledgeBase(), objectClass);
List<String> settableProperties = getAccessibleProperties( context.getKnowledgeBase(), objectClass );
declaredMask = calculateDeclaredMask(settableProperties);
}
}
Expand Down
Expand Up @@ -111,7 +111,7 @@ public static boolean isPropertySetOnMask(BitMask mask, int index) {
return mask.isSet(index + CUSTOM_BITS_OFFSET);
}

public static List<String> getSettableProperties(InternalKnowledgeBase kBase, Class<?> nodeClass) {
public static List<String> getAccessibleProperties( InternalKnowledgeBase kBase, Class<?> nodeClass ) {
return kBase.getOrCreateExactTypeDeclaration(nodeClass).getAccessibleProperties();
}
}

0 comments on commit fa39028

Please sign in to comment.