Skip to content

Commit

Permalink
JBRULES-3343 Property Specific
Browse files Browse the repository at this point in the history
-Large rewrite for how masks are determined and used in the network
-All mask determination is now done at compile time
-Rule Removal is now supported
  • Loading branch information
Mark Proctor committed Feb 27, 2012
1 parent 4055a5b commit 5dad95a
Show file tree
Hide file tree
Showing 11 changed files with 1,287 additions and 200 deletions.

Large diffs are not rendered by default.

Expand Up @@ -519,7 +519,8 @@ public void addPackages( final Collection<Package> newPkgs ) {
// with the classloader recreated for all byte[] classes, we should now merge and wire any new accessors
pkg.getClassFieldAccessorStore().merge( newPkg.getClassFieldAccessorStore() );
}


// Add all Type Declarations, this has to be done first incase packages cross reference each other during build process.
for (Package newPkg : newPkgs) {
Package pkg = this.pkgs.get( newPkg.getName() );

Expand Down Expand Up @@ -554,6 +555,10 @@ public void addPackages( final Collection<Package> newPkgs ) {
"unable to resolve Type Declaration class '" + lastType.getTypeName() +
"'" );
}
}

for (Package newPkg : newPkgs) {
Package pkg = this.pkgs.get( newPkg.getName() );

// now merge the new package into the existing one
mergePackage( pkg,
Expand Down
3 changes: 2 additions & 1 deletion drools-core/src/main/java/org/drools/common/BaseNode.java
Expand Up @@ -101,6 +101,7 @@ public void remove(RuleRemovalContext context,
ReteooBuilder builder,
BaseNode node,
InternalWorkingMemory[] workingMemories) {
context.getRemovedNodes().add( this );
this.removeAssociation( context.getRule() );
doRemove( context,
builder,
Expand Down Expand Up @@ -184,5 +185,5 @@ public Map<Rule, RuleComponent> getAssociations() {
*/
public void removeAssociation( Rule rule ) {
this.associations.remove( rule );
}
}
}
2 changes: 2 additions & 0 deletions drools-core/src/main/java/org/drools/common/NetworkNode.java
Expand Up @@ -18,6 +18,8 @@

import java.io.Externalizable;

import org.drools.definition.rule.Rule;

/**
* Interface used to expose generic information on Rete nodes outside of he package. It is used
* for exposing information events.
Expand Down
137 changes: 98 additions & 39 deletions drools-core/src/main/java/org/drools/reteoo/AlphaNode.java
Expand Up @@ -22,6 +22,7 @@
import java.util.List;

import org.drools.RuleBaseConfiguration;
import org.drools.base.ClassObjectType;
import org.drools.common.InternalFactHandle;
import org.drools.common.InternalWorkingMemory;
import org.drools.common.NodeMemory;
Expand All @@ -30,12 +31,16 @@
import org.drools.common.SharableNode;
import org.drools.reteoo.builder.BuildContext;
import org.drools.rule.ContextEntry;
import org.drools.rule.Pattern;
import org.drools.rule.TypeDeclaration;
import org.drools.rule.constraint.MvelConstraint;
import org.drools.spi.AlphaNodeFieldConstraint;
import org.drools.spi.ObjectType;
import org.drools.spi.PropagationContext;

import static org.drools.core.util.BitMaskUtil.intersect;
import static org.drools.reteoo.PropertySpecificUtil.addListenedPropertiesToMask;
import static org.drools.reteoo.PropertySpecificUtil.calculateMaskFromPattern;
import static org.drools.reteoo.PropertySpecificUtil.getNodeClass;
import static org.drools.reteoo.PropertySpecificUtil.getSettableProperties;

Expand All @@ -61,7 +66,7 @@ public class AlphaNode extends ObjectSource
private ObjectSinkNode nextRightTupleSinkNode;

private long declaredMask;
private long networkMask;
private long inferredMask;

public AlphaNode() {

Expand Down Expand Up @@ -89,36 +94,59 @@ public AlphaNode(final int id,
context.getRuleBase().getConfiguration().getAlphaNodeHashingThreshold() );
this.constraint = constraint;

initPropertySpecificMask(context);
initDeclaredMask(context);
}

private void initPropertySpecificMask(BuildContext context) {
Class<?> nodeClass = getNodeClass(getObjectTypeNode());
List<String> settableProperties = getSettableProperties(context.getRuleBase(), nodeClass);
if (settableProperties != null) {
declaredMask = calculateDeclaredMask(settableProperties);
networkMask = declaredMask;
public void initDeclaredMask(BuildContext context) {
Pattern pattern = context.getLastBuiltPatterns()[0];
ObjectType objectType = pattern.getObjectType();

if ( !(objectType instanceof ClassObjectType)) {
// Only ClassObjectType can use property specific
declaredMask = Long.MAX_VALUE;
return;
}

List<String> listenedProperties = context.getListenedPropertiesFor(nodeClass);
if (listenedProperties != null) {
networkMask = addListenedPropertiesToMask(listenedProperties, networkMask, settableProperties);

Class objectClass = ((ClassObjectType)objectType).getClassType();
TypeDeclaration typeDeclaration = context.getRuleBase().getTypeDeclaration(objectClass);
if ( !typeDeclaration.isPropertySpecific() ) {
// if property specific is not on, then accept all modification propagations
declaredMask = Long.MAX_VALUE;
} else {
List<String> settableProperties = getSettableProperties(context.getRuleBase(), objectClass);
declaredMask = calculateDeclaredMask(settableProperties);
}
}

public void resetInferredMask() {
this.inferredMask = 0;
}

public long updateMask(long mask) {
long returnMask;
if (source instanceof AlphaNode) {
returnMask = ((AlphaNode) source).updateMask( declaredMask | mask );
} else { // else ObjectTypeNode
returnMask = declaredMask | mask;
}
inferredMask = inferredMask | returnMask;
return returnMask;

}

public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
super.readExternal( in );
constraint = (AlphaNodeFieldConstraint) in.readObject();
declaredMask = in.readLong();
networkMask = in.readLong();
inferredMask = in.readLong();
}

public void writeExternal(ObjectOutput out) throws IOException {
super.writeExternal(out);
out.writeObject(constraint);
out.writeLong(declaredMask);
out.writeLong(networkMask);
out.writeLong(inferredMask);
}

/**
Expand All @@ -136,7 +164,7 @@ public AlphaNodeFieldConstraint getConstraint() {
* @see org.drools.reteoo.BaseNode#attach()
*/
public void attach() {
this.source.addObjectSink( this );
this.source.addObjectSink( this );
}

public void attach(final InternalWorkingMemory[] workingMemories) {
Expand All @@ -153,8 +181,8 @@ public void attach(final InternalWorkingMemory[] workingMemories) {
propagationContext,
workingMemory );
}
}

}
public void assertObject(final InternalFactHandle factHandle,
final PropagationContext context,
final InternalWorkingMemory workingMemory) {
Expand All @@ -173,12 +201,7 @@ public void modifyObject(final InternalFactHandle factHandle,
final ModifyPreviousTuples modifyPreviousTuples,
final PropagationContext context,
final InternalWorkingMemory workingMemory) {

long propagationMask = context.getPropagationMask();
if ( context.getModificationMask() == Long.MAX_VALUE ||
intersect(context.getModificationMask(), propagationMask | networkMask) ) {

context.setPropagationMask(propagationMask | declaredMask);
if ( intersect(context.getModificationMask(), inferredMask ) ) {

final AlphaMemory memory = (AlphaMemory) workingMemory.getNodeMemory( this );
if ( this.constraint.isAllowed( factHandle,
Expand All @@ -189,8 +212,6 @@ public void modifyObject(final InternalFactHandle factHandle,
context,
workingMemory );
}

context.setPropagationMask(propagationMask);
} else {
byPassModifyToBetaNode(modifyPreviousTuples);
}
Expand Down Expand Up @@ -378,26 +399,64 @@ private long calculateDeclaredMask(List<String> settableProperties) {
@Override
public long getDeclaredMask() {
return declaredMask;
}

public long getInferredMask() {
return inferredMask;
}

@Override
public void addObjectSink(final ObjectSink objectSink) {
super.addObjectSink(objectSink);
addToNetworkMask(objectSink);
public void setInferredMask(long inferredMask) {
this.inferredMask = inferredMask;
}

private void addToNetworkMask(ObjectSink objectSink) {
if (objectSink instanceof AlphaNode) {
networkMask |= ((AlphaNode)objectSink).networkMask;
} else if (objectSink instanceof BetaNode) {
networkMask |= ((BetaNode)objectSink).getDeclaredMask();
}
if (source instanceof AlphaNode) {
((AlphaNode)source).addToNetworkMask(this);
}
public void setDeclaredMask(long declaredMask) {
this.declaredMask = declaredMask;
}

@Override
public void addObjectSink(final ObjectSink objectSink) {
super.addObjectSink(objectSink);
}

// private long updateMask(ObjectSink objectSink) {
// long mask = 0;
// if (objectSink instanceof AlphaNode) {
// mask = ((AlphaNode)objectSink).networkMask;
// }
//
// if (source instanceof AlphaNode) {
// return mask | ((AlphaNode)source).updateMask(this, mask);
// } else { // instanceof ObjectTypeNode
// return mask;
// }
// }
//
// private long updateMask(ObjectSink objectSink, long mask) {
// if (objectSink instanceof AlphaNode) {
// inferredMask = inferredMask | mask;
// //return de
// //networkMask |= ((AlphaNode)objectSink).networkMask;
// }
//
// if (source instanceof AlphaNode) {
// return mask | ((AlphaNode)source).updateMask(this, mask);
// } else { // instanceof ObjectTypeNode
// return mask;
// }
// }

// private void addToNetworkMask(ObjectSink objectSink) {
// if (objectSink instanceof AlphaNode) {
// networkMask |= ((AlphaNode)objectSink).networkMask;
// } else if (objectSink instanceof BetaNode) {
// networkMask |= ((BetaNode)objectSink).getDeclaredMask();
// }
// if (source instanceof AlphaNode) {
// ((AlphaNode)source).addToNetworkMask(this);
// }
// }
//
public void sharedWith(AlphaNode node) {
networkMask |= node.networkMask;
//networkMask |= node.networkMask;
}
}

0 comments on commit 5dad95a

Please sign in to comment.