[jboss-svn-commits] JBL Code SVN: r5996 - in labs/jbossrules/trunk: drools-compiler/src/test/java/org/drools/integrationtests drools-core/src/main/java/org/drools/leaps drools-core/src/main/java/org/drools/leaps/util drools-core/src/test/java/org/drools/examples/manners drools-core/src/test/java/org/drools/leaps
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Aug 28 20:49:02 EDT 2006
Author: bagerman
Date: 2006-08-28 20:48:55 -0400 (Mon, 28 Aug 2006)
New Revision: 5996
Modified:
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/LeapsTest.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/FactHandleTupleAssembly.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/FactTable.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/HashedTableComponent.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsAgenda.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsBuilder.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsFactHandle.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsRuleBase.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsWorkingMemory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/Token.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/TokenEvaluator.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/util/Table.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/LeapsMannersTest.java
labs/jbossrules/trunk/drools-core/src/test/java/org/drools/leaps/LeapsWorkingMemoryTest.java
Log:
1 another query unit test is fixed by adding fireAll()
2 modifyObject is reworked and many related changes are done including streamlined assert / retract and lazier not and exits evaluation.
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/LeapsTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/LeapsTest.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/LeapsTest.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -34,7 +34,6 @@
import org.drools.compiler.PackageBuilder;
import org.drools.lang.DrlDumper;
import org.drools.lang.descr.PackageDescr;
-import org.drools.leaps.LeapsRuleBase;
import org.drools.rule.Package;
import org.drools.rule.Rule;
import org.drools.xml.XmlDumper;
@@ -75,6 +74,40 @@
results.size() );
}
+
+ public void testTwoQuerries() throws Exception {
+ // @see JBRULES-410 More than one Query definition causes an incorrect Rete network to be built.
+
+ final PackageBuilder builder = new PackageBuilder();
+ builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_TwoQuerries.drl" ) ) );
+ final Package pkg = builder.getPackage();
+
+ final RuleBase ruleBase = getRuleBase();
+ ruleBase.addPackage( pkg );
+ final WorkingMemory workingMemory = ruleBase.newWorkingMemory();
+
+ final Cheese stilton = new Cheese( "stinky",
+ 5 );
+ workingMemory.assertObject( stilton );
+ final Person per1 = new Person( "stinker", "smelly feet", 70);
+ final Person per2 = new Person( "skunky", "smelly armpits", 40);
+
+ workingMemory.assertObject( per1 );
+ workingMemory.assertObject( per2 );
+
+ workingMemory.fireAllRules( );
+
+ QueryResults results = workingMemory.getQueryResults( "find stinky cheeses" );
+ assertEquals( 1,
+ results.size() );
+
+ results = workingMemory.getQueryResults( "find pensioners" );
+ assertEquals( 1,
+ results.size() );
+ }
+
+
+
/**
* leaps does not create activations upfront hence its inability to apply
* auto-focus predicate in the same way as reteoo does. activations in
@@ -385,12 +418,4 @@
assertEquals( "3 1",
list.get( 1 ) );
}
-
- public void testLogicalAssertionsWithExists() throws Exception {
- // FIXME
- }
-
- public void testTwoQuerries() throws Exception {
- // FIXME
- }
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/FactHandleTupleAssembly.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/FactHandleTupleAssembly.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/FactHandleTupleAssembly.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -31,9 +31,18 @@
final LeapsTuple tuple;
final int index;
+
+ final int type;
- FactHandleTupleAssembly(final LeapsTuple tuple,
+ public final static int EXISTS = 1;
+
+ public final static int NOT = 2;
+
+
+ FactHandleTupleAssembly(final int type,
+ final LeapsTuple tuple,
final int index) {
+ this.type = type;
this.tuple = tuple;
this.index = index;
}
@@ -45,4 +54,8 @@
protected LeapsTuple getTuple() {
return this.tuple;
}
+
+ public int getType() {
+ return type;
+ }
}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/FactTable.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/FactTable.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/FactTable.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -21,7 +21,6 @@
import org.drools.common.DefaultFactHandle;
import org.drools.common.PropagationContextImpl;
-import org.drools.leaps.util.IteratorFromPositionToTableStart;
import org.drools.leaps.util.Table;
import org.drools.leaps.util.TableIterator;
import org.drools.spi.PropagationContext;
@@ -196,7 +195,6 @@
protected void removeTuple( final LeapsTuple tuple ) {
this.tuples.remove( tuple );
}
-
private final IdentityMap notAndExistsHashedTables;
@@ -205,15 +203,16 @@
public void add( Object object ) {
super.add( object );
for (Iterator it = this.notAndExistsHashedTables.values( ).iterator( ); it.hasNext( );) {
+ // this will also add link to hash into the leapsfacthandle
((HashedTableComponent)it.next( )).add( (LeapsFactHandle)object );
}
}
public void remove( Object object ) {
super.remove( object );
- for (Iterator it = this.notAndExistsHashedTables.values( ).iterator( ); it.hasNext( );) {
- ((HashedTableComponent)it.next( )).remove( (LeapsFactHandle)object );
- }
+ // during modify we need to directly remove facts from participating
+ // hashes because modify can throw us off
+ ((LeapsFactHandle)object ).removeFromHash();
}
protected void createHashedSubTable(ColumnConstraints constraint) {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/HashedTableComponent.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/HashedTableComponent.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/HashedTableComponent.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -34,19 +34,13 @@
}
public void add( LeapsFactHandle factHandle ) {
- Table table = this.getTable( factHandle, true );
+ Table table = this.getTable( factHandle);
if (table != null) {
table.add( factHandle );
+ factHandle.addHash(table);
}
}
- public void remove( LeapsFactHandle factHandle ) {
- Table table = this.getTable( factHandle, false );
- if (table != null) {
- table.remove( factHandle );
- }
- }
-
public TableIterator reverseOrderIterator( Tuple tuple ) {
Table table = this.getTable( tuple );
if (table != null) {
@@ -115,13 +109,12 @@
return ret;
}
- private Table getTable( LeapsFactHandle factHandle, boolean createIfNotThere ) {
+ private Table getTable( LeapsFactHandle factHandle ) {
Table ret = null;
Map currentMap = this.buckets;
if (this.constraints.isAllowedAlpha( factHandle, null, null )) {
if (this.numberOfVariableConstraints > 0) {
- for (int i = 0; ( i < this.numberOfVariableConstraints )
- && ( currentMap != null ); i++) {
+ for (int i = 0; i < this.numberOfVariableConstraints; i++) {
Integer hash = DEFAULT_HASH;
if (this.constraints.getBetaContraints( )[i] instanceof VariableConstraint
&& ( (VariableConstraint) this.constraints.getBetaContraints( )[i] ).getEvaluator( )
@@ -136,7 +129,7 @@
if (i != ( this.numberOfVariableConstraints - 1 )) {
// we can not have null as a value to the key
Map map = (Map) currentMap.get( hash );
- if (map == null && createIfNotThere) {
+ if (map == null) {
map = new HashMap( );
currentMap.put( hash, map );
}
@@ -144,7 +137,7 @@
}
else {
Table table = (Table) currentMap.get( hash );
- if (table == null && createIfNotThere) {
+ if (table == null) {
table = new Table( this.comparator );
currentMap.put( hash, table );
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsAgenda.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsAgenda.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsAgenda.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -49,29 +49,21 @@
activation.getTuple( ) );
}
else {
- if (activation.getRule( ).getActivationGroup( ) == null
- || ( activation.getRule( ).getActivationGroup( ) != null && this.getActivationGroup( activation.getRule( )
- .getActivationGroup( ) )
- .isEmpty( ) )) {
- // fire regular rule
- super.fireActivation( activation );
- ((LeapsTuple)activation.getTuple( )).setWasFired( true );
- if (activation.getRule( ).getActivationGroup( ) != null) {
- this.getActivationGroup( activation.getRule( ).getActivationGroup( ) );
- }
- }
+ // fire regular rule
+ super.fireActivation( activation );
+ ( (LeapsTuple) activation.getTuple( ) ).setWasFired( true );
}
}
-
+
/**
- * to accomodate the difference between rete and leaps in storing
- * activations. we pull activations from rule to activations map
- * we store in working memory to facilitate activations removal
- * when rule is removed from the memory
+ * to accomodate the difference between rete and leaps in storing
+ * activations. we pull activations from rule to activations map we store in
+ * working memory to facilitate activations removal when rule is removed
+ * from the memory
*
*/
public Activation[] getActivations() {
- final List list = this.workingMemory.getActivations();
- return (Activation[]) list.toArray( new Activation[list.size()] );
+ final List list = this.workingMemory.getActivations( );
+ return (Activation[]) list.toArray( new Activation[list.size( )] );
}
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsBuilder.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsBuilder.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -24,7 +24,6 @@
import org.drools.base.ClassObjectType;
import org.drools.common.BetaNodeBinder;
-import org.drools.facttemplates.FactTemplate;
import org.drools.facttemplates.FactTemplateObjectType;
import org.drools.rule.And;
import org.drools.rule.Column;
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsFactHandle.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsFactHandle.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsFactHandle.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -21,6 +21,7 @@
import java.util.List;
import org.drools.common.DefaultFactHandle;
+import org.drools.leaps.util.Table;
/**
* class container for each object asserted / retracted into the system
@@ -51,14 +52,14 @@
if (this.notTuples == null) {
this.notTuples = new LinkedList( );
}
- this.notTuples.add( new FactHandleTupleAssembly( tuple, index ) );
+ this.notTuples.add( new FactHandleTupleAssembly( FactHandleTupleAssembly.NOT, tuple, index ) );
}
protected void addExistsTuple( final LeapsTuple tuple, final int index ) {
if (this.existsTuples == null) {
this.existsTuples = new LinkedList( );
}
- this.existsTuples.add( new FactHandleTupleAssembly( tuple, index ) );
+ this.existsTuples.add( new FactHandleTupleAssembly( FactHandleTupleAssembly.EXISTS, tuple, index ) );
}
protected Iterator getActivatedTuples() {
@@ -81,4 +82,33 @@
}
return null;
}
+
+ protected void clearActivatedTuples() {
+ this.activatedTuples = null;
+ }
+
+ protected void clearExistsTuples() {
+ this.existsTuples = null;
+ }
+
+ protected void clearNotTuples() {
+ this.notTuples = null;
+ }
+
+ private LinkedList hashes = null;
+ protected void addHash(Table table){
+ if(this.hashes == null){
+ this.hashes = new LinkedList();
+ }
+ this.hashes.add( table );
+ }
+
+ protected void removeFromHash() {
+ if(this.hashes!= null){
+ for(Iterator it = this.hashes.iterator( ); it.hasNext( );){
+ ((Table)it.next( )).remove( this );
+ }
+ this.hashes.clear( );
+ }
+ }
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsRuleBase.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsRuleBase.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsRuleBase.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -125,6 +125,7 @@
*/
public void addRule(final Rule rule) throws FactException,
InvalidPatternException {
+ // checks rule validity
super.addRule( rule );
final List rules = LeapsBuilder.processRule( rule );
@@ -138,10 +139,7 @@
// Iterate each workingMemory and attempt to fire any rules, that were
// activated as a result of the new rule addition
- for ( final Iterator it = this.getWorkingMemories().iterator(); it.hasNext(); ) {
- final LeapsWorkingMemory workingMemory = (LeapsWorkingMemory) it.next();
- workingMemory.fireAllRules();
- }
+ // abstract rule base does it
}
public void removeRule(final Rule rule) {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsWorkingMemory.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/LeapsWorkingMemory.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -29,7 +29,6 @@
import org.drools.FactException;
import org.drools.FactHandle;
-import org.drools.NoSuchFactObjectException;
import org.drools.QueryResults;
import org.drools.WorkingMemory;
import org.drools.common.AbstractWorkingMemory;
@@ -107,80 +106,56 @@
final FactTable factTable = (FactTable) tables.next( );
// adding fact to container
factTable.add( factHandle );
+ // iterate through unsatisfied exists
for (final Iterator tuples = factTable.getTuplesIterator( ); tuples.hasNext( );) {
final LeapsTuple tuple = (LeapsTuple) tuples.next( );
- final ColumnConstraints[] not = tuple.getLeapsRule( )
- .getNotColumnConstraints( );
- for (int i = 0, length = not.length; i < length; i++) {
- final ColumnConstraints constraint = not[i];
- final Object columnClassObject = constraint.getClassType( );
- if (!tuple.isBlockingNotFactHandle( i )
- && ( ( objectClass.getClass( ) == Class.class
- && columnClassObject.getClass( ) == Class.class && ( (Class) columnClassObject ).isAssignableFrom( (Class) objectClass ) ) || ( objectClass.getClass( ) != Class.class
- && columnClassObject.getClass( ) != Class.class && columnClassObject.equals( objectClass ) ) )
- && constraint.isAllowed( factHandle, tuple, this )) {
- tuple.setBlockingNotFactHandle( (LeapsFactHandle) factHandle, i );
- ( (LeapsFactHandle) factHandle ).addNotTuple( tuple, i );
- }
- }
- // check exists constraints and activate constraints
- final ColumnConstraints[] exists = tuple.getLeapsRule( )
- .getExistsColumnConstraints( );
- for (int i = 0, length = exists.length; i < length; i++) {
- final ColumnConstraints constraint = exists[i];
- final Object columnClassObject = constraint.getClassType( );
- if (!tuple.isExistsFactHandle( i )
- && ( ( objectClass.getClass( ) == Class.class
- && columnClassObject.getClass( ) == Class.class && ( (Class) columnClassObject ).isAssignableFrom( (Class) objectClass ) ) || ( objectClass.getClass( ) != Class.class
- && columnClassObject.getClass( ) != Class.class && columnClassObject.equals( objectClass ) ) )
- && constraint.isAllowed( factHandle, tuple, this )) {
- tuple.setExistsFactHandle( (LeapsFactHandle) factHandle, i );
- ( (LeapsFactHandle) factHandle ).addExistsTuple( tuple, i );
- }
- }
+ TokenEvaluator.evaluateExistsConditions( tuple, tuple.getLeapsRule( ), this );
// check and see if we need activate
// activate only if tuple was not ready for it before
if (tuple.isReadyForActivation( )) {
// ready to activate
- tuple.setContext( new PropagationContextImpl( nextPropagationIdCounter( ),
- PropagationContext.ASSERTION,
- tuple.getLeapsRule( )
- .getRule( ),
- null ) );
tuplesToAssert.add( tuple );
}
}
- for (Iterator tuples = tuplesToAssert.iterator( ); tuples.hasNext( );) {
- LeapsTuple tuple = (LeapsTuple) tuples.next( );
+ for (final Iterator it = tuplesToAssert.iterator( ); it.hasNext( );) {
+ // ready to activate
+ final LeapsTuple tuple = (LeapsTuple) it.next( );
factTable.removeTuple( tuple );
+ tuple.setContext( new PropagationContextImpl( nextPropagationIdCounter( ),
+ PropagationContext.ASSERTION,
+ tuple.getLeapsRule( )
+ .getRule( ),
+ null ) );
this.assertTuple( tuple );
}
}
- // inspect all tuples for exists and not conditions and activate
+ // inspect all tuples for not conditions and activate
// deactivate agenda items
Activation[] activations = this.agenda.getActivations( );
for (int k = 0; k < activations.length; k++) {
boolean deActivate = false;
LeapsTuple tuple = (LeapsTuple) activations[k].getTuple( );
final ColumnConstraints[] not = tuple.getLeapsRule( ).getNotColumnConstraints( );
- for (int i = 0, length = not.length; i < length; i++) {
+ for (int i = 0, length = not.length; !deActivate && i < length; i++) {
final ColumnConstraints constraint = not[i];
final Object columnClassObject = constraint.getClassType( );
- if (!tuple.isBlockingNotFactHandle( i )
- && ( ( objectClass.getClass( ) == Class.class
- && columnClassObject.getClass( ) == Class.class && ( (Class) columnClassObject ).isAssignableFrom( (Class) objectClass ) ) || ( objectClass.getClass( ) != Class.class
- && columnClassObject.getClass( ) != Class.class && columnClassObject.equals( objectClass ) ) )
+ if (( ( objectClass.getClass( ) == Class.class
+ && columnClassObject.getClass( ) == Class.class && ( (Class) columnClassObject ).isAssignableFrom( (Class) objectClass ) ) || ( objectClass.getClass( ) != Class.class
+ && columnClassObject.getClass( ) != Class.class && columnClassObject.equals( objectClass ) ) )
&& constraint.isAllowed( factHandle, tuple, this )) {
tuple.setBlockingNotFactHandle( (LeapsFactHandle) factHandle, i );
( (LeapsFactHandle) factHandle ).addNotTuple( tuple, i );
- if (!deActivate) {
- deActivate = true;
- }
+ deActivate = true;
}
}
// check and see if we need de-activate
if (deActivate) {
+ tuple.setContext( new PropagationContextImpl( nextPropagationIdCounter( ),
+ PropagationContext.ASSERTION,
+ tuple.getLeapsRule( )
+ .getRule( ),
+ null ) );
if (tuple.getLeapsRule( ).getRule( ) instanceof Query) {
// put query results to the working memory
// location
@@ -209,8 +184,8 @@
* leaps specific actions
*/
// remove fact from all relevant fact tables container
- for (final Iterator it = this.getFactTablesList( LeapsBuilder.getLeapsClassType( factHandle.getObject( ) ) )
- .iterator( ); it.hasNext( );) {
+ final Object objectClass = LeapsBuilder.getLeapsClassType( factHandle.getObject( ) );
+ for (final Iterator it = this.getFactTablesList( objectClass ).iterator( ); it.hasNext( );) {
( (FactTable) it.next( ) ).remove( factHandle );
}
@@ -227,51 +202,10 @@
invalidateActivation( tuple );
}
}
-
- // 1. remove fact for nots and exists tuples
- final IdentityMap tuplesNotReadyForActivation = new IdentityMap( );
- FactHandleTupleAssembly assembly;
- LeapsTuple tuple;
- Iterator it;
- it = ( (LeapsFactHandle) factHandle ).getNotTupleAssemblies( );
- if (it != null) {
- for (; it.hasNext( );) {
- assembly = (FactHandleTupleAssembly) it.next( );
- tuple = assembly.getTuple( );
- if (!tuple.isReadyForActivation( )) {
- tuplesNotReadyForActivation.put( tuple, tuple );
- }
- tuple.removeBlockingNotFactHandle( assembly.getIndex( ) );
-
- TokenEvaluator.evaluateNotCondition( (LeapsFactHandle) factHandle,
- // TokenEvaluator.evaluateNotCondition( new LeapsFactHandle(
- // factHandle.getRecency( ) + 1,
- // new Object( ) ),
- assembly.getIndex( ),
- tuple,
- this );
- }
- }
- it = ( (LeapsFactHandle) factHandle ).getExistsTupleAssemblies( );
- if (it != null) {
- for (; it.hasNext( );) {
- assembly = (FactHandleTupleAssembly) it.next( );
- tuple = assembly.getTuple( );
- if (!tuple.isReadyForActivation( )) {
- tuplesNotReadyForActivation.put( tuple, tuple );
- }
- tuple.removeExistsFactHandle( assembly.getIndex( ) );
- TokenEvaluator.evaluateExistsCondition( (LeapsFactHandle) factHandle,
- // TokenEvaluator.evaluateExistsCondition( new LeapsFactHandle(
- // factHandle.getRecency( ) + 1,
- // null ),
- assembly.getIndex( ),
- tuple,
- this );
- }
- }
- // 2. assert all tuples that are ready for activation or cancel ones
+ ( (LeapsFactHandle) factHandle ).clearActivatedTuples( );
+ // assert all tuples that are ready for activation or cancel ones
// that are no longer
+ Iterator it;
final IteratorChain chain = new IteratorChain( );
it = ( (LeapsFactHandle) factHandle ).getNotTupleAssemblies( );
if (it != null) {
@@ -282,22 +216,30 @@
chain.addIterator( it );
}
for (; chain.hasNext( );) {
- tuple = ( (FactHandleTupleAssembly) chain.next( ) ).getTuple( );
+ FactHandleTupleAssembly tupleAssembly = ( (FactHandleTupleAssembly) chain.next( ) );
+ final LeapsTuple tuple = tupleAssembly.getTuple( );
+ if (tupleAssembly.getType( ) == FactHandleTupleAssembly.NOT) {
+ tuple.removeBlockingNotFactHandle( tupleAssembly.getIndex( ) );
+ }
+ else {
+ tuple.removeExistsFactHandle( tupleAssembly.getIndex( ) );
+ }
// can assert only tuples that were not eligible for activation
// before retraction
- if (tuple.isReadyForActivation( )) {
- // ready to activate
- tuple.setContext( new PropagationContextImpl( nextPropagationIdCounter( ),
- PropagationContext.ASSERTION,
- tuple.getLeapsRule( )
- .getRule( ),
- null ) );
- this.getFactTable( LeapsBuilder.getLeapsClassType( factHandle.getObject( ) ) )
- .removeTuple( tuple );
+ if (!TokenEvaluator.processAfterAllPositiveConstraintOk( tuple,
+ tuple.getLeapsRule( ),
+ this )) {
+ // deactivate tuple that was activated inside of
+ // processAfterAllPositive
+ // bad design, need to rethink it
+ invalidateActivation( tuple );
+ }
+ else {
this.assertTuple( tuple );
}
}
-
+ ( (LeapsFactHandle) factHandle ).clearExistsTuples( );
+ ( (LeapsFactHandle) factHandle ).clearNotTuples( );
// remove it from stack
this.removeTokenFromStack( (LeapsFactHandle) factHandle );
}
@@ -310,21 +252,20 @@
*/
private final void invalidateActivation( final LeapsTuple tuple ) {
final Activation activation = tuple.getActivation( );
- if (!tuple.isReadyForActivation( ) && !tuple.isActivationNull( )) {
- // invalidate agenda agendaItem
+ // tuple can already loose activation if another fact or exists fact was retracted
+ // or not fact added
+ if (activation != null) {
if (activation.isActivated( )) {
activation.remove( );
- getAgendaEventSupport( ).fireActivationCancelled( activation );
+ this.getAgendaEventSupport( ).fireActivationCancelled( activation );
}
+
+ this.getTruthMaintenanceSystem( )
+ .removeLogicalDependencies( activation,
+ tuple.getContext( ),
+ tuple.getLeapsRule( ).getRule( ) );
//
tuple.setActivation( null );
- }
- if (activation != null) {
- // remove logical dependency
- this.tms.removeLogicalDependencies( activation,
- tuple.getContext( ),
- tuple.getLeapsRule( ).getRule( ) );
-
// remove from rule / activaitons map
FastMap activations = (FastMap) this.rulesActivationsMap.get( activation.getRule( ) );
if (activations != null) {
@@ -344,70 +285,76 @@
final Rule rule,
final Activation activation ) throws FactException {
try {
- this.getLock( ).lock( );
- final PropagationContext propagationContext = new PropagationContextImpl( this.propagationIdCounter++,
- PropagationContext.MODIFICATION,
- rule,
- activation );
-
- final int status = ( (InternalFactHandle) factHandle ).getEqualityKey( )
- .getStatus( );
-
- final Object originalObject = this.assertMap.remove( factHandle );
- if (originalObject == null) {
- throw new NoSuchFactObjectException( factHandle );
- }
- //
- // do subset of retractObject( )
- //
+ this.lock.lock();
+ final int status = ((InternalFactHandle) factHandle).getEqualityKey().getStatus();
final InternalFactHandle handle = (InternalFactHandle) factHandle;
- if (handle.getId( ) == -1) {
- // can't retract an already retracted handle
+ final Object originalObject = handle.getObject();
+
+ if ( handle.getId() == -1 || object == null ) {
+ // the handle is invalid, most likely already retracted, so return
+ // and we cannot assert a null object
return;
}
- removePropertyChangeListener( handle );
- doRetract( handle, propagationContext );
+ // set anyway, so that it updates the hashCodes
+ handle.setObject( object );
- // Update the equality key, which maintains a list of stated
- // FactHandles
- final EqualityKey key = handle.getEqualityKey( );
+ // We only need to put objects, if its a new object
+ if ( originalObject != object ) {
+ this.assertMap.put( handle,
+ handle );
+ }
+ // the hashCode and equality has changed, so we must update the EqualityKey
+ EqualityKey key = handle.getEqualityKey();
key.removeFactHandle( handle );
- handle.setEqualityKey( null );
// If the equality key is now empty, then remove it
- if (key.isEmpty( )) {
+ if ( key.isEmpty() ) {
this.tms.remove( key );
}
- // produces NPE otherwise
- this.handleFactory.destroyFactHandle( handle );
- //
- // and now assert
- //
- /* check to see if this is a logically asserted object */
- this.assertObject( object, false, ( status == EqualityKey.STATED ) ? false
- : true, rule, activation );
+ // now use an existing EqualityKey, if it exists, else create a new one
+ key = this.tms.get( object );
+ if ( key == null ) {
+ key = new EqualityKey( handle,
+ status );
+ this.tms.put( key );
+ } else {
+ key.addFactHandle( handle );
+ }
+ handle.setEqualityKey( key );
+
+ final PropagationContext propagationContext = new PropagationContextImpl( this.propagationIdCounter++,
+ PropagationContext.MODIFICATION,
+ rule,
+ activation );
+ doRetract( handle, propagationContext );
+
+ this.handleFactory.increaseFactHandleRecency( handle );
+
+ doAssertObject( handle, object, propagationContext );
+
this.workingMemoryEventSupport.fireObjectModified( propagationContext,
- handle,
- handle.getObject( ),
+ factHandle,
+ originalObject,
object );
- if (!this.factQueue.isEmpty( )) {
- propagateQueuedActions( );
+ if ( !this.factQueue.isEmpty() ) {
+ propagateQueuedActions();
}
+ } finally {
+ this.lock.unlock();
}
- finally {
- this.getLock( ).unlock( );
- }
}
/**
* ************* leaps section *********************
*/
private long idLastFireAllAt = -1;
+
+ private boolean rulesAddedSinceLastFireAll = false;
/**
* algorithm stack.
@@ -521,6 +468,8 @@
protected void addLeapsRules( final List rules ) {
this.getLock( ).lock( );
try {
+ this.rulesAddedSinceLastFireAll = true;
+
ArrayList ruleHandlesList;
LeapsRule rule;
LeapsRuleHandle ruleHandle;
@@ -630,6 +579,7 @@
if (!this.firing) {
try {
this.firing = true;
+
boolean nothingToProcess = false;
while (!nothingToProcess) {
// check for the initial fact
@@ -637,13 +587,16 @@
LeapsRule rule = ( (LeapsRuleHandle) rulesIt.next( ) ).getLeapsRule( );
final PropagationContextImpl context = new PropagationContextImpl( nextPropagationIdCounter( ),
PropagationContext.ASSERTION,
- null,
+ null, //rule.getRule( ),
null );
- TokenEvaluator.processAfterAllPositiveConstraintOk( new LeapsTuple( new LeapsFactHandle[0],
- rule,
- context ),
- rule,
- this );
+ final LeapsTuple tuple = new LeapsTuple( new LeapsFactHandle[0],
+ rule,
+ context );
+ if (TokenEvaluator.processAfterAllPositiveConstraintOk( tuple,
+ rule,
+ this )) {
+ this.assertTuple( tuple );
+ }
}
this.noPositiveColumnsRules.clear( );
@@ -708,6 +661,7 @@
}
}
// mark when method was called last time
+ this.rulesAddedSinceLastFireAll = false;
this.idLastFireAllAt = ( (LeapsFactHandleFactory) this.handleFactory ).getNextId( );
// set all factTables to be reseeded
for (final Iterator it = this.factTables.values( ).iterator( ); it.hasNext( );) {
@@ -722,6 +676,10 @@
}
}
+ protected final boolean isRulesAddedSinceLastFireAll() {
+ return this.rulesAddedSinceLastFireAll;
+ }
+
protected final long getIdLastFireAllAt() {
return this.idLastFireAllAt;
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/Token.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/Token.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/Token.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -95,7 +95,9 @@
if ( this.rulesIterator() != null ) {
// starting with calling rulesIterator() to make sure that we picks
// rules because fact can be asserted before rules added
- final long levelId = this.workingMemory.getIdLastFireAllAt( );
+ final long levelId = ( this.workingMemory.isRulesAddedSinceLastFireAll( ) ) ? this.workingMemory.getIdLastFireAllAt( )
+ : -1;
+
if (this.dominantFactHandle == null
|| this.dominantFactHandle.getRecency( ) >= levelId) {
ret = this.rules.hasNext( );
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/TokenEvaluator.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/TokenEvaluator.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/TokenEvaluator.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -189,9 +189,11 @@
// one check negative conditions and fire consequence
if (jj == stopIteratingCount) {
if (!skip) {
- if (processAfterAllPositiveConstraintOk( token.getTuple( ),
+ final LeapsTuple tuple = token.getTuple( );
+ if (processAfterAllPositiveConstraintOk( tuple,
leapsRule,
workingMemory )) {
+ workingMemory.assertTuple( tuple );
return;
}
}
@@ -230,25 +232,11 @@
if (leapsRule.containsExistsColumns( )) {
TokenEvaluator.evaluateExistsConditions( tuple, leapsRule, workingMemory );
}
- if (leapsRule.containsNotColumns( )) {
+ if (tuple.isReadyForActivation( ) && leapsRule.containsNotColumns( )) {
TokenEvaluator.evaluateNotConditions( tuple, leapsRule, workingMemory );
}
//
- if (tuple.isReadyForActivation( )) {
- // let agenda to do its work
- workingMemory.assertTuple( tuple );
- return true;
- }
- else {
- // put tuple onto fact tables that might affect activation status
- // via exists or not conditions
- final Class[] classes = leapsRule.getExistsNotColumnsClasses( );
- for (int i = 0, length = classes.length; i < length; i++) {
- workingMemory.getFactTable( classes[i] ).addTuple( tuple );
- }
-
- return false;
- }
+ return tuple.isReadyForActivation( );
}
/**
@@ -306,17 +294,15 @@
final static void evaluateNotConditions( final LeapsTuple tuple,
final LeapsRule rule,
final LeapsWorkingMemory workingMemory ) {
+ // stops if exists
+ boolean done = false;
final ColumnConstraints[] not = rule.getNotColumnConstraints( );
- for (int i = 0, length = not.length; i < length; i++) {
+ for (int i = 0, length = not.length; i < length && !done; i++) {
final ColumnConstraints constraint = not[i];
// scan table starting at start fact handle
final TableIterator tableIterator = workingMemory.getFactTable( constraint.getClassType( ) )
.reverseOrderIterator( tuple, constraint );
-// .reverseOrderIterator( );
- // stops if exists
- boolean done = false;
while (!done && tableIterator.hasNext( )) {
-// while (!done && tableIterator.hasNext( )) {
final LeapsFactHandle factHandle = (LeapsFactHandle) tableIterator.next( );
// check constraint conditions
if (constraint.isAllowed( factHandle, tuple, workingMemory )) {
@@ -329,103 +315,42 @@
}
/**
- * To evaluate conditions above the water line that is supplied in the first
- * argument
- *
- * @param startFactHandle
- * @param index
- * @param tuple
- * @param rule
- * @param workingMemory
- */
- final static void evaluateNotCondition( final LeapsFactHandle startFactHandle,
- final int index,
- final LeapsTuple tuple,
- final LeapsWorkingMemory workingMemory ) {
- final LeapsRule rule = tuple.getLeapsRule( );
- // scan table starting at start fact handle
- final ColumnConstraints constraint = rule.getNotColumnConstraints( )[index];
- final TableIterator tableIterator = workingMemory.getFactTable( constraint.getClassType( ) )
- .iteratorFromPositionToTableEnd( tuple, constraint, startFactHandle);
-// .iteratorFromPositionToTableEnd( startFactHandle );
-// .reverseOrderIterator( );
- // stops if exists
- boolean done = false;
- while (!done && tableIterator.hasNext( )) {
- final LeapsFactHandle factHandle = (LeapsFactHandle) tableIterator.next( );
- // check constraint conditions
- if (constraint.isAllowed( factHandle, tuple, workingMemory )) {
- tuple.setBlockingNotFactHandle( factHandle, index );
- factHandle.addNotTuple( tuple, index );
- done = true;
- }
- }
- }
-
- /**
* Check if any of the exists conditions are satisfied
*
* @param tuple
* @param memory
* @throws Exception
*/
- private final static void evaluateExistsConditions( final LeapsTuple tuple,
- final LeapsRule rule,
- final LeapsWorkingMemory workingMemory ) {
+ public final static void evaluateExistsConditions( final LeapsTuple tuple,
+ final LeapsRule rule,
+ final LeapsWorkingMemory workingMemory ) {
+ // stop if exists
+ boolean notFound = false;
+ boolean done = false;
final ColumnConstraints[] exists = rule.getExistsColumnConstraints( );
- for (int i = 0, length = exists.length; i < length; i++) {
+ for (int i = 0, length = exists.length; !notFound && i < length; i++) {
final ColumnConstraints constraint = exists[i];
- // scan table starting at start fact handle
- final TableIterator tableIterator = workingMemory.getFactTable( constraint.getClassType( ) )
- .reverseOrderIterator( tuple, constraint );
-// .reverseOrderIterator( );
- // stop if exists
- boolean done = false;
- while (!done && tableIterator.hasNext( )) {
- final LeapsFactHandle factHandle = (LeapsFactHandle) tableIterator.next( );
- // check constraint conditions
- if (constraint.isAllowed( factHandle,
- tuple,
- workingMemory ) ) {
- tuple.setExistsFactHandle( factHandle,
- i );
- factHandle.addExistsTuple( tuple,
- i );
- done = true;
+ if (!tuple.isExistsFactHandle( i )) {
+ // scan table starting at start fact handle
+ final TableIterator tableIterator = workingMemory.getFactTable( constraint.getClassType( ) )
+ .reverseOrderIterator( tuple,
+ constraint );
+ done = false;
+ while (!done && tableIterator.hasNext( )) {
+ final LeapsFactHandle factHandle = (LeapsFactHandle) tableIterator.next( );
+ // check constraint conditions
+ if (constraint.isAllowed( factHandle, tuple, workingMemory )) {
+ tuple.setExistsFactHandle( factHandle, i );
+ factHandle.addExistsTuple( tuple, i );
+ done = true;
+ }
}
+ if (!done) {
+ notFound = true;
+ workingMemory.getFactTable( constraint.getClassType( ) )
+ .addTuple( tuple );
+ }
}
}
}
-
- /**
- * To evaluate conditions above the water line that is supplied in the first
- * argument
- *
- * @param startFactHandle
- * @param index
- * @param tuple
- * @param rule
- * @param workingMemory
- */
- final static void evaluateExistsCondition( final LeapsFactHandle startFactHandle,
- final int index,
- final LeapsTuple tuple,
- final LeapsWorkingMemory workingMemory ) {
- final LeapsRule rule = tuple.getLeapsRule( );
- // scan table starting at start fact handle
- final ColumnConstraints constraint = rule.getExistsColumnConstraints( )[index];
- final TableIterator tableIterator = workingMemory.getFactTable( constraint.getClassType( ) )
- .iteratorFromPositionToTableEnd( startFactHandle );
- // stop if exists
- boolean done = false;
- while (!done && tableIterator.hasNext( )) {
- final LeapsFactHandle factHandle = (LeapsFactHandle) tableIterator.next( );
- // check constraint conditions
- if (constraint.isAllowed( factHandle, tuple, workingMemory )) {
- tuple.setExistsFactHandle( factHandle, index );
- factHandle.addExistsTuple( tuple, index );
- done = true;
- }
- }
- }
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/util/Table.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/util/Table.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/util/Table.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -86,7 +86,7 @@
}
catch (final NoSuchElementException nsee) {
- // means map is empty
+ // means sub map is empty
this.headRecord.left = newRecord;
newRecord.right = this.headRecord;
this.headRecord = newRecord;
@@ -114,9 +114,8 @@
try {
final TableRecord record = (TableRecord) this.set.tailSet( new TableRecord( object ) )
.first( );
-
- if (record != null) {
- if (record == this.headRecord) {
+ if (record != null && record.object == object) {
+ if (record == this.headRecord ) {
if (record.right != null) {
this.headRecord = record.right;
this.headRecord.left = null;
@@ -124,8 +123,8 @@
else {
// single element in table being valid
// table is empty now
- this.headRecord = new TableRecord( null );
- this.tailRecord = this.headRecord;
+ this.headRecord = null;
+ this.tailRecord = null;
this.empty = true;
}
}
@@ -143,11 +142,15 @@
record.left = null;
record.right = null;
}
+ else {
+ throw new NoSuchElementException();
+ }
this.count--;
//
this.set.remove( record );
}
catch (final NoSuchElementException nsee) {
+ throw nsee;
}
}
}
Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/LeapsMannersTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/LeapsMannersTest.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/examples/manners/LeapsMannersTest.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -32,7 +32,7 @@
ruleBase.addPackage( this.pkg );
final WorkingMemory workingMemory = ruleBase.newWorkingMemory();
- final InputStream is = getClass().getResourceAsStream( "/manners64.dat" );
+ final InputStream is = getClass().getResourceAsStream( "/manners128.dat" );
final List list = getInputObjects( is );
for ( final Iterator it = list.iterator(); it.hasNext(); ) {
final Object object = it.next();
Modified: labs/jbossrules/trunk/drools-core/src/test/java/org/drools/leaps/LeapsWorkingMemoryTest.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/test/java/org/drools/leaps/LeapsWorkingMemoryTest.java 2006-08-28 23:37:16 UTC (rev 5995)
+++ labs/jbossrules/trunk/drools-core/src/test/java/org/drools/leaps/LeapsWorkingMemoryTest.java 2006-08-29 00:48:55 UTC (rev 5996)
@@ -30,10 +30,10 @@
assertEquals(1,
tms.getAssertMap().size() );
key = tms.get( string );
- assertNotSame( fd, key.getFactHandle() );
+ assertSame( fd, key.getFactHandle() );
assertNull( key.getOtherFactHandle() );
- workingMemory.retractObject( key.getFactHandle() );
+ workingMemory.retractObject(fd);
assertEquals(0,
tms.getAssertMap().size() );
More information about the jboss-svn-commits
mailing list