Author: bagerman Date: 2006-05-13 10:12:32 -0400 (Sat, 13 May 2006) New Revision: 4214 Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/LeapsTest.java labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.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/WorkingMemoryImpl.java Log: JBRULES-233 for leaps 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-05-13 10:11:23 UTC (rev 4213) +++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/LeapsTest.java 2006-05-13 14:12:32 UTC (rev 4214) @@ -162,9 +162,4 @@ assertTrue( "rule2", list.contains( "rule2" ) ); } - - public void testLogicalAssertionsDynamicRule() throws Exception { - // TODO FIXME - } - } Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java 2006-05-13 10:11:23 UTC (rev 4213) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java 2006-05-13 14:12:32 UTC (rev 4214) @@ -111,7 +111,9 @@ protected long propagationIdCounter; private ReentrantLock lock = new ReentrantLock( ); - + + private List factQueue = new ArrayList( ); + public AbstractWorkingMemory(RuleBase ruleBase, FactHandleFactory handleFactory) { this.ruleBase = ruleBase; @@ -377,8 +379,52 @@ return this.justified; } + public long getNextPropagationIdCounter() { + return this.propagationIdCounter++; + } + abstract public void dispose(); + public void removeLogicalDependencies(Activation activation, + PropagationContext context, + Rule rule) throws FactException { + org.drools.util.LinkedList list = activation.getLogicalDependencies(); + if ( list == null || list.isEmpty() ) { + return; + } + for ( LogicalDependency node = (LogicalDependency) list.getFirst(); node != null; node = (LogicalDependency) node.getNext() ) { + InternalFactHandle handle = (InternalFactHandle) node.getFactHandle(); + Set set = (Set) this.justified.get( handle.getId( ) ); + // check set for null because in some weird cases on logical assertion + // it comes back with the same activation/handle and tries on + // already cleaned this.justified. only happens on removal of rule + // from the working memory + if (set != null) { + set.remove( node ); + if (set.isEmpty( )) { + this.justified.remove( handle.getId( ) ); + // this needs to be scheduled so we don't upset the current + // working memory operation + this.factQueue.add( new WorkingMemoryRetractAction( handle, + false, + true, + context.getRuleOrigin( ), + context.getActivationOrigin( ) ) ); + } + } + } + } + + public void removeLogicalDependencies(FactHandle handle) throws FactException { + Set set = (Set) this.justified.remove( ((InternalFactHandle) handle).getId() ); + if ( set != null && !set.isEmpty() ) { + for ( Iterator it = set.iterator(); it.hasNext(); ) { + LogicalDependency node = (LogicalDependency) it.next(); + node.getJustifier().getLogicalDependencies().remove( node ); + } + } + } + public void addLogicalDependency(FactHandle handle, Activation activation, PropagationContext context, @@ -395,42 +441,55 @@ set.add( node ); } - public void removeLogicalDependencies( Activation activation, - PropagationContext context, - Rule rule ) throws FactException { - org.drools.util.LinkedList list = activation.getLogicalDependencies(); - if (list == null || list.isEmpty( )) { - return; - } - for (LogicalDependency node = (LogicalDependency) list.getFirst( ); node != null; node = (LogicalDependency) node.getNext( )) { - InternalFactHandle handle = (InternalFactHandle) node.getFactHandle( ); - Set set = (Set) this.justified.get( handle.getId( ) ); - set.remove( node ); - if (set.isEmpty( )) { - this.justified.remove( handle.getId( ) ); - retractObject( handle, - false, - true, - context.getRuleOrigin( ), - context.getActivationOrigin( ) ); + protected void propagateQueuedActions() { + if (!this.factQueue.isEmpty( )) { + for (Iterator it = this.factQueue.iterator( ); it.hasNext( );) { + WorkingMemoryAction action = (WorkingMemoryAction) it.next( ); + it.remove( ); + action.propagate( ); } } } - public void removeLogicalDependencies(FactHandle handle) throws FactException { - Set set = (Set) this.justified.remove( ((InternalFactHandle) handle).getId() ); - if ( set != null && !set.isEmpty() ) { - for ( Iterator it = set.iterator(); it.hasNext(); ) { - LogicalDependency node = (LogicalDependency) it.next(); - node.getJustifier().getLogicalDependencies().remove( node ); - } - } - } - public Lock getLock() { return this.lock; } + private interface WorkingMemoryAction { + public void propagate(); + } + + private class WorkingMemoryRetractAction implements WorkingMemoryAction { + private InternalFactHandle factHandle; + private boolean removeLogical; + private boolean updateEqualsMap; + private Rule ruleOrigin; + private Activation activationOrigin; + + + + public WorkingMemoryRetractAction(InternalFactHandle factHandle, + boolean removeLogical, + boolean updateEqualsMap, + Rule ruleOrigin, + Activation activationOrigin) { + super(); + this.factHandle = factHandle; + this.removeLogical = removeLogical; + this.updateEqualsMap = updateEqualsMap; + this.ruleOrigin = ruleOrigin; + this.activationOrigin = activationOrigin; + } + + public void propagate() { + retractObject( this.factHandle, + this.removeLogical, + this.updateEqualsMap, + this.ruleOrigin, + this.activationOrigin ); + } + } + protected static class FactStatus { private int counter; private String status; 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-05-13 10:11:23 UTC (rev 4213) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/FactTable.java 2006-05-13 14:12:32 UTC (rev 4214) @@ -46,7 +46,7 @@ * Tuples that are either already on agenda or are very close (missing * exists or have not facts matching) */ - private final LinkedList tuples; + private LinkedList tuples; /** * initializes base LeapsTable with appropriate Comparator and positive and @@ -67,9 +67,8 @@ * @param workingMemory * @param ruleHandle */ - public void addRule(WorkingMemoryImpl workingMemory, - RuleHandle ruleHandle) { - if ( !this.rules.contains( ruleHandle ) ) { + public void addRule( WorkingMemoryImpl workingMemory, RuleHandle ruleHandle ) { + if (!this.rules.contains( ruleHandle )) { this.rules.add( ruleHandle ); // push facts back to stack if needed this.checkAndAddFactsToStack( workingMemory ); @@ -81,8 +80,18 @@ * * @param ruleHandle */ - public void removeRule(RuleHandle ruleHandle) { + public void removeRule( RuleHandle ruleHandle ) { this.rules.remove( ruleHandle ); + // remove tuples that are still there + LinkedList list = new LinkedList( ); + + for (Iterator it = this.getTuplesIterator( ); it.hasNext( );) { + LeapsTuple tuple = (LeapsTuple) it.next( ); + if (ruleHandle.getLeapsRule( ).getRule( ) != tuple.getLeapsRule( ).getRule( )) { + list.add( tuple ); + } + } + this.tuples = list; } /** Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/WorkingMemoryImpl.java =================================================================== --- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/WorkingMemoryImpl.java 2006-05-13 10:11:23 UTC (rev 4213) +++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/leaps/WorkingMemoryImpl.java 2006-05-13 14:12:32 UTC (rev 4214) @@ -74,6 +74,8 @@ private final IdentityMap leapsRulesToHandlesMap = new IdentityMap( ); + private final IdentityMap rulesActivationsMap = new IdentityMap( ); + /** * Construct. * @@ -214,11 +216,11 @@ boolean logical, Rule rule, Activation activation ) throws FactException { - + FactHandleImpl handle ; this.getLock().lock( ); try { // check if the object already exists in the WM - FactHandleImpl handle = (FactHandleImpl) this.identityMap.get( object ); + handle = (FactHandleImpl) this.identityMap.get( object ); // lets see if the object is already logical asserted FactStatus logicalState = (FactStatus) this.equalsMap.get( object ); @@ -237,6 +239,7 @@ activation, activation.getPropagationContext( ), rule ); + return logicalState.getHandle( ); } @@ -294,7 +297,6 @@ activation, activation.getPropagationContext( ), rule ); - } // new leaps stack token @@ -380,12 +382,13 @@ } } } - - return handle; + propagateQueuedActions( ); } finally { - this.getLock().unlock( ); + this.getLock( ).unlock( ); } + + return handle; } /** @@ -555,6 +558,8 @@ activation ); this.workingMemoryEventSupport.fireObjectRetracted( context, handle, oldObject ); + + propagateQueuedActions(); } finally { this.getLock().unlock( ); @@ -586,14 +591,37 @@ } } + + + public void addLogicalDependency( FactHandle handle, + Activation activation, + PropagationContext context, + Rule rule ) throws FactException { + super.addLogicalDependency( handle, activation, context, rule ); + + LinkedList activations = (LinkedList) this.rulesActivationsMap.get( rule ); + if (activations == null) { + activations = new LinkedList( ); + this.rulesActivationsMap.put( rule, activations ); + } + activations.add( activation ); + } + + + public void removeLogicalDependencies( Activation activation, + PropagationContext context, + Rule rule ) throws FactException { + super.removeLogicalDependencies( activation, context, rule ); + } + /** * @see WorkingMemory */ - public void modifyObject(FactHandle handle, + public void modifyObject( FactHandle handle, Object object, Rule rule, Activation activation ) throws FactException { - this.getLock().lock( ); + this.getLock( ).lock( ); try { this.retractObject( handle ); @@ -624,9 +652,10 @@ handle, ( (FactHandleImpl) handle ).getObject( ), object ); + propagateQueuedActions( ); } finally { - this.getLock().unlock( ); + this.getLock( ).unlock( ); } } @@ -778,22 +807,36 @@ this.getLock( ).lock( ); try { ArrayList ruleHandlesList; - LeapsRule rule; + LeapsRule leapsRule; RuleHandle ruleHandle; for (Iterator it = rules.iterator( ); it.hasNext( );) { - rule = (LeapsRule) it.next( ); + leapsRule = (LeapsRule) it.next( ); // some times rules do not have "normal" constraints and only // not and exists - if (rule.getNumberOfColumns( ) > 0) { - ruleHandlesList = (ArrayList) this.leapsRulesToHandlesMap.remove( rule ); + if (leapsRule.getNumberOfColumns( ) > 0) { + ruleHandlesList = (ArrayList) this.leapsRulesToHandlesMap.remove( leapsRule ); for (int i = 0; i < ruleHandlesList.size( ); i++) { ruleHandle = (RuleHandle) ruleHandlesList.get( i ); // - this.getFactTable( rule.getColumnClassObjectTypeAtPosition( i ) ) + this.getFactTable( leapsRule.getColumnClassObjectTypeAtPosition( i ) ) .removeRule( ruleHandle ); } } + // } + Rule rule = ((LeapsRule)rules.get(0)).getRule( ); + List activations = (List) this.rulesActivationsMap.remove( rule ); + if (activations != null) { + for (Iterator activationsIt = activations.iterator( ); activationsIt.hasNext( );) { + Activation activation = (Activation) activationsIt.next( ); + ((LeapsTuple)activation.getTuple()).setActivation(null); + this.removeLogicalDependencies( activation, + activation.getPropagationContext( ), + rule ); + } + } + + propagateQueuedActions(); } finally { this.getLock( ).unlock( ); |