[jboss-svn-commits] JBL Code SVN: r7724 - in labs/jbossrules/trunk: drools-compiler/src/main/java/org/drools/semantics/java drools-core/src/main/java/org/drools/reteoo drools-core/src/test/java/org/drools/reteoo
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Nov 20 11:22:10 EST 2006
Author: tirelli
Date: 2006-11-20 11:21:55 -0500 (Mon, 20 Nov 2006)
New Revision: 7724
Added:
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ExistsNodeTest.java
Modified:
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/RuleBuilder.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryTerminalNode.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java
Log:
JBRULES-547: added specialized ExistsNode. Added unit test. All integration tests are green.
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/RuleBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/RuleBuilder.java 2006-11-20 13:47:52 UTC (rev 7723)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/RuleBuilder.java 2006-11-20 16:21:55 UTC (rev 7724)
@@ -289,7 +289,8 @@
this.innerDeclarations = null;
} else if ( object.getClass() == ExistsDescr.class ) {
- // We cannot have declarations created inside a not visible outside it, so track no declarations so they can be removed
+ // We cannot have declarations created inside exists visible outside it,
+ // so track declarations in a way they can be removed
this.innerDeclarations = new HashMap();
final Exists exists = new Exists();
build( this.rule,
Added: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java 2006-11-20 13:47:52 UTC (rev 7723)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java 2006-11-20 16:21:55 UTC (rev 7724)
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2006 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.reteoo;
+
+import org.drools.common.BetaConstraints;
+import org.drools.common.EmptyBetaConstraints;
+import org.drools.common.InternalFactHandle;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.spi.PropagationContext;
+import org.drools.util.Iterator;
+import org.drools.util.AbstractHashTable.FactEntry;
+
+/**
+ * <code>ExistsNode</code> extends <code>BetaNode</code> to perform tests for
+ * the existence of a Fact plus one or more conditions. Where existence
+ * is found the left ReteTuple is copied and propagated. Further to this it
+ * maintains the "truth" by cancelling any
+ * <code>Activation<code>s that are no longer
+ * considered true by the retraction of ReteTuple's or FactHandleImpl.
+ * Tuples are considered to be asserted from the left input and facts from the right input.
+ * The <code>BetaNode</code> provides the BetaMemory to store assserted ReteTuples and
+ * <code>FactHandleImpl<code>s. Each fact handle is stored in the right
+ * memory.
+ *
+ * @author <a href="mailto:etirelli at redhat.com">Edson Tirelli</a>
+ *
+ */
+public class ExistsNode extends BetaNode {
+
+ private static final long serialVersionUID = 2597133625232012026L;
+
+ static int notAssertObject = 0;
+ static int notAssertTuple = 0;
+
+ // ------------------------------------------------------------
+ // Instance methods
+ // ------------------------------------------------------------
+
+ /**
+ * Constructs a new Exists node with EmptyBetaConstraints.
+ *
+ * @paran id
+ * The unique id for this node.
+ * @param leftInput
+ * The left input <code>TupleSource</code>.
+ * @param rightInput
+ * The right input <code>ObjectSource</code>.
+ */
+ ExistsNode(final int id,
+ final TupleSource leftInput,
+ final ObjectSource rightInput) {
+ super( id,
+ leftInput,
+ rightInput,
+ EmptyBetaConstraints.getInstance() );
+ }
+
+ /**
+ * Construct.
+ *
+ * @paran id
+ * The unique id for this node.
+ * @param leftInput
+ * The left input <code>TupleSource</code>.
+ * @param rightInput
+ * The right input <code>ObjectSource</code>.
+ * @param joinNodeBinder
+ * The constraints to be aplied to the right objects
+ */
+ ExistsNode(final int id,
+ final TupleSource leftInput,
+ final ObjectSource rightInput,
+ final BetaConstraints joinNodeBinder) {
+ super( id,
+ leftInput,
+ rightInput,
+ joinNodeBinder );
+ }
+
+ /**
+ * Assert a new <code>ReteTuple</code> from the left input. It iterates
+ * over the right <code>FactHandleImpl</code>'s and if any match is found,
+ * a copy of the <code>ReteTuple</code> is made and propagated.
+ *
+ * @param tuple
+ * The <code>Tuple</code> being asserted.
+ * @param context
+ * The <code>PropagationContext</code>
+ * @param workingMemory
+ * The working memory seesion.
+ */
+ public void assertTuple(final ReteTuple leftTuple,
+ final PropagationContext context,
+ final InternalWorkingMemory workingMemory) {
+ final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
+ memory.getTupleMemory().add( leftTuple );
+
+ final Iterator it = memory.getFactHandleMemory().iterator( leftTuple );
+ this.constraints.updateFromTuple( workingMemory,
+ leftTuple );
+ int matches = 0;
+ for ( FactEntry entry = (FactEntry) it.next(); entry != null; entry = (FactEntry) it.next() ) {
+ final InternalFactHandle handle = entry.getFactHandle();
+ if ( this.constraints.isAllowedCachedLeft( handle.getObject() ) ) {
+ matches++;
+ }
+ }
+
+ leftTuple.setMatches( matches );
+
+ if ( matches > 0 ) {
+ this.sink.propagateAssertTuple( leftTuple,
+ context,
+ workingMemory );
+ }
+ }
+
+ /**
+ * Assert a new <code>FactHandleImpl</code> from the right input. If it
+ * matches any left ReteTuple's that had no matches before, propagate
+ * tuple as an assertion.
+ *
+ * @param handle
+ * The <code>FactHandleImpl</code> being asserted.
+ * @param context
+ * The <code>PropagationContext</code>
+ * @param workingMemory
+ * The working memory seesion.
+ */
+ public void assertObject(final InternalFactHandle handle,
+ final PropagationContext context,
+ final InternalWorkingMemory workingMemory) {
+ final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
+ memory.getFactHandleMemory().add( handle );
+
+ final Iterator it = memory.getTupleMemory().iterator( handle );
+ this.constraints.updateFromFactHandle( workingMemory,
+ handle );
+ for ( ReteTuple tuple = (ReteTuple) it.next(); tuple != null; tuple = (ReteTuple) it.next() ) {
+ if ( this.constraints.isAllowedCachedRight( tuple ) ) {
+ final int matches = tuple.getMatches();
+ tuple.setMatches( matches + 1 );
+
+ // if this is the first match, propagate tuple
+ if( tuple.getMatches() == 1 ) {
+ this.sink.propagateAssertTuple( tuple,
+ context,
+ workingMemory );
+ }
+ }
+ }
+ }
+
+ /**
+ * Retract the <code>FactHandleImpl</code>. If the handle has any
+ * <code>ReteTuple</code> matches and those tuples now have no
+ * other match, retract tuple
+ *
+ * @param handle
+ * the <codeFactHandleImpl</code> being retracted
+ * @param context
+ * The <code>PropagationContext</code>
+ * @param workingMemory
+ * The working memory seesion.
+ */
+ public void retractObject(final InternalFactHandle handle,
+ final PropagationContext context,
+ final InternalWorkingMemory workingMemory) {
+ final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
+ if ( !memory.getFactHandleMemory().remove( handle ) ) {
+ return;
+ }
+
+ final Iterator it = memory.getTupleMemory().iterator( handle );
+ this.constraints.updateFromFactHandle( workingMemory,
+ handle );
+ for ( ReteTuple tuple = (ReteTuple) it.next(); tuple != null; tuple = (ReteTuple) it.next() ) {
+ if ( this.constraints.isAllowedCachedRight( tuple ) ) {
+ tuple.setMatches( tuple.getMatches() - 1 );
+ if ( tuple.getMatches() == 0 ) {
+ this.sink.propagateRetractTuple( tuple,
+ context,
+ workingMemory );
+ }
+ }
+ }
+ }
+
+ /**
+ * Retract the
+ * <code>ReteTuple<code>, any resulting propagated joins are also retracted.
+ *
+ * @param leftTuple
+ * The tuple being retracted
+ * @param context
+ * The <code>PropagationContext</code>
+ * @param workingMemory
+ * The working memory seesion.
+ */
+ public void retractTuple(final ReteTuple leftTuple,
+ final PropagationContext context,
+ final InternalWorkingMemory workingMemory) {
+ final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
+
+ // Must use the tuple in memory as it has the tuple matches count
+ final ReteTuple tuple = (ReteTuple) memory.getTupleMemory().remove( leftTuple );
+ if ( tuple == null ) {
+ return;
+ }
+
+ if ( tuple.getMatches() > 0 ) {
+ this.sink.propagateRetractTuple( tuple,
+ context,
+ workingMemory );
+ }
+ }
+
+ /**
+ * Updates the given sink propagating all previously propagated tuples to it
+ *
+ */
+ public void updateSink(final TupleSink sink,
+ final PropagationContext context,
+ final InternalWorkingMemory workingMemory) {
+ final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
+
+ final Iterator tupleIter = memory.getTupleMemory().iterator();
+ for ( ReteTuple tuple = (ReteTuple) tupleIter.next(); tuple != null; tuple = (ReteTuple) tupleIter.next() ) {
+ if ( tuple.getMatches() > 0 ) {
+ sink.assertTuple( new ReteTuple( tuple ),
+ context,
+ workingMemory );
+ }
+ }
+ }
+
+ public String toString() {
+ ObjectSource source = this.rightInput;
+ while ( source.getClass() != ObjectTypeNode.class ) {
+ source = source.objectSource;
+ }
+
+ return "[ExistsNode - " + ((ObjectTypeNode) source).getObjectType() + "]";
+ }
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ExistsNode.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java 2006-11-20 13:47:52 UTC (rev 7723)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/NotNode.java 2006-11-20 16:21:55 UTC (rev 7724)
@@ -42,9 +42,7 @@
*
*/
public class NotNode extends BetaNode {
- /**
- *
- */
+
private static final long serialVersionUID = 320L;
static int notAssertObject = 0;
static int notAssertTuple = 0;
@@ -229,22 +227,16 @@
public void updateSink(final TupleSink sink,
final PropagationContext context,
final InternalWorkingMemory workingMemory) {
- // this.attachingNewNode = true;
- //
- // final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
- // for ( final Iterator it = memory.getLeftTupleMemory().iterator(); it.hasNext(); ) {
- // final ReteTuple leftTuple = (ReteTuple) it.next();
- // if ( leftTuple.matchesSize() == 0 ) {
- // final ReteTuple child = new ReteTuple( leftTuple );
- // // no TupleMatch so instead add as a linked tuple
- // leftTuple.addLinkedTuple( new LinkedListObjectWrapper( child ) );
- // ((TupleSink) getTupleSinks().get( getTupleSinks().size() - 1 )).assertTuple( child,
- // context,
- // workingMemory );
- // }
- // }
- //
- // this.attachingNewNode = true;
+ final BetaMemory memory = (BetaMemory) workingMemory.getNodeMemory( this );
+
+ final Iterator tupleIter = memory.getTupleMemory().iterator();
+ for ( ReteTuple tuple = (ReteTuple) tupleIter.next(); tuple != null; tuple = (ReteTuple) tupleIter.next() ) {
+ if ( tuple.getMatches() == 0 ) {
+ sink.assertTuple( new ReteTuple( tuple ),
+ context,
+ workingMemory );
+ }
+ }
}
public String toString() {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryTerminalNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryTerminalNode.java 2006-11-20 13:47:52 UTC (rev 7723)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/QueryTerminalNode.java 2006-11-20 16:21:55 UTC (rev 7724)
@@ -111,9 +111,6 @@
public void retractTuple(final ReteTuple tuple,
final PropagationContext context,
final InternalWorkingMemory workingMemory) {
- // following code is needed because of queries that eventually uses "exists"
- final LinkedList list = (LinkedList) workingMemory.getNodeMemory( this );
- list.remove( tuple );
}
public String toString() {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java 2006-11-20 13:47:52 UTC (rev 7723)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooBuilder.java 2006-11-20 16:21:55 UTC (rev 7724)
@@ -38,7 +38,6 @@
import org.drools.common.DefaultBetaConstraints;
import org.drools.common.DoubleBetaConstraints;
import org.drools.common.EmptyBetaConstraints;
-import org.drools.common.InstanceEqualsConstraint;
import org.drools.common.InstanceNotEqualsConstraint;
import org.drools.common.QuadroupleBetaConstraints;
import org.drools.common.SingleBetaConstraints;
@@ -479,28 +478,7 @@
tupleSource,
ObjectSource,
binder ) );
- if ( not.getChild() instanceof Not ) {
-
- final RightInputAdapterNode adapter = (RightInputAdapterNode) attachNode( new RightInputAdapterNode( this.id++,
- column,
- notNode ) );
- attachNot( tupleSource,
- (Not) not.getChild(),
- adapter,
- EmptyBetaConstraints.getInstance(),
- column );
- } else if ( not.getChild() instanceof Exists ) {
- final RightInputAdapterNode adapter = (RightInputAdapterNode) attachNode( new RightInputAdapterNode( this.id++,
- column,
- notNode ) );
- attachExists( tupleSource,
- (Exists) not.getChild(),
- adapter,
- EmptyBetaConstraints.getInstance(),
- column );
- } else {
- this.tupleSource = notNode;
- }
+ this.tupleSource = notNode;
}
private void attachExists(final TupleSource tupleSource,
@@ -508,41 +486,11 @@
final ObjectSource ObjectSource,
final BetaConstraints binder,
final Column column) {
- NotNode notNode = (NotNode) attachNode( new NotNode( this.id++,
+ ExistsNode existsNode = (ExistsNode) attachNode( new ExistsNode( this.id++,
tupleSource,
ObjectSource,
binder ) );
- RightInputAdapterNode adapter = (RightInputAdapterNode) attachNode( new RightInputAdapterNode( this.id++,
- column,
- notNode ) );
-
- final BetaConstraints identityBinder = new SingleBetaConstraints( new InstanceEqualsConstraint( column ), this.ruleBase.getConfiguration() );
- notNode = (NotNode) attachNode( new NotNode( this.id++,
- tupleSource,
- adapter,
- identityBinder ) );
-
- if ( exists.getChild() instanceof Not ) {
- adapter = (RightInputAdapterNode) attachNode( new RightInputAdapterNode( this.id++,
- column,
- notNode ) );
- attachNot( tupleSource,
- (Not) exists.getChild(),
- adapter,
- EmptyBetaConstraints.getInstance(),
- column );
- } else if ( exists.getChild() instanceof Exists ) {
- adapter = (RightInputAdapterNode) attachNode( new RightInputAdapterNode( this.id++,
- column,
- notNode ) );
- attachExists( tupleSource,
- (Exists) exists.getChild(),
- adapter,
- EmptyBetaConstraints.getInstance(),
- column );
- } else {
- this.tupleSource = notNode;
- }
+ this.tupleSource = existsNode;
}
/**
Added: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ExistsNodeTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ExistsNodeTest.java 2006-11-20 13:47:52 UTC (rev 7723)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ExistsNodeTest.java 2006-11-20 16:21:55 UTC (rev 7724)
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2006 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.reteoo;
+
+import java.beans.IntrospectionException;
+
+import junit.framework.Assert;
+
+import org.drools.Cheese;
+import org.drools.DroolsTestCase;
+import org.drools.FactException;
+import org.drools.RuleBaseConfiguration;
+import org.drools.RuleBaseFactory;
+import org.drools.common.DefaultBetaConstraints;
+import org.drools.common.DefaultFactHandle;
+import org.drools.common.PropagationContextImpl;
+import org.drools.rule.Rule;
+import org.drools.spi.BetaNodeFieldConstraint;
+import org.drools.spi.MockConstraint;
+import org.drools.spi.PropagationContext;
+
+/**
+ * @author etirelli
+ *
+ */
+public class ExistsNodeTest extends DroolsTestCase {
+ Rule rule;
+ PropagationContext context;
+ ReteooWorkingMemory workingMemory;
+ MockObjectSource objectSource;
+ MockTupleSource tupleSource;
+ MockTupleSink sink;
+ ExistsNode node;
+ RightInputAdapterNode ria;
+ BetaMemory memory;
+ MockConstraint constraint = new MockConstraint();
+
+ /**
+ * Setup the BetaNode used in each of the tests
+ * @throws IntrospectionException
+ */
+ public void setUp() throws IntrospectionException {
+ this.rule = new Rule( "test-rule" );
+ this.context = new PropagationContextImpl( 0,
+ PropagationContext.ASSERTION,
+ null,
+ null );
+ this.workingMemory = new ReteooWorkingMemory( 1,
+ (ReteooRuleBase) RuleBaseFactory.newRuleBase() );
+
+ RuleBaseConfiguration configuration = new RuleBaseConfiguration();
+
+ // string1Declaration is bound to column 3
+ this.node = new ExistsNode( 15,
+ new MockTupleSource( 5 ),
+ new MockObjectSource( 8 ),
+ new DefaultBetaConstraints( new BetaNodeFieldConstraint[] { this.constraint }, configuration ) );
+
+ this.sink = new MockTupleSink();
+ this.node.addTupleSink( this.sink );
+
+ this.memory = (BetaMemory) this.workingMemory.getNodeMemory( this.node );
+ }
+
+ /**
+ * Test assertion with both Objects and Tuples
+ *
+ * @throws AssertionException
+ */
+ public void testExistsStandard() throws FactException {
+ // assert tuple
+ final Cheese cheddar = new Cheese( "cheddar",
+ 10 );
+ final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.assertObject( cheddar );
+
+ final ReteTuple tuple1 = new ReteTuple( f0 );
+
+ this.node.assertTuple( tuple1,
+ this.context,
+ this.workingMemory );
+
+ // no matching objects, so should not propagate
+ assertLength( 0,
+ this.sink.getAsserted() );
+
+ assertLength( 0,
+ this.sink.getRetracted() );
+
+ // assert will match, so should propagate
+ final Cheese brie = new Cheese( "brie",
+ 10 );
+ final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.assertObject( brie );
+
+ this.node.assertObject( f1,
+ this.context,
+ this.workingMemory );
+
+ // check a single assertion
+ assertLength( 1,
+ this.sink.getAsserted() );
+
+ assertLength( 0,
+ this.sink.getRetracted() );
+
+ assertEquals( new ReteTuple( f0 ),
+ ((Object[]) this.sink.getAsserted().get( 0 ))[0] );
+
+
+ // assert tuple, will have matches, so propagate
+ final DefaultFactHandle f2 = (DefaultFactHandle) this.workingMemory.assertObject( new Cheese( "gouda",
+ 10 ) );
+ final ReteTuple tuple2 = new ReteTuple( f2 );
+ this.node.assertTuple( tuple2,
+ this.context,
+ this.workingMemory );
+
+ // check propagations
+ assertLength( 2,
+ this.sink.getAsserted() );
+
+ assertLength( 0,
+ this.sink.getRetracted() );
+
+ // check memory sizes
+ assertEquals( 2,
+ this.memory.getTupleMemory().size() );
+ assertEquals( 1,
+ this.memory.getFactHandleMemory().size() );
+
+ // When this is retracter both tuples should be retracted
+ this.node.retractObject( f1,
+ this.context,
+ this.workingMemory );
+
+ // check retracts
+ assertLength( 2,
+ this.sink.getAsserted() );
+
+ assertLength( 2,
+ this.sink.getRetracted() );
+ }
+
+ /**
+ * Test assertion with both Objects and Tuples
+ *
+ * @throws AssertionException
+ */
+ public void testExistsWithConstraints() throws FactException {
+ this.constraint.isAllowed = false;
+
+ // assert tuple
+ final Cheese cheddar = new Cheese( "cheddar",
+ 10 );
+ final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.assertObject( cheddar );
+
+ final ReteTuple tuple1 = new ReteTuple( f0 );
+
+ this.node.assertTuple( tuple1,
+ this.context,
+ this.workingMemory );
+
+ // no matching objects, so don't propagate
+ assertLength( 0,
+ this.sink.getAsserted() );
+
+ assertLength( 0,
+ this.sink.getRetracted() );
+
+ // assert will not match, so activation should stay propagated
+ final Cheese brie = new Cheese( "brie",
+ 10 );
+ final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.assertObject( brie );
+
+ this.node.assertObject( f1,
+ this.context,
+ this.workingMemory );
+
+ // no matches, so no propagations still
+ assertLength( 0,
+ this.sink.getAsserted() );
+
+ assertLength( 0,
+ this.sink.getRetracted() );
+
+ // assert tuple, will have matches, so do assert propagation
+ final DefaultFactHandle f2 = (DefaultFactHandle) this.workingMemory.assertObject( new Cheese( "gouda",
+ 10 ) );
+ final ReteTuple tuple2 = new ReteTuple( f2 );
+ this.node.assertTuple( tuple2,
+ this.context,
+ this.workingMemory );
+
+ assertLength( 0,
+ this.sink.getAsserted() );
+
+ assertLength( 0,
+ this.sink.getRetracted() );
+ }
+
+ /**
+ * Tests memory consistency after assert/modify/retract calls
+ *
+ * @throws AssertionException
+ */
+ public void testExistsMemoryManagement() throws FactException {
+ try {
+ // assert tuple
+ final Cheese cheddar = new Cheese( "cheddar",
+ 10 );
+ final DefaultFactHandle f0 = (DefaultFactHandle) this.workingMemory.assertObject( cheddar );
+ final ReteTuple tuple1 = new ReteTuple( f0 );
+
+ this.node.assertTuple( tuple1,
+ this.context,
+ this.workingMemory );
+
+ // assert will match, so should propagate
+ final Cheese brie = new Cheese( "brie",
+ 10 );
+ final DefaultFactHandle f1 = (DefaultFactHandle) this.workingMemory.assertObject( brie );
+
+ // Initially, no objects in right memory
+ assertEquals( 0,
+ this.memory.getFactHandleMemory().size() );
+ this.node.assertObject( f1,
+ this.context,
+ this.workingMemory );
+
+ // Now, needs to have 1 object in right memory
+ assertEquals( 1,
+ this.memory.getFactHandleMemory().size() );
+
+ // simulate modify
+ this.node.retractObject( f1,
+ this.context,
+ this.workingMemory );
+ this.node.assertObject( f1,
+ this.context,
+ this.workingMemory );
+ // Memory should not change
+ assertEquals( 1,
+ this.memory.getFactHandleMemory().size() );
+
+ // When this is retracter both tuples should assert
+ this.node.retractObject( f1,
+ this.context,
+ this.workingMemory );
+ assertEquals( 0,
+ this.memory.getFactHandleMemory().size() );
+
+ // check memory sizes
+ assertEquals( 1,
+ this.memory.getTupleMemory().size() );
+
+ // simulate modify
+ this.node.retractTuple( tuple1,
+ this.context,
+ this.workingMemory );
+ this.node.assertTuple( tuple1,
+ this.context,
+ this.workingMemory );
+ assertEquals( 1,
+ this.memory.getTupleMemory().size() );
+ this.node.retractTuple( tuple1,
+ this.context,
+ this.workingMemory );
+ assertEquals( 0,
+ this.memory.getTupleMemory().size() );
+ } catch ( final Exception e ) {
+ Assert.fail( "No exception should be raised in this procedure, but got: " + e.toString() );
+ }
+ }
+
+}
Property changes on: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/reteoo/ExistsNodeTest.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:keywords
+ id author date revision
Name: svn:eol-style
+ native
More information about the jboss-svn-commits
mailing list