[jboss-svn-commits] JBL Code SVN: r36090 - in labs/jbossrules/trunk/drools-core/src/main/java/org/drools: impl and 1 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Sun Nov 28 01:02:37 EST 2010
Author: mark.proctor at jboss.com
Date: 2010-11-28 01:02:35 -0500 (Sun, 28 Nov 2010)
New Revision: 36090
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/InternalWorkingMemory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemoryEntryPoint.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/NamedEntryPoint.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/impl/StatefulKnowledgeSessionImpl.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
Log:
JBRULES-2807 Refactor WorkingMemory so all entry points use the same code
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 2010-11-26 18:49:25 UTC (rev 36089)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/AbstractWorkingMemory.java 2010-11-28 06:02:35 UTC (rev 36090)
@@ -117,26 +117,14 @@
implements
InternalWorkingMemoryActions,
EventSupport,
- ProcessEventManager,
- PropertyChangeListener {
- // ------------------------------------------------------------
- // Constants
- // ------------------------------------------------------------
- protected static final Class[] ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES = new Class[]{PropertyChangeListener.class};
- private static final int NODE_MEMORIES_ARRAY_GROWTH = 32;
+ ProcessEventManager {
- // ------------------------------------------------------------
- // Instance members
- // ------------------------------------------------------------
protected int id;
- /** The arguments used when adding/removing a property change listener. */
- protected Object[] addRemovePropertyChangeListenerArgs;
-
/** The actual memory for the <code>JoinNode</code>s. */
protected NodeMemories nodeMemories;
- protected ObjectStore objectStore;
+ protected NamedEntryPoint defaultEntryPoint;
/** Global values which are associated with this memory. */
protected GlobalResolver globalResolver;
@@ -185,14 +173,9 @@
private WorkItemManager workItemManager;
private TimeMachine timeMachine;
-
+
private TimerService timerService;
- protected transient ObjectTypeConfigurationRegistry typeConfReg;
-
- protected EntryPoint entryPoint;
- protected transient EntryPointNode entryPointNode;
-
protected Map<String, WorkingMemoryEntryPoint> entryPoints;
protected InternalFactHandle initialFactHandle;
@@ -201,10 +184,8 @@
protected PartitionManager partitionManager;
- protected transient AtomicReference<ExternalExecutorService> threadPool = new AtomicReference<ExternalExecutorService>();
+ protected transient AtomicReference<ExternalExecutorService> threadPool = new AtomicReference<ExternalExecutorService>();
- private Map<InternalFactHandle, PropagationContext> modifyContexts;
-
private InternalKnowledgeRuntime kruntime;
private Map<String, ExitPoint> exitPoints;
@@ -221,11 +202,11 @@
// this is the timestamp of the end of the last operation, based on the session clock,
// or -1 if there are operation being executed at this moment
private AtomicLong lastIdleTimestamp;
-
+
private InternalProcessRuntime processRuntime;
-
- private transient ObjectMarshallingStrategyStore marshallingStore;
+ private transient ObjectMarshallingStrategyStore marshallingStore;
+
// ------------------------------------------------------------
// Constructors
// ------------------------------------------------------------
@@ -268,7 +249,7 @@
config,
environment,
workingMemoryEventSupport,
- agendaEventSupport);
+ agendaEventSupport );
}
public AbstractWorkingMemory(final int id,
@@ -286,7 +267,7 @@
config,
environment,
new WorkingMemoryEventSupport(),
- new AgendaEventSupport());
+ new AgendaEventSupport() );
}
public AbstractWorkingMemory(final int id,
@@ -328,12 +309,11 @@
this.sequential = conf.isSequential();
-
if ( initialFactHandle == null ) {
this.initialFactHandle = handleFactory.newFactHandle( InitialFactImpl.getInstance(),
null,
this,
- this);
+ this );
} else {
this.initialFactHandle = initialFactHandle;
}
@@ -341,7 +321,6 @@
this.actionQueue = new ConcurrentLinkedQueue<WorkingMemoryAction>();
this.evaluatingActionQueue = new AtomicBoolean( false );
- this.addRemovePropertyChangeListenerArgs = new Object[]{this};
this.workingMemoryEventSupport = workingMemoryEventSupport;
this.agendaEventSupport = agendaEventSupport;
this.__ruleBaseEventListeners = new LinkedList();
@@ -352,14 +331,11 @@
timerService = TimerServiceFactory.getTimerService( this.config );
this.nodeMemories = new ConcurrentNodeMemories( this.ruleBase );
-
- this.tms = new TruthMaintenanceSystem(this);
+ this.tms = new TruthMaintenanceSystem( this );
+
this.propagationIdCounter = new AtomicLong( propagationContext );
- this.objectStore = new SingleThreadedObjectStore( conf,
- this.lock );
-
// Only takes effect if are using idententity behaviour for assert
if ( LogicalOverride.DISCARD.equals( conf.getLogicalOverride() ) ) {
this.discardOnLogicalOverride = true;
@@ -367,9 +343,7 @@
this.discardOnLogicalOverride = false;
}
- initEntryPointsMap();
this.firing = new AtomicBoolean( false );
- this.modifyContexts = new HashMap<InternalFactHandle, PropagationContext>();
this.exitPoints = new ConcurrentHashMap<String, ExitPoint>();
this.channels = new ConcurrentHashMap<String, Channel>();
initPartitionManagers();
@@ -378,7 +352,7 @@
this.opCounter = new AtomicLong( 0 );
this.lastIdleTimestamp = new AtomicLong( -1 );
- initManagementBeans();
+ initManagementBeans();
}
private void initManagementBeans() {
@@ -386,13 +360,13 @@
DroolsManagementAgent.getInstance().registerKnowledgeSession( this );
}
}
-
+
private InternalProcessRuntime createProcessRuntime() {
- try {
- return ProcessRuntimeFactory.newProcessRuntime(this);
- } catch (IllegalArgumentException e) {
- return null;
- }
+ try {
+ return ProcessRuntimeFactory.newProcessRuntime( this );
+ } catch ( IllegalArgumentException e ) {
+ return null;
+ }
}
public String getEntryPointId() {
@@ -424,21 +398,6 @@
// Instance methods
// ------------------------------------------------------------
- public void setRuleBase(final InternalRuleBase ruleBase) {
- this.ruleBase = ruleBase;
- this.nodeMemories.setRuleBaseReference( this.ruleBase );
- initTransient();
- }
-
- private void initEntryPointsMap() {
- this.entryPoints = new ConcurrentHashMap<String, WorkingMemoryEntryPoint>();
- this.entryPoints.put( "DEFAULT",
- this );
- this.entryPoint = EntryPoint.DEFAULT;
-
- updateEntryPointsCache();
- }
-
public void updateEntryPointsCache() {
Map<EntryPoint, EntryPointNode> reteEPs = this.ruleBase.getRete().getEntryPointNodes();
@@ -520,20 +479,40 @@
}
private void initTransient() {
- this.entryPointNode = this.ruleBase.getRete().getEntryPointNode( this.entryPoint );
- this.typeConfReg = new ObjectTypeConfigurationRegistry( this.ruleBase );
+ EntryPointNode epn = this.ruleBase.getRete().getEntryPointNode( EntryPoint.DEFAULT );
+
+ this.defaultEntryPoint = new NamedEntryPoint( EntryPoint.DEFAULT,
+ epn,
+ this );
+
+ this.entryPoints = new ConcurrentHashMap<String, WorkingMemoryEntryPoint>();
+
+ this.entryPoints.put( "DEFAULT",
+ this.defaultEntryPoint );
+
+ updateEntryPointsCache();
}
public SessionConfiguration getSessionConfiguration() {
return this.config;
}
+ public void reset() {
+ throw new UnsupportedOperationException( "This should not be called" );
+ }
+
public void reset(int handleId,
long handleCounter,
long propagationCounter) {
this.nodeMemories.clear();
this.agenda.clear();
- this.objectStore.clear();
+
+ for ( WorkingMemoryEntryPoint ep : this.entryPoints.values() ) {
+ // clear the state for each entry point
+ InternalWorkingMemoryEntryPoint iep = (InternalWorkingMemoryEntryPoint) ep;
+ iep.reset();
+ }
+
this.handleFactory.clear( handleId,
handleCounter );
this.tms.clear();
@@ -616,7 +595,7 @@
}
public void removeEventListener(ProcessEventListener listener) {
- ((ProcessEventManager) this.processRuntime).removeEventListener(listener);
+ ((ProcessEventManager) this.processRuntime).removeEventListener( listener );
}
public FactHandleFactory getFactHandleFactory() {
@@ -823,25 +802,25 @@
*
*/
public Object getObject(final org.drools.runtime.rule.FactHandle handle) {
- return this.objectStore.getObjectForHandle( (InternalFactHandle) handle );
+ return this.defaultEntryPoint.getObject( handle );
}
public ObjectStore getObjectStore() {
- return this.objectStore;
+ return ((InternalWorkingMemoryEntryPoint) this.defaultEntryPoint).getObjectStore();
}
/**
* @see WorkingMemory
*/
public FactHandle getFactHandle(final Object object) {
- return this.objectStore.getHandleForObject( object );
+ return this.defaultEntryPoint.getFactHandle( object );
}
/**
* @see WorkingMemory
*/
public FactHandle getFactHandleByIdentity(final Object object) {
- return this.objectStore.getHandleForObjectIdentity( object );
+ return getObjectStore().getHandleForObjectIdentity( object );
}
/**
@@ -849,7 +828,7 @@
* iteration may give unexpected results
*/
public Iterator iterateObjects() {
- return this.objectStore.iterateObjects();
+ return getObjectStore().iterateObjects();
}
/**
@@ -857,7 +836,7 @@
* iteration may give unexpected results
*/
public Iterator iterateObjects(org.drools.runtime.ObjectFilter filter) {
- return this.objectStore.iterateObjects( filter );
+ return getObjectStore().iterateObjects( filter );
}
/**
@@ -865,7 +844,7 @@
* iteration may give unexpected results
*/
public Iterator iterateFactHandles() {
- return this.objectStore.iterateFactHandles();
+ return getObjectStore().iterateFactHandles();
}
/**
@@ -873,7 +852,7 @@
* iteration may give unexpected results
*/
public Iterator iterateFactHandles(org.drools.runtime.ObjectFilter filter) {
- return this.objectStore.iterateFactHandles( filter );
+ return getObjectStore().iterateFactHandles( filter );
}
public abstract QueryResults getQueryResults(String query);
@@ -931,326 +910,25 @@
boolean logical,
final Rule rule,
final Activation activation) throws FactException {
- if ( object == null ) {
- // you cannot assert a null object
- return null;
- }
-
- try {
- startOperation();
-
- ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
- object );
- if ( logical && !typeConf.isTMSEnabled()) {
- enableTMS(object, typeConf);
- }
-
- InternalFactHandle handle = null;
-
- if ( isSequential() ) {
- handle = createHandle( object,
- typeConf );
- insert( handle,
- object,
- rule,
- activation,
- typeConf );
- return handle;
- }
- try {
- this.ruleBase.readLock();
- this.lock.lock();
- // check if the object already exists in the WM
- handle = (InternalFactHandle) this.objectStore.getHandleForObject( object );
-
- if ( typeConf.isTMSEnabled() ) {
-
- EqualityKey key = null;
-
- if ( handle == null ) {
- // lets see if the object is already logical asserted
- key = this.tms.get( object );
- } else {
- // Object is already asserted, so check and possibly correct its
- // status and then return the handle
- key = handle.getEqualityKey();
-
- if ( key.getStatus() == EqualityKey.STATED ) {
- // return null as you cannot justify a stated object.
- return handle;
- }
-
- if ( !logical ) {
- // this object was previously justified, so we have to override it to stated
- key.setStatus( EqualityKey.STATED );
- this.tms.removeLogicalDependencies( handle );
- } else {
- // this was object is already justified, so just add new logical dependency
- this.tms.addLogicalDependency( handle,
- activation,
- activation.getPropagationContext(),
- rule );
- }
-
- return handle;
- }
-
- // At this point we know the handle is null
- if ( key == null ) {
-
- handle = createHandle( object,
- typeConf );
-
- key = createEqualityKey(handle);
-
- this.tms.put( key );
-
- if ( !logical ) {
- key.setStatus( EqualityKey.STATED );
- } else {
- key.setStatus( EqualityKey.JUSTIFIED );
- this.tms.addLogicalDependency( handle,
- activation,
- activation.getPropagationContext(),
- rule );
- }
- } else if ( !logical ) {
- if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
- // Its previous justified, so switch to stated and remove logical dependencies
- final InternalFactHandle justifiedHandle = key.getFactHandle();
- this.tms.removeLogicalDependencies( justifiedHandle );
-
- if ( this.discardOnLogicalOverride ) {
- // override, setting to new instance, and return
- // existing handle
- key.setStatus( EqualityKey.STATED );
- handle = key.getFactHandle();
-
- if ( AssertBehaviour.IDENTITY.equals( this.ruleBase.getConfiguration().getAssertBehaviour() ) ) {
- // as assertMap may be using an "identity"
- // equality comparator,
- // we need to remove the handle from the map,
- // before replacing the object
- // and then re-add the handle. Otherwise we may
- // end up with a leak.
- this.objectStore.updateHandle( handle,
- object );
- } else {
- Object oldObject = handle.getObject();
- }
- return handle;
- } else {
- // override, then instantiate new handle for
- // assertion
- key.setStatus( EqualityKey.STATED );
- handle = createHandle( object,
- typeConf );
- handle.setEqualityKey( key );
- key.addFactHandle( handle );
- }
-
- } else {
- handle = createHandle( object,
- typeConf );
- key.addFactHandle( handle );
- handle.setEqualityKey( key );
-
- }
-
- } else {
- if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
- // only add as logical dependency if this wasn't previously stated
- this.tms.addLogicalDependency( key.getFactHandle(),
- activation,
- activation.getPropagationContext(),
- rule );
- return key.getFactHandle();
- } else {
- // You cannot justify a previously stated equality equal object, so return null
- return null;
- }
- }
-
- } else {
- if ( handle != null ) {
- return handle;
- }
- handle = createHandle( object,
- typeConf );
-
- }
-
- // if the dynamic parameter is true or if the user declared the fact type with the meta tag:
- // @propertyChangeSupport
- if ( dynamic || typeConf.isDynamic() ) {
- addPropertyChangeListener( object );
- }
-
- insert( handle,
- object,
- rule,
- activation,
- typeConf );
-
- } finally {
- this.lock.unlock();
- this.ruleBase.readUnlock();
- }
- return handle;
- } finally {
- endOperation();
- }
-
+ return this.defaultEntryPoint.insert( object,
+ dynamic,
+ logical,
+ rule,
+ activation );
}
- /** Side-effects, will add the created key to the handle. */
- private EqualityKey createEqualityKey(InternalFactHandle handle) {
- EqualityKey key = new EqualityKey( handle );
- handle.setEqualityKey( key );
- return key;
- }
-
- /**
- * TMS will be automatically enabled when the first logical insert happens.
- *
- * We will take all the already asserted objects of the same type and initialize
- * the equality map.
- *
- * @param object the logically inserted object.
- * @param conf the type's configuration.
- */
- private void enableTMS(Object object, ObjectTypeConf conf) {
-
-
- final Rete source = this.ruleBase.getRete();
- final ClassObjectType cot = new ClassObjectType( object.getClass() );
- final Map<ObjectType, ObjectTypeNode> map = source.getObjectTypeNodes( EntryPoint.DEFAULT );
- final ObjectTypeNode node = map.get( cot );
- final ObjectHashSet memory = (ObjectHashSet) this.getNodeMemory( node );
-
- // All objects of this type that are already there were certainly stated,
- // since this method call happens at the first logical insert, for any given type.
- org.drools.core.util.Iterator it = memory.iterator();
-
- for ( Object obj = it.next(); obj != null; obj = it.next() ) {
-
- org.drools.core.util.ObjectHashSet.ObjectEntry holder = (org.drools.core.util.ObjectHashSet.ObjectEntry) obj;
-
- InternalFactHandle handle = (InternalFactHandle) holder.getValue();
-
- if ( handle != null) {
- EqualityKey key = createEqualityKey(handle);
- key.setStatus(EqualityKey.STATED);
- this.tms.put(key);
- }
- }
-
- // Enable TMS for this type.
- conf.enableTMS();
-
- }
-
- private InternalFactHandle createHandle(final Object object,
- ObjectTypeConf typeConf) {
- InternalFactHandle handle;
- handle = this.handleFactory.newFactHandle( object,
- typeConf,
- this,
- this );
- this.objectStore.addHandle( handle,
- object );
- return handle;
- }
-
public void insert(final InternalFactHandle handle,
final Object object,
final Rule rule,
final Activation activation,
ObjectTypeConf typeConf) {
- this.ruleBase.executeQueuedActions();
-
- executeQueuedActions();
-
- if ( activation != null ) {
- // release resources so that they can be GC'ed
- activation.getPropagationContext().releaseResources();
- }
- final PropagationContext propagationContext = new PropagationContextImpl( getNextPropagationIdCounter(),
- PropagationContext.ASSERTION,
- rule,
- (activation == null) ? null : (LeftTuple) activation.getTuple(),
- handle,
- this.agenda.getActiveActivations(),
- this.agenda.getDormantActivations(),
- entryPoint );
-
- this.entryPointNode.assertObject( handle,
- propagationContext,
- typeConf,
- this );
-
- executeQueuedActions();
-
- this.workingMemoryEventSupport.fireObjectInserted( propagationContext,
- handle,
- object,
- this );
+ this.defaultEntryPoint.insert( handle,
+ object,
+ rule,
+ activation,
+ typeConf );
}
- protected void addPropertyChangeListener(final Object object) {
- try {
- final Method method = object.getClass().getMethod( "addPropertyChangeListener",
- AbstractWorkingMemory.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES );
-
- method.invoke( object,
- this.addRemovePropertyChangeListenerArgs );
- } catch ( final NoSuchMethodException e ) {
- System.err.println( "Warning: Method addPropertyChangeListener not found" + " on the class " + object.getClass() + " so Drools will be unable to process JavaBean" + " PropertyChangeEvents on the asserted Object" );
- } catch ( final IllegalArgumentException e ) {
- System.err.println( "Warning: The addPropertyChangeListener method" + " on the class " + object.getClass() + " does not take" + " a simple PropertyChangeListener argument" + " so Drools will be unable to process JavaBean"
- + " PropertyChangeEvents on the asserted Object" );
- } catch ( final IllegalAccessException e ) {
- System.err.println( "Warning: The addPropertyChangeListener method" + " on the class " + object.getClass() + " is not public" + " so Drools will be unable to process JavaBean" + " PropertyChangeEvents on the asserted Object" );
- } catch ( final InvocationTargetException e ) {
- System.err.println( "Warning: The addPropertyChangeListener method" + " on the class " + object.getClass() + " threw an InvocationTargetException" + " so Drools will be unable to process JavaBean"
- + " PropertyChangeEvents on the asserted Object: " + e.getMessage() );
- } catch ( final SecurityException e ) {
- System.err.println( "Warning: The SecurityManager controlling the class " + object.getClass() + " did not allow the lookup of a" + " addPropertyChangeListener method" + " so Drools will be unable to process JavaBean"
- + " PropertyChangeEvents on the asserted Object: " + e.getMessage() );
- }
- }
-
- protected void removePropertyChangeListener(final FactHandle handle) {
- Object object = null;
- try {
- object = ((InternalFactHandle) handle).getObject();
-
- if ( object != null ) {
- final Method mehod = object.getClass().getMethod( "removePropertyChangeListener",
- AbstractWorkingMemory.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES );
-
- mehod.invoke( object,
- this.addRemovePropertyChangeListenerArgs );
- }
- } catch ( final NoSuchMethodException e ) {
- // The removePropertyChangeListener method on the class
- // was not found so Drools will be unable to
- // stop processing JavaBean PropertyChangeEvents
- // on the retracted Object
- } catch ( final IllegalArgumentException e ) {
- throw new RuntimeDroolsException( "Warning: The removePropertyChangeListener method on the class " + object.getClass() + " does not take a simple PropertyChangeListener argument so Drools will be unable to stop processing JavaBean"
- + " PropertyChangeEvents on the retracted Object" );
- } catch ( final IllegalAccessException e ) {
- throw new RuntimeDroolsException( "Warning: The removePropertyChangeListener method on the class " + object.getClass() + " is not public so Drools will be unable to stop processing JavaBean PropertyChangeEvents on the retracted Object" );
- } catch ( final InvocationTargetException e ) {
- throw new RuntimeDroolsException( "Warning: The removePropertyChangeL istener method on the class " + object.getClass() + " threw an InvocationTargetException so Drools will be unable to stop processing JavaBean"
- + " PropertyChangeEvents on the retracted Object: " + e.getMessage() );
- } catch ( final SecurityException e ) {
- throw new RuntimeDroolsException( "Warning: The SecurityManager controlling the class " + object.getClass() + " did not allow the lookup of a removePropertyChangeListener method so Drools will be unable to stop processing JavaBean"
- + " PropertyChangeEvents on the retracted Object: " + e.getMessage() );
- }
- }
-
public void retract(final org.drools.runtime.rule.FactHandle handle) throws FactException {
retract( (org.drools.FactHandle) handle,
true,
@@ -1264,90 +942,15 @@
final boolean updateEqualsMap,
final Rule rule,
final Activation activation) throws FactException {
- try {
- this.ruleBase.readLock();
- this.lock.lock();
- startOperation();
- this.ruleBase.executeQueuedActions();
-
- InternalFactHandle handle = (InternalFactHandle) factHandle;
- if ( handle.getId() == -1 ) {
- // can't retract an already retracted handle
- return;
- }
-
- // the handle might have been disconnected, so reconnect if it has
- if ( handle.isDisconnected() ) {
- handle = this.objectStore.reconnect( handle );
- }
-
- removePropertyChangeListener( handle );
-
- if ( activation != null ) {
- // release resources so that they can be GC'ed
- activation.getPropagationContext().releaseResources();
- }
- final PropagationContext propagationContext = new PropagationContextImpl( getNextPropagationIdCounter(),
- PropagationContext.RETRACTION,
- rule,
- (activation == null) ? null : (LeftTuple) activation.getTuple(),
- handle,
- this.agenda.getActiveActivations(),
- this.agenda.getDormantActivations(),
- this.entryPoint );
-
- final Object object = handle.getObject();
-
- final ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
- object );
-
- this.entryPointNode.retractObject( handle,
- propagationContext,
- typeConf,
- this );
-
- if ( typeConf.isTMSEnabled() ) {
-
- // Update the equality key, which maintains a list of stated
- // FactHandles
- final EqualityKey key = handle.getEqualityKey();
-
- // Its justified so attempt to remove any logical dependencies
- // for
- // the handle
- if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
- this.tms.removeLogicalDependencies( handle );
- }
-
- key.removeFactHandle( handle );
- handle.setEqualityKey( null );
-
- // If the equality key is now empty, then remove it
- if ( key.isEmpty() ) {
- this.tms.remove( key );
- }
- }
-
-
- this.workingMemoryEventSupport.fireObjectRetracted( propagationContext,
- handle,
- object,
- this );
-
- this.objectStore.removeHandle( handle );
-
- this.handleFactory.destroyFactHandle( handle );
-
- executeQueuedActions();
- } finally {
- endOperation();
- this.lock.unlock();
- this.ruleBase.readUnlock();
- }
+ this.defaultEntryPoint.retract( factHandle,
+ removeLogical,
+ updateEqualsMap,
+ rule,
+ activation );
}
public EntryPointNode getEntryPointNode() {
- return this.entryPointNode;
+ return ((InternalWorkingMemoryEntryPoint) this.defaultEntryPoint).getEntryPointNode();
}
public void update(final org.drools.runtime.rule.FactHandle handle,
@@ -1379,108 +982,17 @@
final Object object,
final Rule rule,
final Activation activation) throws FactException {
- try {
- this.ruleBase.readLock();
- this.lock.lock();
- startOperation();
- this.ruleBase.executeQueuedActions();
-
- // the handle might have been disconnected, so reconnect if it has
- if ( ((InternalFactHandle)factHandle).isDisconnected() ) {
- factHandle = this.objectStore.reconnect( factHandle );
- }
-
- final ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
- object );
-
- // only needed if we maintain tms, but either way we must get it before we do the retract
- int status = -1;
- if ( typeConf.isTMSEnabled() ) {
- status = ((InternalFactHandle) factHandle).getEqualityKey().getStatus();
- }
- final InternalFactHandle handle = (InternalFactHandle) factHandle;
- final Object originalObject = handle.getObject();
-
- if ( handle.getId() == -1 || object == null || (handle.isEvent() && ((EventFactHandle) handle).isExpired()) ) {
- // the handle is invalid, most likely already retracted, so return and we cannot assert a null object
- return;
- }
-
- if ( activation != null ) {
- // release resources so that they can be GC'ed
- activation.getPropagationContext().releaseResources();
- }
-
- if ( originalObject != object || !AssertBehaviour.IDENTITY.equals( this.ruleBase.getConfiguration().getAssertBehaviour() ) ) {
- this.objectStore.removeHandle( handle );
-
- // set anyway, so that it updates the hashCodes
- handle.setObject( object );
- this.objectStore.addHandle( handle,
- object );
- }
-
- if ( typeConf.isTMSEnabled() ) {
-
- // the hashCode and equality has changed, so we must update the
- // EqualityKey
- EqualityKey key = handle.getEqualityKey();
- key.removeFactHandle( handle );
-
-
- // If the equality key is now empty, then remove it
- if ( key.isEmpty() ) {
- this.tms.remove( key );
- }
-
- // 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 );
-
- }
-
- this.handleFactory.increaseFactHandleRecency( handle );
-
- final PropagationContext propagationContext = new PropagationContextImpl( getNextPropagationIdCounter(),
- PropagationContext.MODIFICATION,
- rule,
- (activation == null) ? null : (LeftTuple) activation.getTuple(),
- handle,
- this.agenda.getActiveActivations(),
- this.agenda.getDormantActivations(),
- entryPoint );
-
- this.entryPointNode.modifyObject( handle,
- propagationContext,
- typeConf,
- this );
-
- this.workingMemoryEventSupport.fireObjectUpdated( propagationContext,
- (org.drools.FactHandle) factHandle,
- originalObject,
- object,
- this );
-
- executeQueuedActions();
- } finally {
- endOperation();
- this.lock.unlock();
- this.ruleBase.readUnlock();
- }
+ this.defaultEntryPoint.update( factHandle,
+ object,
+ rule,
+ activation );
}
public void executeQueuedActions() {
try {
startOperation();
- if( evaluatingActionQueue.compareAndSet( false, true ) ) {
+ if ( evaluatingActionQueue.compareAndSet( false,
+ true ) ) {
try {
if ( !this.actionQueue.isEmpty() ) {
WorkingMemoryAction action = null;
@@ -1495,7 +1007,8 @@
}
}
} finally {
- evaluatingActionQueue.compareAndSet( true, false );
+ evaluatingActionQueue.compareAndSet( true,
+ false );
}
}
} finally {
@@ -1517,16 +1030,6 @@
}
}
- public void removeLogicalDependencies(final Activation activation,
- final PropagationContext context,
- final Rule rule) throws FactException {
-
- this.tms.removeLogicalDependencies( activation,
- context,
- rule );
-
- }
-
/**
* Retrieve the <code>JoinMemory</code> for a particular
* <code>JoinNode</code>.
@@ -1568,21 +1071,6 @@
* this.joinMemories.get( it.next( ) )).dump( ); } }
*/
- public void propertyChange(final PropertyChangeEvent event) {
- final Object object = event.getSource();
-
- try {
- FactHandle handle = getFactHandle( object );
- if ( handle == null ) {
- throw new FactException( "Update error: handle not found for object: " + object + ". Is it in the working memory?" );
- }
- update( handle,
- object );
- } catch ( final FactException e ) {
- throw new RuntimeDroolsException( e.getMessage() );
- }
- }
-
public long getNextPropagationIdCounter() {
return this.propagationIdCounter.incrementAndGet();
}
@@ -1601,18 +1089,19 @@
}
}
-
+
public InternalProcessRuntime getProcessRuntime() {
- return processRuntime;
+ return processRuntime;
}
public ProcessInstance startProcess(final String processId) {
- return processRuntime.startProcess(processId);
+ return processRuntime.startProcess( processId );
}
public ProcessInstance startProcess(String processId,
Map<String, Object> parameters) {
- return processRuntime.startProcess(processId, parameters);
+ return processRuntime.startProcess( processId,
+ parameters );
}
public Collection<ProcessInstance> getProcessInstances() {
@@ -1620,7 +1109,7 @@
}
public ProcessInstance getProcessInstance(long processInstanceId) {
- return processRuntime.getProcessInstance(processInstanceId);
+ return processRuntime.getProcessInstance( processInstanceId );
}
public WorkItemManager getWorkItemManager() {
@@ -1714,14 +1203,6 @@
this.timeMachine = timeMachine;
}
- public ExecutorService getExecutorService() {
- return null; // no executor service
- }
-
- public void setExecutorService(ExecutorService executor) {
- // no executor service, so nothing to set
- }
-
public WorkingMemoryEntryPoint getWorkingMemoryEntryPoint(String name) {
WorkingMemoryEntryPoint wmEntryPoint = this.entryPoints.get( name );
return wmEntryPoint;
@@ -1732,7 +1213,7 @@
}
public ObjectTypeConfigurationRegistry getObjectTypeConfigurationRegistry() {
- return this.typeConfReg;
+ return this.defaultEntryPoint.getObjectTypeConfigurationRegistry();
}
public InternalFactHandle getInitialFactHandle() {
@@ -1771,35 +1252,6 @@
this.ruleBase.readUnlock();
}
- // public static class FactHandleInvalidation implements WorkingMemoryAction
- // {
- // private final InternalFactHandle handle;
- //
- // public FactHandleInvalidation(InternalFactHandle handle) {
- // this.handle = handle;
- // }
- //
- // public void execute(InternalWorkingMemory workingMemory) {
- // workingMemory.getFactHandleFactory().destroyFactHandle( handle );
- // }
- //
- // public void write(WMSerialisationOutContext context) throws IOException {
- // context.writeInt( handle.getId() );
- // }
- //
- // public void readExternal(ObjectInput in) throws IOException,
- // ClassNotFoundException {
- // // TODO Auto-generated method stub
- //
- // }
- //
- // public void writeExternal(ObjectOutput out) throws IOException {
- // // TODO Auto-generated method stub
- //
- // }
- //
- // }
-
public void dispose() {
if ( this.ruleBase.getConfiguration().isMBeansEnabled() ) {
DroolsManagementAgent.getInstance().unregisterKnowledgeSession( this );
@@ -1810,8 +1262,8 @@
this.ruleBase.removeEventListener( (RuleBaseEventListener) it.next() );
}
this.stopPartitionManagers();
- if (processRuntime != null) {
- this.processRuntime.dispose();
+ if ( processRuntime != null ) {
+ this.processRuntime.dispose();
}
}
@@ -1855,7 +1307,7 @@
this.channels.put( name,
channel );
}
-
+
public void unregisterChannel(String name) {
this.channels.remove( name );
}
@@ -1869,7 +1321,7 @@
}
public long getFactCount() {
- return this.objectStore.size();
+ return getObjectStore().size();
}
public long getTotalFactCount() {
@@ -1959,11 +1411,11 @@
this.partitionManager.releaseTasks();
}
}
-
- public ObjectMarshallingStrategyStore getObjectMarshallingStrategyStore(){
- if(this.marshallingStore == null){
+
+ public ObjectMarshallingStrategyStore getObjectMarshallingStrategyStore() {
+ if ( this.marshallingStore == null ) {
this.marshallingStore = new ObjectMarshallingStrategyStore(
- (ObjectMarshallingStrategy[])this.environment.get(EnvironmentName.OBJECT_MARSHALLING_STRATEGIES));
+ (ObjectMarshallingStrategy[]) this.environment.get( EnvironmentName.OBJECT_MARSHALLING_STRATEGIES ) );
}
return this.marshallingStore;
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java 2010-11-26 18:49:25 UTC (rev 36089)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemory.java 2010-11-28 06:02:35 UTC (rev 36090)
@@ -51,8 +51,6 @@
public int getId();
public void setId(int id);
-
- void setRuleBase(final InternalRuleBase ruleBase);
public void setWorkingMemoryEventSupport(WorkingMemoryEventSupport workingMemoryEventSupport);
@@ -96,10 +94,6 @@
*/
public FactHandle getFactHandleByIdentity(final Object object);
- public void removeLogicalDependencies(final Activation activation,
- final PropagationContext context,
- final Rule rule) throws FactException;
-
void retract(final FactHandle factHandle,
final boolean removeLogical,
final boolean updateEqualsMap,
@@ -114,11 +108,7 @@
public TimeMachine getTimeMachine();
- public void setTimeMachine(TimeMachine tm);
-
- public ExecutorService getExecutorService();
-
- public void setExecutorService(ExecutorService executor);
+ public void setTimeMachine(TimeMachine tm);
public ObjectTypeConfigurationRegistry getObjectTypeConfigurationRegistry();
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemoryEntryPoint.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemoryEntryPoint.java 2010-11-26 18:49:25 UTC (rev 36089)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/InternalWorkingMemoryEntryPoint.java 2010-11-28 06:02:35 UTC (rev 36090)
@@ -19,6 +19,7 @@
import org.drools.FactException;
import org.drools.FactHandle;
import org.drools.RuleBase;
+import org.drools.reteoo.EntryPointNode;
import org.drools.rule.EntryPoint;
import org.drools.rule.Rule;
@@ -43,4 +44,10 @@
public InternalWorkingMemory getInternalWorkingMemory();
public FactHandle getFactHandleByIdentity(final Object object);
+
+ void reset();
+
+ ObjectStore getObjectStore();
+
+ EntryPointNode getEntryPointNode();
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/NamedEntryPoint.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/NamedEntryPoint.java 2010-11-26 18:49:25 UTC (rev 36089)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/common/NamedEntryPoint.java 2010-11-28 06:02:35 UTC (rev 36090)
@@ -19,9 +19,12 @@
*/
package org.drools.common;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
+import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
import org.drools.FactException;
@@ -31,22 +34,30 @@
import org.drools.WorkingMemory;
import org.drools.WorkingMemoryEntryPoint;
import org.drools.RuleBaseConfiguration.AssertBehaviour;
+import org.drools.base.ClassObjectType;
+import org.drools.core.util.ObjectHashSet;
import org.drools.impl.StatefulKnowledgeSessionImpl.ObjectStoreWrapper;
import org.drools.reteoo.EntryPointNode;
import org.drools.reteoo.LeftTuple;
import org.drools.reteoo.ObjectTypeConf;
+import org.drools.reteoo.ObjectTypeNode;
+import org.drools.reteoo.Rete;
import org.drools.rule.EntryPoint;
import org.drools.rule.Rule;
import org.drools.spi.Activation;
import org.drools.spi.FactHandleFactory;
+import org.drools.spi.ObjectType;
import org.drools.spi.PropagationContext;
public class NamedEntryPoint
implements
InternalWorkingMemoryEntryPoint,
- WorkingMemoryEntryPoint {
+ WorkingMemoryEntryPoint,
+ PropertyChangeListener {
+ protected static final Class[] ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES = new Class[]{PropertyChangeListener.class};
+
/** The arguments used when adding/removing a property change listener. */
- protected final Object[] addRemovePropertyChangeListenerArgs = new Object[]{this};
+ protected final Object[] addRemovePropertyChangeListenerArgs = new Object[]{this};
private static final long serialVersionUID = 510l;
@@ -89,6 +100,19 @@
this.lock );
}
+ public void reset() {
+ this.objectStore.clear();
+ }
+
+ public ObjectStore getObjectStore() {
+ return this.objectStore;
+ }
+
+ public EntryPointNode getEntryPointNode() {
+ return this.entryPointNode;
+ }
+
+
/**
* @see WorkingMemory
*/
@@ -120,46 +144,181 @@
}
try {
- this.ruleBase.readLock();
- this.lock.lock();
this.wm.startOperation();
+
ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
object );
- // check if the object already exists in the WM
- InternalFactHandle handle = (InternalFactHandle) this.objectStore.getHandleForObject( object );
+ if ( logical && !typeConf.isTMSEnabled()) {
+ enableTMS(object, typeConf);
+ }
- if ( handle != null ) {
- // already inserted, so return the same handle
+ InternalFactHandle handle = null;
+
+ if ( this.wm.isSequential() ) {
+ handle = createHandle( object,
+ typeConf );
+ insert( handle,
+ object,
+ rule,
+ activation,
+ typeConf );
return handle;
}
+ try {
+ this.ruleBase.readLock();
+ this.lock.lock();
+ // check if the object already exists in the WM
+ handle = (InternalFactHandle) this.objectStore.getHandleForObject( object );
- handle = this.handleFactory.newFactHandle( object,
- typeConf,
- wm,
- this );
- this.objectStore.addHandle( handle,
- object );
- if ( dynamic ) {
- addPropertyChangeListener( object );
+ if ( typeConf.isTMSEnabled() ) {
+
+ EqualityKey key = null;
+
+ if ( handle == null ) {
+ // lets see if the object is already logical asserted
+ key = this.wm.tms.get( object );
+ } else {
+ // Object is already asserted, so check and possibly correct its
+ // status and then return the handle
+ key = handle.getEqualityKey();
+
+ if ( key.getStatus() == EqualityKey.STATED ) {
+ // return null as you cannot justify a stated object.
+ return handle;
+ }
+
+ if ( !logical ) {
+ // this object was previously justified, so we have to override it to stated
+ key.setStatus( EqualityKey.STATED );
+ this.wm.tms.removeLogicalDependencies( handle );
+ } else {
+ // this was object is already justified, so just add new logical dependency
+ this.wm.tms.addLogicalDependency( handle,
+ activation,
+ activation.getPropagationContext(),
+ rule );
+ }
+
+ return handle;
+ }
+
+ // At this point we know the handle is null
+ if ( key == null ) {
+
+ handle = createHandle( object,
+ typeConf );
+
+ key = createEqualityKey(handle);
+
+ this.wm.tms.put( key );
+
+ if ( !logical ) {
+ key.setStatus( EqualityKey.STATED );
+ } else {
+ key.setStatus( EqualityKey.JUSTIFIED );
+ this.wm.tms.addLogicalDependency( handle,
+ activation,
+ activation.getPropagationContext(),
+ rule );
+ }
+ } else if ( !logical ) {
+ if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
+ // Its previous justified, so switch to stated and remove logical dependencies
+ final InternalFactHandle justifiedHandle = key.getFactHandle();
+ this.wm.tms.removeLogicalDependencies( justifiedHandle );
+
+ if ( this.wm.discardOnLogicalOverride ) {
+ // override, setting to new instance, and return
+ // existing handle
+ key.setStatus( EqualityKey.STATED );
+ handle = key.getFactHandle();
+
+ if ( AssertBehaviour.IDENTITY.equals( this.ruleBase.getConfiguration().getAssertBehaviour() ) ) {
+ // as assertMap may be using an "identity"
+ // equality comparator,
+ // we need to remove the handle from the map,
+ // before replacing the object
+ // and then re-add the handle. Otherwise we may
+ // end up with a leak.
+ this.objectStore.updateHandle( handle,
+ object );
+ } else {
+ Object oldObject = handle.getObject();
+ }
+ return handle;
+ } else {
+ // override, then instantiate new handle for
+ // assertion
+ key.setStatus( EqualityKey.STATED );
+ handle = createHandle( object,
+ typeConf );
+ handle.setEqualityKey( key );
+ key.addFactHandle( handle );
+ }
+
+ } else {
+ handle = createHandle( object,
+ typeConf );
+ key.addFactHandle( handle );
+ handle.setEqualityKey( key );
+
+ }
+
+ } else {
+ if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
+ // only add as logical dependency if this wasn't previously stated
+ this.wm.tms.addLogicalDependency( key.getFactHandle(),
+ activation,
+ activation.getPropagationContext(),
+ rule );
+ return key.getFactHandle();
+ } else {
+ // You cannot justify a previously stated equality equal object, so return null
+ return null;
+ }
+ }
+
+ } else {
+ if ( handle != null ) {
+ return handle;
+ }
+ handle = createHandle( object,
+ typeConf );
+
+ }
+
+ // if the dynamic parameter is true or if the user declared the fact type with the meta tag:
+ // @propertyChangeSupport
+ if ( dynamic || typeConf.isDynamic() ) {
+ addPropertyChangeListener( object );
+ }
+
+ insert( handle,
+ object,
+ rule,
+ activation,
+ typeConf );
+
+ } finally {
+ this.lock.unlock();
+ this.ruleBase.readUnlock();
}
- insert( handle,
- object,
- rule,
- activation );
return handle;
} finally {
this.wm.endOperation();
- this.ruleBase.readUnlock();
- this.lock.unlock();
}
+
}
- protected void insert(final InternalFactHandle handle,
- final Object object,
- final Rule rule,
- final Activation activation) {
+ public void insert(final InternalFactHandle handle,
+ final Object object,
+ final Rule rule,
+ final Activation activation,
+ ObjectTypeConf typeConf) {
this.ruleBase.executeQueuedActions();
+ this.wm.executeQueuedActions();
+
if ( activation != null ) {
// release resources so that they can be GC'ed
activation.getPropagationContext().releaseResources();
@@ -169,22 +328,21 @@
rule,
(activation == null) ? null : (LeftTuple) activation.getTuple(),
handle,
- -1,
- -1,
- this.entryPoint );
+ this.wm.agenda.getActiveActivations(),
+ this.wm.agenda.getDormantActivations(),
+ entryPoint );
this.entryPointNode.assertObject( handle,
propagationContext,
- this.typeConfReg.getObjectTypeConf( this.entryPoint,
- object ),
+ typeConf,
this.wm );
this.wm.executeQueuedActions();
- this.wm.getWorkingMemoryEventSupport().fireObjectInserted( propagationContext,
- handle,
- object,
- wm );
+ this.wm.workingMemoryEventSupport.fireObjectInserted( propagationContext,
+ handle,
+ object,
+ this.wm );
}
public void update(final org.drools.runtime.rule.FactHandle handle,
@@ -194,50 +352,55 @@
null,
null );
}
-
+
public void update(final org.drools.runtime.rule.FactHandle factHandle,
final Object object,
final Rule rule,
final Activation activation) throws FactException {
+
+ update( (org.drools.FactHandle) factHandle,
+ object,
+ rule,
+ activation );
+ }
+
+ public void update(org.drools.FactHandle factHandle,
+ final Object object,
+ final Rule rule,
+ final Activation activation) throws FactException {
try {
this.ruleBase.readLock();
this.lock.lock();
+ this.wm.startOperation();
this.ruleBase.executeQueuedActions();
- this.wm.startOperation();
+ // the handle might have been disconnected, so reconnect if it has
+ if ( ((InternalFactHandle)factHandle).isDisconnected() ) {
+ factHandle = this.objectStore.reconnect( factHandle );
+ }
+
+ final ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
+ object );
+
+ // only needed if we maintain tms, but either way we must get it before we do the retract
+ int status = -1;
+ if ( typeConf.isTMSEnabled() ) {
+ status = ((InternalFactHandle) factHandle).getEqualityKey().getStatus();
+ }
final InternalFactHandle handle = (InternalFactHandle) factHandle;
final Object originalObject = handle.getObject();
if ( handle.getId() == -1 || object == null || (handle.isEvent() && ((EventFactHandle) handle).isExpired()) ) {
- // the handle is invalid, most likely already retracted, so
- // return
- // and we cannot assert a null object
+ // the handle is invalid, most likely already retracted, so return and we cannot assert a null object
return;
}
- ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
- object );
-
if ( activation != null ) {
// release resources so that they can be GC'ed
activation.getPropagationContext().releaseResources();
}
- // Nowretract any trace of the original fact
- final PropagationContext propagationContext = new PropagationContextImpl( this.wm.getNextPropagationIdCounter(),
- PropagationContext.MODIFICATION,
- rule,
- (activation == null) ? null : (LeftTuple) activation.getTuple(),
- handle,
- -1,
- -1,
- this.entryPoint );
- this.entryPointNode.retractObject( handle,
- propagationContext,
- typeConf,
- this.wm );
-
- if ( (originalObject != object) || (this.ruleBase.getConfiguration().getAssertBehaviour() != AssertBehaviour.IDENTITY) ) {
+ if ( originalObject != object || !AssertBehaviour.IDENTITY.equals( this.ruleBase.getConfiguration().getAssertBehaviour() ) ) {
this.objectStore.removeHandle( handle );
// set anyway, so that it updates the hashCodes
@@ -246,24 +409,60 @@
object );
}
+ if ( typeConf.isTMSEnabled() ) {
+
+ // the hashCode and equality has changed, so we must update the
+ // EqualityKey
+ EqualityKey key = handle.getEqualityKey();
+ key.removeFactHandle( handle );
+
+
+ // If the equality key is now empty, then remove it
+ if ( key.isEmpty() ) {
+ this.wm.tms.remove( key );
+ }
+
+ // now use an existing EqualityKey, if it exists, else create a new one
+ key = this.wm.tms.get( object );
+ if ( key == null ) {
+ key = new EqualityKey( handle,
+ status );
+ this.wm.tms.put( key );
+ } else {
+ key.addFactHandle( handle );
+ }
+
+ handle.setEqualityKey( key );
+
+ }
+
this.handleFactory.increaseFactHandleRecency( handle );
- this.entryPointNode.assertObject( handle,
+ final PropagationContext propagationContext = new PropagationContextImpl( this.wm.getNextPropagationIdCounter(),
+ PropagationContext.MODIFICATION,
+ rule,
+ (activation == null) ? null : (LeftTuple) activation.getTuple(),
+ handle,
+ this.wm.agenda.getActiveActivations(),
+ this.wm.agenda.getDormantActivations(),
+ entryPoint );
+
+ this.entryPointNode.modifyObject( handle,
propagationContext,
typeConf,
this.wm );
- this.wm.getWorkingMemoryEventSupport().fireObjectUpdated( propagationContext,
- (org.drools.FactHandle) factHandle,
- originalObject,
- object,
- this.wm );
+ this.wm.workingMemoryEventSupport.fireObjectUpdated( propagationContext,
+ (org.drools.FactHandle) factHandle,
+ originalObject,
+ object,
+ this.wm );
- this.wm.executeQueuedActions();
+ this.wm.executeQueuedActions();
} finally {
this.wm.endOperation();
+ this.lock.unlock();
this.ruleBase.readUnlock();
- this.lock.unlock();
}
}
@@ -275,7 +474,7 @@
null );
}
- public void retract(final FactHandle factHandle,
+ public void retract(final org.drools.FactHandle factHandle,
final boolean removeLogical,
final boolean updateEqualsMap,
final Rule rule,
@@ -283,14 +482,20 @@
try {
this.ruleBase.readLock();
this.lock.lock();
+ this.wm.startOperation();
this.ruleBase.executeQueuedActions();
- this.wm.startOperation();
- final InternalFactHandle handle = (InternalFactHandle) factHandle;
+ InternalFactHandle handle = (InternalFactHandle) factHandle;
if ( handle.getId() == -1 ) {
// can't retract an already retracted handle
return;
}
+
+ // the handle might have been disconnected, so reconnect if it has
+ if ( handle.isDisconnected() ) {
+ handle = this.objectStore.reconnect( handle );
+ }
+
removePropertyChangeListener( handle );
if ( activation != null ) {
@@ -302,173 +507,64 @@
rule,
(activation == null) ? null : (LeftTuple) activation.getTuple(),
handle,
- -1,
- -1,
+ this.wm.agenda.getActiveActivations(),
+ this.wm.agenda.getDormantActivations(),
this.entryPoint );
- ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
- handle.getObject() );
-
- this.entryPointNode.retractObject( handle,
- propagationContext,
- typeConf,
- this.wm );
-
final Object object = handle.getObject();
+
+ final ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
+ object );
- this.wm.getWorkingMemoryEventSupport().fireObjectRetracted( propagationContext,
- handle,
- object,
- this.wm );
-
- this.objectStore.removeHandle( handle );
-
- this.handleFactory.destroyFactHandle( handle );
-
- this.wm.executeQueuedActions();
- } finally {
- this.wm.endOperation();
- this.ruleBase.readUnlock();
- this.lock.unlock();
- }
- }
-
- public void modifyRetract(final FactHandle factHandle) {
- modifyRetract( factHandle,
- null,
- null );
- }
-
- public void modifyRetract(final FactHandle factHandle,
- final Rule rule,
- final Activation activation) {
- try {
- this.ruleBase.readLock();
- this.lock.lock();
- this.ruleBase.executeQueuedActions();
- this.wm.startOperation();
-
- final InternalFactHandle handle = (InternalFactHandle) factHandle;
- // final Object originalObject = (handle.isShadowFact()) ?
- // ((ShadowProxy) handle.getObject()).getShadowedObject() :
- // handle.getObject();
-
- if ( handle.getId() == -1 || (handle.isEvent() && ((EventFactHandle) handle).isExpired()) ) {
- // the handle is invalid, most likely already retracted, so
- // return
- return;
- }
-
- if ( activation != null ) {
- // release resources so that they can be GC'ed
- activation.getPropagationContext().releaseResources();
- }
- // Nowretract any trace of the original fact
- final PropagationContext propagationContext = new PropagationContextImpl( this.wm.getNextPropagationIdCounter(),
- PropagationContext.MODIFICATION,
- rule,
- (activation == null) ? null : (LeftTuple) activation.getTuple(),
- handle,
- -1,
- -1,
- entryPoint );
-
- ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
- handle.getObject() );
-
this.entryPointNode.retractObject( handle,
propagationContext,
typeConf,
this.wm );
- } finally {
- this.wm.endOperation();
- this.ruleBase.readUnlock();
- this.lock.unlock();
- }
- }
+ if ( typeConf.isTMSEnabled() ) {
- public void modifyInsert(final FactHandle factHandle,
- final Object object) {
- modifyInsert( factHandle,
- object,
- null,
- null );
- }
+ // Update the equality key, which maintains a list of stated
+ // FactHandles
+ final EqualityKey key = handle.getEqualityKey();
- public void modifyInsert(final FactHandle factHandle,
- final Object object,
- final Rule rule,
- final Activation activation) {
- this.modifyInsert( EntryPoint.DEFAULT,
- factHandle,
- object,
- rule,
- activation );
- }
+ // Its justified so attempt to remove any logical dependencies
+ // for
+ // the handle
+ if ( key.getStatus() == EqualityKey.JUSTIFIED ) {
+ this.wm.tms.removeLogicalDependencies( handle );
+ }
- protected void modifyInsert(final EntryPoint entryPoint,
- final FactHandle factHandle,
- final Object object,
- final Rule rule,
- final Activation activation) {
- try {
- this.ruleBase.readLock();
- this.lock.lock();
- this.ruleBase.executeQueuedActions();
- this.wm.startOperation();
+ key.removeFactHandle( handle );
+ handle.setEqualityKey( null );
- final InternalFactHandle handle = (InternalFactHandle) factHandle;
- final Object originalObject = handle.getObject();
-
- if ( handle.getId() == -1 || (handle.isEvent() && ((EventFactHandle) handle).isExpired()) ) {
- // the handle is invalid, most likely already retracted, so
- // return
- return;
+ // If the equality key is now empty, then remove it
+ if ( key.isEmpty() ) {
+ this.wm.tms.remove( key );
+ }
}
+
- this.handleFactory.increaseFactHandleRecency( handle );
+ this.wm.workingMemoryEventSupport.fireObjectRetracted( propagationContext,
+ handle,
+ object,
+ this.wm );
- if ( activation != null ) {
- // release resources so that they can be GC'ed
- activation.getPropagationContext().releaseResources();
- }
- // Nowretract any trace of the original fact
- final PropagationContext propagationContext = new PropagationContextImpl( this.wm.getNextPropagationIdCounter(),
- PropagationContext.MODIFICATION,
- rule,
- (activation == null) ? null : (LeftTuple) activation.getTuple(),
- handle,
- -1,
- -1,
- entryPoint );
+ this.objectStore.removeHandle( handle );
- ObjectTypeConf typeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
- handle.getObject() );
+ this.handleFactory.destroyFactHandle( handle );
- this.entryPointNode.assertObject( handle,
- propagationContext,
- typeConf,
- this.wm );
-
- this.wm.getWorkingMemoryEventSupport().fireObjectUpdated( propagationContext,
- factHandle,
- originalObject,
- object,
- this.wm );
-
this.wm.executeQueuedActions();
} finally {
this.wm.endOperation();
+ this.lock.unlock();
this.ruleBase.readUnlock();
- this.lock.unlock();
}
}
protected void addPropertyChangeListener(final Object object) {
try {
final Method method = object.getClass().getMethod( "addPropertyChangeListener",
- AbstractWorkingMemory.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES );
+ NamedEntryPoint.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES );
method.invoke( object,
this.addRemovePropertyChangeListenerArgs );
@@ -495,7 +591,7 @@
if ( object != null ) {
final Method mehod = object.getClass().getMethod( "removePropertyChangeListener",
- AbstractWorkingMemory.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES );
+ NamedEntryPoint.ADD_REMOVE_PROPERTY_CHANGE_LISTENER_ARG_TYPES );
mehod.invoke( object,
this.addRemovePropertyChangeListenerArgs );
@@ -586,5 +682,80 @@
public long getFactCount() {
return this.objectStore.size();
}
+
+ private InternalFactHandle createHandle(final Object object,
+ ObjectTypeConf typeConf) {
+ InternalFactHandle handle;
+ handle = this.handleFactory.newFactHandle( object,
+ typeConf,
+ this.wm,
+ this );
+ this.objectStore.addHandle( handle,
+ object );
+ return handle;
+ }
+
+ /** Side-effects, will add the created key to the handle. */
+ private EqualityKey createEqualityKey(InternalFactHandle handle) {
+ EqualityKey key = new EqualityKey( handle );
+ handle.setEqualityKey( key );
+ return key;
+ }
+
+ /**
+ * TMS will be automatically enabled when the first logical insert happens.
+ *
+ * We will take all the already asserted objects of the same type and initialize
+ * the equality map.
+ *
+ * @param object the logically inserted object.
+ * @param conf the type's configuration.
+ */
+ private void enableTMS(Object object, ObjectTypeConf conf) {
+
+ final Rete source = this.ruleBase.getRete();
+ final ClassObjectType cot = new ClassObjectType( object.getClass() );
+ final Map<ObjectType, ObjectTypeNode> map = source.getObjectTypeNodes( EntryPoint.DEFAULT );
+ final ObjectTypeNode node = map.get( cot );
+ final ObjectHashSet memory = (ObjectHashSet) this.wm.getNodeMemory( node );
+
+ // All objects of this type that are already there were certainly stated,
+ // since this method call happens at the first logical insert, for any given type.
+ org.drools.core.util.Iterator it = memory.iterator();
+
+ for ( Object obj = it.next(); obj != null; obj = it.next() ) {
+
+ org.drools.core.util.ObjectHashSet.ObjectEntry holder = (org.drools.core.util.ObjectHashSet.ObjectEntry) obj;
+
+ InternalFactHandle handle = (InternalFactHandle) holder.getValue();
+
+ if ( handle != null) {
+ EqualityKey key = createEqualityKey(handle);
+ key.setStatus(EqualityKey.STATED);
+ this.wm.tms.put(key);
+ }
+ }
+
+ // Enable TMS for this type.
+ conf.enableTMS();
+
+ }
+
+ public void propertyChange(final PropertyChangeEvent event) {
+ final Object object = event.getSource();
+
+ try {
+ FactHandle handle = getFactHandle( object );
+ if ( handle == null ) {
+ throw new FactException( "Update error: handle not found for object: " + object + ". Is it in the working memory?" );
+ }
+ update( handle,
+ object );
+ } catch ( final FactException e ) {
+ throw new RuntimeDroolsException( e.getMessage() );
+ }
+ }
+
+
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/impl/StatefulKnowledgeSessionImpl.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/impl/StatefulKnowledgeSessionImpl.java 2010-11-26 18:49:25 UTC (rev 36089)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/impl/StatefulKnowledgeSessionImpl.java 2010-11-28 06:02:35 UTC (rev 36090)
@@ -67,6 +67,7 @@
import org.drools.event.rule.impl.ObjectInsertedEventImpl;
import org.drools.event.rule.impl.ObjectRetractedEventImpl;
import org.drools.event.rule.impl.ObjectUpdatedEventImpl;
+import org.drools.reteoo.EntryPointNode;
import org.drools.reteoo.ReteooWorkingMemory;
import org.drools.rule.EntryPoint;
import org.drools.rule.Rule;
@@ -115,7 +116,19 @@
this.session.setKnowledgeRuntime( this );
this.kbase = kbase;
}
+
+ public void reset() {
+ throw new UnsupportedOperationException("This should not be called");
+ }
+
+ public ObjectStore getObjectStore() {
+ return this.session.getObjectStore();
+ }
+ public EntryPointNode getEntryPointNode() {
+ return this.session.getEntryPointNode();
+ }
+
public int getId() {
return this.session.getId();
}
@@ -843,4 +856,5 @@
return this.session.getLastIdleTimestamp();
}
+
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java 2010-11-26 18:49:25 UTC (rev 36089)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java 2010-11-28 06:02:35 UTC (rev 36090)
@@ -170,8 +170,9 @@
arguments,
getQueryListenerInstance(),
false );
- ObjectTypeConf objectTypeConf = this.typeConfReg.getObjectTypeConf( this.entryPoint,
- queryObject );
+
+ ObjectTypeConf objectTypeConf = this.defaultEntryPoint.getObjectTypeConfigurationRegistry().getObjectTypeConf( this.defaultEntryPoint.getEntryPoint(),
+ queryObject );
InternalFactHandle handle = this.handleFactory.newFactHandle( queryObject,
objectTypeConf,
this,
@@ -233,8 +234,8 @@
queryObject,
null,
null,
- this.typeConfReg.getObjectTypeConf( this.entryPoint,
- queryObject ) );
+ this.defaultEntryPoint.getObjectTypeConfigurationRegistry().getObjectTypeConf( this.defaultEntryPoint.getEntryPoint(),
+ queryObject ) );
return new LiveQueryImpl( this,
handle );
@@ -430,7 +431,7 @@
}
public EntryPoint getEntryPoint() {
- return this.entryPoint;
+ return this.defaultEntryPoint.getEntryPoint();
}
public InternalWorkingMemory getInternalWorkingMemory() {
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java 2010-11-26 18:49:25 UTC (rev 36089)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/RuleTerminalNode.java 2010-11-28 06:02:35 UTC (rev 36090)
@@ -260,10 +260,10 @@
} else {
((InternalAgenda) workingMemory.getAgenda()).decreaseDormantActivations();
}
-
- workingMemory.removeLogicalDependencies( activation,
- context,
- this.rule );
+
+ workingMemory.getTruthMaintenanceSystem().removeLogicalDependencies( activation,
+ context,
+ this.rule );
}
public void modifyLeftTuple(InternalFactHandle factHandle,
More information about the jboss-svn-commits
mailing list