[jboss-svn-commits] JBL Code SVN: r19287 - in labs/jbossrules/trunk/drools-core/src: test/java/org/drools/reteoo and 1 other directory.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Mar 28 01:31:20 EDT 2008
Author: mark.proctor at jboss.com
Date: 2008-03-28 01:31:19 -0400 (Fri, 28 Mar 2008)
New Revision: 19287
Modified:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AccumulateNodeTest.java
Log:
JBRULES-1520 RightTuple merge for asymmetrical Rete propagations
-Fixed AccumulateNode and AccumulateNodeTest
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java 2008-03-28 04:58:25 UTC (rev 19286)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/AccumulateNode.java 2008-03-28 05:31:19 UTC (rev 19287)
@@ -27,6 +27,7 @@
import org.drools.common.BetaConstraints;
import org.drools.common.InternalFactHandle;
import org.drools.common.InternalWorkingMemory;
+import org.drools.reteoo.CollectNode.CollectMemory;
import org.drools.reteoo.builder.BuildContext;
import org.drools.rule.Accumulate;
import org.drools.rule.ContextEntry;
@@ -36,6 +37,7 @@
import org.drools.util.Entry;
import org.drools.util.FactEntry;
import org.drools.util.Iterator;
+import org.drools.util.ObjectHashMap;
import org.drools.util.ObjectHashMap.ObjectEntry;
/**
@@ -125,9 +127,9 @@
if ( this.tupleMemoryEnabled ) {
memory.betaMemory.getLeftTupleMemory().add( leftTuple );
- memory.betaMemory.getCreatedHandles().put( leftTuple,
- accresult,
- false );
+ memory.resultMap.put( leftTuple,
+ accresult,
+ false );
}
final Object accContext = this.accumulate.createContext();
@@ -138,13 +140,12 @@
leftTuple,
workingMemory );
- final Iterator it = memory.betaMemory.getRightTupleMemory().iterator( leftTuple );
this.constraints.updateFromTuple( memory.betaMemory.getContext(),
workingMemory,
leftTuple );
- for ( FactEntry entry = (FactEntry) it.next(); entry != null; entry = (FactEntry) it.next() ) {
- InternalFactHandle handle = entry.getFactHandle();
+ for ( RightTuple rightTuple = memory.betaMemory.getRightTupleMemory().getFirst( leftTuple ); rightTuple != null; rightTuple = (RightTuple) rightTuple.getNext() ) {
+ InternalFactHandle handle = rightTuple.getFactHandle();
if ( this.constraints.isAllowedCachedLeft( memory.betaMemory.getContext(),
handle ) ) {
if ( this.unwrapRightObject ) {
@@ -182,6 +183,9 @@
final InternalFactHandle handle = workingMemory.getFactHandleFactory().newFactHandle( result,
false,
workingMemory ); // so far, result is not an event
+
+ final RightTuple resultTuple = new RightTuple( handle,
+ this );
for ( int i = 0, length = this.resultConstraints.length; i < length; i++ ) {
if ( !this.resultConstraints[i].isAllowed( handle,
@@ -197,10 +201,8 @@
leftTuple );
if ( this.resultBinder.isAllowedCachedLeft( memory.resultsContext,
handle ) ) {
- accresult.handle = handle;
-
this.sink.propagateAssertLeftTuple( leftTuple,
- handle,
+ resultTuple,
context,
workingMemory );
} else {
@@ -223,22 +225,13 @@
final PropagationContext context,
final InternalWorkingMemory workingMemory) {
final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory( this );
- if ( memory.betaMemory.getLeftTupleMemory().remove( leftTuple ) == null ) {
- return;
- }
- final AccumulateResult accresult = (AccumulateResult) memory.betaMemory.getCreatedHandles().remove( leftTuple );
+ memory.betaMemory.getLeftTupleMemory().remove( leftTuple );
+
+ memory.resultMap.remove( leftTuple );
- // if tuple was propagated
- if ( accresult.handle != null ) {
- this.sink.propagateRetractLeftTuple( leftTuple,
- accresult.handle,
- context,
- workingMemory );
-
- // Destroying the acumulate result object
- workingMemory.getFactHandleFactory().destroyFactHandle( accresult.handle );
- }
-
+ this.sink.propagateRetractLeftTupleDestroyRightTuple( leftTuple,
+ context,
+ workingMemory );
}
/**
@@ -255,7 +248,9 @@
final InternalWorkingMemory workingMemory) {
final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory( this );
- memory.betaMemory.getRightTupleMemory().add( factHandle );
+ final RightTuple rightTuple = new RightTuple( factHandle,
+ this );
+ memory.betaMemory.getRightTupleMemory().add( rightTuple );
if ( !this.tupleMemoryEnabled ) {
// do nothing here, as we know there are no left tuples at this stage in sequential mode.
@@ -299,13 +294,13 @@
* If an object is retract, call modify tuple for each
* tuple match.
*/
- public void retractObject(final InternalFactHandle handle,
+ public void retractRightTuple(final RightTuple rightTuple,
final PropagationContext context,
final InternalWorkingMemory workingMemory) {
final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory( this );
- if ( !memory.betaMemory.getRightTupleMemory().remove( handle ) ) {
- return;
- }
+ memory.betaMemory.getRightTupleMemory().remove( rightTuple );
+
+ InternalFactHandle handle = rightTuple.getFactHandle();
this.constraints.updateFromFactHandle( memory.betaMemory.getContext(),
workingMemory,
@@ -343,20 +338,13 @@
final InternalWorkingMemory workingMemory) {
final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory( this );
- AccumulateResult accresult = (AccumulateResult) memory.betaMemory.getCreatedHandles().get( leftTuple );
+ AccumulateResult accresult = (AccumulateResult) memory.resultMap.get( leftTuple );
// if tuple was propagated
- if ( accresult.handle != null ) {
- this.sink.propagateRetractLeftTuple( leftTuple,
- accresult.handle,
- context,
- workingMemory );
+ this.sink.propagateRetractLeftTupleDestroyRightTuple( leftTuple,
+ context,
+ workingMemory );
- // Destroying the acumulate result object
- workingMemory.getFactHandleFactory().destroyFactHandle( accresult.handle );
- accresult.handle = null;
- }
-
LeftTuple tuple = leftTuple;
if ( this.unwrapRightObject ) {
// if there is a subnetwork, handle must be unwrapped
@@ -420,6 +408,10 @@
final InternalFactHandle createdHandle = workingMemory.getFactHandleFactory().newFactHandle( result,
false,
workingMemory ); // so far, result is not an event
+
+ final RightTuple resultTuple = new RightTuple( handle,
+ this );
+
for ( int i = 0, length = this.resultConstraints.length; i < length; i++ ) {
if ( !this.resultConstraints[i].isAllowed( createdHandle,
workingMemory,
@@ -434,10 +426,8 @@
leftTuple );
if ( this.resultBinder.isAllowedCachedLeft( memory.resultsContext,
createdHandle ) ) {
- accresult.handle = createdHandle;
-
this.sink.propagateAssertLeftTuple( leftTuple,
- createdHandle,
+ resultTuple,
context,
workingMemory );
} else {
@@ -455,12 +445,12 @@
final InternalWorkingMemory workingMemory) {
final AccumulateMemory memory = (AccumulateMemory) workingMemory.getNodeMemory( this );
- final Iterator it = memory.betaMemory.getCreatedHandles().iterator();
-
- for ( ObjectEntry entry = (ObjectEntry) it.next(); entry != null; entry = (ObjectEntry) it.next() ) {
- AccumulateResult accresult = (AccumulateResult) entry.getValue();
- sink.assertLeftTuple( new LeftTuple( (LeftTuple) entry.getKey(),
- accresult.handle ),
+ final Iterator tupleIter = memory.betaMemory.getLeftTupleMemory().iterator();
+ for ( LeftTuple leftTuple = (LeftTuple) tupleIter.next(); leftTuple != null; leftTuple = (LeftTuple) tupleIter.next() ) {
+ RightTuple rightTuple = leftTuple.getBetaChildren().getRightParent();
+ sink.assertLeftTuple( new LeftTuple( leftTuple,
+ rightTuple,
+ sink ),
context,
workingMemory );
}
@@ -505,6 +495,7 @@
public Object createMemory(final RuleBaseConfiguration config) {
AccumulateMemory memory = new AccumulateMemory();
memory.betaMemory = this.constraints.createBetaMemory( config );
+ memory.resultMap = new ObjectHashMap();
memory.workingMemoryContext = this.accumulate.createWorkingMemoryContext();
memory.resultsContext = this.resultBinder.createContext();
memory.alphaContexts = new ContextEntry[this.resultConstraints.length];
@@ -521,6 +512,7 @@
public Object workingMemoryContext;
public BetaMemory betaMemory;
+ public ObjectHashMap resultMap;
public ContextEntry[] resultsContext;
public ContextEntry[] alphaContexts;
@@ -528,6 +520,7 @@
ClassNotFoundException {
workingMemoryContext = in.readObject();
betaMemory = (BetaMemory) in.readObject();
+ resultMap = (ObjectHashMap) in.readObject();
resultsContext = (ContextEntry[]) in.readObject();
alphaContexts = (ContextEntry[]) in.readObject();
}
@@ -535,6 +528,7 @@
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject( workingMemoryContext );
out.writeObject( betaMemory );
+ out.writeObject( resultMap );
out.writeObject( resultsContext );
out.writeObject( alphaContexts );
}
@@ -544,18 +538,14 @@
public static class AccumulateResult
implements
Externalizable {
- // keeping attributes public just for performance
- public InternalFactHandle handle;
public Object context;
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
- handle = (InternalFactHandle) in.readObject();
context = in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
- out.writeObject( handle );
out.writeObject( context );
}
Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AccumulateNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AccumulateNodeTest.java 2008-03-28 04:58:25 UTC (rev 19286)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/AccumulateNodeTest.java 2008-03-28 05:31:19 UTC (rev 19287)
@@ -49,7 +49,7 @@
ReteooWorkingMemory workingMemory;
MockObjectSource objectSource;
MockTupleSource tupleSource;
- MockLeftTupleSink sink;
+ MockLeftTupleSink sink;
BetaNode node;
BetaMemory memory;
MockConstraint constraint = new MockConstraint();
@@ -66,11 +66,11 @@
PropagationContext.ASSERTION,
null,
null );
-
+
ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
BuildContext buildContext = new BuildContext( ruleBase,
ruleBase.getReteooBuilder().getIdGenerator() );
-
+
this.workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession();
this.tupleSource = new MockTupleSource( 4 );
@@ -81,13 +81,11 @@
final ObjectType srcObjType = new ClassObjectType( String.class );
final Pattern sourcePattern = new Pattern( 0,
- srcObjType );
+ srcObjType );
this.accumulate = new Accumulate( sourcePattern,
new Declaration[0],
new Declaration[0],
this.accumulator );
-
-
this.node = new AccumulateNode( 15,
this.tupleSource,
@@ -128,12 +126,18 @@
0,
this.sink.getAsserted().size() );
- this.node.assertLeftTuple( new LeftTuple( this.workingMemory.getFactHandleFactory().newFactHandle( "cheese", false, null ) ),
- this.context,
- this.workingMemory );
- this.node.assertLeftTuple( new LeftTuple( this.workingMemory.getFactHandleFactory().newFactHandle( "other cheese", false, null ) ),
- this.context,
- this.workingMemory );
+ this.node.assertLeftTuple( new LeftTuple( this.workingMemory.getFactHandleFactory().newFactHandle( "cheese",
+ false,
+ null ),
+ null ),
+ this.context,
+ this.workingMemory );
+ this.node.assertLeftTuple( new LeftTuple( this.workingMemory.getFactHandleFactory().newFactHandle( "other cheese",
+ false,
+ null ),
+ null ),
+ this.context,
+ this.workingMemory );
Assert.assertEquals( "Two tuples should have been propagated",
2,
@@ -155,13 +159,16 @@
* Test method for {@link org.drools.reteoo.AccumulateNode#assertLeftTuple(org.drools.reteoo.LeftTuple, org.drools.spi.PropagationContext, org.drools.reteoo.ReteooWorkingMemory)}.
*/
public void testAssertTuple() {
- final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "cheese", false, null );
- final LeftTuple tuple0 = new LeftTuple( f0 );
+ final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "cheese",
+ false,
+ null );
+ final LeftTuple tuple0 = new LeftTuple( f0,
+ null );
// assert tuple, should add one to left memory
this.node.assertLeftTuple( tuple0,
- this.context,
- this.workingMemory );
+ this.context,
+ this.workingMemory );
// check memories
assertEquals( 1,
this.memory.getLeftTupleMemory().size() );
@@ -171,12 +178,15 @@
this.accumulator.getMatchingObjects().isEmpty() );
// assert tuple, should add left memory
- final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "other cheese", false, null );
+ final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "other cheese",
+ false,
+ null );
- final LeftTuple tuple1 = new LeftTuple( f1 );
+ final LeftTuple tuple1 = new LeftTuple( f1,
+ null );
this.node.assertLeftTuple( tuple1,
- this.context,
- this.workingMemory );
+ this.context,
+ this.workingMemory );
assertEquals( 2,
this.memory.getLeftTupleMemory().size() );
Assert.assertTrue( "An empty matching objects list should be propagated",
@@ -195,10 +205,15 @@
* Test method for {@link org.drools.reteoo.AccumulateNode#assertLeftTuple(org.drools.reteoo.LeftTuple, org.drools.spi.PropagationContext, org.drools.reteoo.ReteooWorkingMemory)}.
*/
public void testAssertTupleWithObjects() {
- final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "cheese", false, null );
- final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "other cheese", false, null );
+ final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "cheese",
+ false,
+ null );
+ final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "other cheese",
+ false,
+ null );
- final LeftTuple tuple0 = new LeftTuple( f0 );
+ final LeftTuple tuple0 = new LeftTuple( f0,
+ null );
this.node.assertObject( f0,
this.context,
@@ -209,8 +224,8 @@
// assert tuple, should add one to left memory
this.node.assertLeftTuple( tuple0,
- this.context,
- this.workingMemory );
+ this.context,
+ this.workingMemory );
// check memories
assertEquals( 1,
this.memory.getLeftTupleMemory().size() );
@@ -221,10 +236,11 @@
this.accumulator.getMatchingObjects().size() );
// assert tuple, should add left memory
- final LeftTuple tuple1 = new LeftTuple( f1 );
+ final LeftTuple tuple1 = new LeftTuple( f1,
+ null );
this.node.assertLeftTuple( tuple1,
- this.context,
- this.workingMemory );
+ this.context,
+ this.workingMemory );
assertEquals( 2,
this.memory.getLeftTupleMemory().size() );
Assert.assertEquals( "Wrong number of elements in matching objects list ",
@@ -244,14 +260,17 @@
* Test method for {@link org.drools.reteoo.AccumulateNode#retractLeftTuple(org.drools.reteoo.LeftTuple, org.drools.spi.PropagationContext, org.drools.reteoo.ReteooWorkingMemory)}.
*/
public void testRetractTuple() {
- final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "cheese", false, null );
+ final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "cheese",
+ false,
+ null );
- final LeftTuple tuple0 = new LeftTuple( f0 );
+ final LeftTuple tuple0 = new LeftTuple( f0,
+ null );
// assert tuple, should add one to left memory
this.node.assertLeftTuple( tuple0,
- this.context,
- this.workingMemory );
+ this.context,
+ this.workingMemory );
// check memories
assertEquals( 1,
this.memory.getLeftTupleMemory().size() );
@@ -261,8 +280,8 @@
this.accumulator.getMatchingObjects().isEmpty() );
this.node.retractLeftTuple( tuple0,
- this.context,
- this.workingMemory );
+ this.context,
+ this.workingMemory );
assertEquals( 0,
this.memory.getLeftTupleMemory().size() );
assertEquals( 1,
@@ -275,15 +294,20 @@
* Test method for {@link org.drools.reteoo.AccumulateNode#assertObject(InternalFactHandle, org.drools.spi.PropagationContext, InternalWorkingMemory)}.
*/
public void testAssertObject() {
- final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "cheese", false, null );
- final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "other cheese", false, null );
+ final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "cheese",
+ false,
+ null );
+ final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "other cheese",
+ false,
+ null );
- final LeftTuple tuple0 = new LeftTuple( f0 );
+ final LeftTuple tuple0 = new LeftTuple( f0,
+ null );
// assert tuple, should add one to left memory
this.node.assertLeftTuple( tuple0,
- this.context,
- this.workingMemory );
+ this.context,
+ this.workingMemory );
// check memory
assertEquals( 1,
@@ -320,10 +344,15 @@
* Test method for {@link org.drools.reteoo.AccumulateNode#retractObject(InternalFactHandle, org.drools.spi.PropagationContext, InternalWorkingMemory)}.
*/
public void testRetractObject() {
- final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "cheese", false, null );
- final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "other cheese", false, null );
+ final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "cheese",
+ false,
+ null );
+ final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "other cheese",
+ false,
+ null );
- final LeftTuple tuple0 = new LeftTuple( f0 );
+ final LeftTuple tuple0 = new LeftTuple( f0,
+ null );
this.node.assertObject( f0,
this.context,
@@ -336,8 +365,8 @@
// assert tuple, should add one to left memory
this.node.assertLeftTuple( tuple0,
- this.context,
- this.workingMemory );
+ this.context,
+ this.workingMemory );
// check memory
assertEquals( 1,
@@ -349,9 +378,9 @@
assertEquals( 2,
this.accumulator.getMatchingObjects().size() );
- this.node.retractObject( f1,
- this.context,
- this.workingMemory );
+ this.node.retractRightTuple( f1.getRightTuple(),
+ this.context,
+ this.workingMemory );
assertEquals( 1,
this.memory.getRightTupleMemory().size() );
assertEquals( 1,
@@ -361,9 +390,9 @@
assertEquals( 1,
this.accumulator.getMatchingObjects().size() );
- this.node.retractObject( f0,
- this.context,
- this.workingMemory );
+ this.node.retractRightTuple( f0.getRightTuple(),
+ this.context,
+ this.workingMemory );
assertEquals( 0,
this.memory.getRightTupleMemory().size() );
assertEquals( 2,
@@ -379,7 +408,7 @@
ReteooRuleBase ruleBase = (ReteooRuleBase) RuleBaseFactory.newRuleBase();
BuildContext buildContext = new BuildContext( ruleBase,
ruleBase.getReteooBuilder().getIdGenerator() );
-
+
this.workingMemory = (ReteooWorkingMemory) ruleBase.newStatefulSession();
final MockObjectSource objectSource = new MockObjectSource( 1 );
@@ -393,7 +422,7 @@
EmptyBetaConstraints.getInstance(),
this.accumulate,
false,
- buildContext );
+ buildContext );
final BetaMemory memory = ((AccumulateMemory) this.workingMemory.getNodeMemory( accumulateNode )).betaMemory;
@@ -424,17 +453,21 @@
false,
buildContext );
- this.node.addTupleSink( this.sink );
-
+ this.node.addTupleSink( this.sink );
+
this.workingMemory = new ReteooWorkingMemory( 1,
(ReteooRuleBase) RuleBaseFactory.newRuleBase( conf ) );
-
+
this.memory = ((AccumulateMemory) this.workingMemory.getNodeMemory( this.node )).betaMemory;
- final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "cheese", false, null );
- final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "other cheese", false, null );
+ final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "cheese",
+ false,
+ null );
+ final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.getFactHandleFactory().newFactHandle( "other cheese",
+ false,
+ null );
- final LeftTuple tuple0 = new LeftTuple( f0 );
+ final LeftTuple tuple0 = new LeftTuple( f0, null );
this.node.assertObject( f0,
this.context,
@@ -445,8 +478,8 @@
// assert tuple, should not add to left memory, since we are in sequential mode
this.node.assertLeftTuple( tuple0,
- this.context,
- this.workingMemory );
+ this.context,
+ this.workingMemory );
// check memories
assertNull( this.memory.getLeftTupleMemory() );
assertEquals( 2,
@@ -456,10 +489,10 @@
this.accumulator.getMatchingObjects().size() );
// assert tuple, should not add left memory
- final LeftTuple tuple1 = new LeftTuple( f1 );
+ final LeftTuple tuple1 = new LeftTuple( f1, null );
this.node.assertLeftTuple( tuple1,
- this.context,
- this.workingMemory );
+ this.context,
+ this.workingMemory );
assertNull( this.memory.getLeftTupleMemory() );
Assert.assertEquals( "Wrong number of elements in matching objects list ",
2,
More information about the jboss-svn-commits
mailing list