[jboss-svn-commits] JBL Code SVN: r34229 - in labs/jbossrules/trunk: drools-api/src/main/java/org/drools/runtime/rule and 4 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Tue Jul 27 15:18:26 EDT 2010
Author: tirelli
Date: 2010-07-27 15:18:25 -0400 (Tue, 27 Jul 2010)
New Revision: 34229
Added:
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/runtime/conf/QueryListenerOption.java
Removed:
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/runtime/conf/QueryListenerClassOption.java
labs/jbossrules/trunk/drools-api/src/main/java/org/drools/runtime/rule/QueryViewChangedEventListener.java
Modified:
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/QueryTest.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/SessionConfiguration.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/InternalViewChangedEventListener.java
labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java
Log:
JBRULES-2596: fixing query performance by adding an alternative query listener that does not clone fact handles.
Deleted: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/runtime/conf/QueryListenerClassOption.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/runtime/conf/QueryListenerClassOption.java 2010-07-27 17:28:25 UTC (rev 34228)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/runtime/conf/QueryListenerClassOption.java 2010-07-27 19:18:25 UTC (rev 34229)
@@ -1,115 +0,0 @@
-/**
- * Copyright 2010 JBoss Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.drools.runtime.conf;
-
-import org.drools.runtime.rule.QueryViewChangedEventListener;
-
-
-/**
- * A class to configure the session query listener configuration.
- *
- * @author etirelli
- */
-public class QueryListenerClassOption implements SingleValueKnowledgeSessionOption {
-
- private static final long serialVersionUID = -8461267995706982981L;
-
- /**
- * The property name for the clock type configuration
- */
- public static final String PROPERTY_NAME = "drools.queryListener";
-
- /**
- * clock type
- */
- private final Class<? extends QueryViewChangedEventListener> queryListener;
-
- /**
- * Private constructor to enforce the use of the factory method
- * @param queryListener
- */
- private QueryListenerClassOption( Class<? extends QueryViewChangedEventListener> queryListener ) {
- this.queryListener = queryListener;
- }
-
- /**
- * This is a factory method for this Query Listener configuration.
- * The factory method is a best practice for the case where the
- * actual object construction is changed in the future.
- *
- * @param queryListener is the class that implements the actual query listener
- *
- * @return the actual type safe query listener configuration.
- */
- public static QueryListenerClassOption get( Class<? extends QueryViewChangedEventListener> queryListener ) {
- return new QueryListenerClassOption( queryListener );
- }
-
- /**
- * {@inheritDoc}
- */
- public String getPropertyName() {
- return PROPERTY_NAME;
- }
-
- /**
- * Returns the configured query listener class
- *
- * @return
- */
- public Class<? extends QueryViewChangedEventListener> getQueryListenerClass() {
- return queryListener;
- }
-
- /**
- * Returns a new instance of the query listener class
- *
- * @return
- */
- public QueryViewChangedEventListener newQueryListenerInstance() {
- try {
- return queryListener.newInstance();
- } catch ( Exception e ) {
- throw new RuntimeException( "Error instantiating configured query view listener class: '"+queryListener.getName()+"'", e );
- }
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + (( queryListener == null) ? 0 : queryListener.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if ( this == obj ) return true;
- if ( obj == null ) return false;
- if ( getClass() != obj.getClass() ) return false;
- QueryListenerClassOption other = (QueryListenerClassOption) obj;
- if ( queryListener == null ) {
- if ( other. queryListener != null ) return false;
- } else if ( ! queryListener.equals( other.queryListener ) ) return false;
- return true;
- }
-
- @Override
- public String toString() {
- return "QueryListenerOption( "+ queryListener +" )";
- }
-}
Added: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/runtime/conf/QueryListenerOption.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/runtime/conf/QueryListenerOption.java (rev 0)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/runtime/conf/QueryListenerOption.java 2010-07-27 19:18:25 UTC (rev 34229)
@@ -0,0 +1,73 @@
+/**
+ * Copyright 2010 JBoss Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.drools.runtime.conf;
+
+/**
+ * An enum to configure the session query listener configuration.
+ *
+ * Queries results are collected by a listener class. The "STANDARD"
+ * query listener class copies and disconnects fact handles and objects
+ * for the query results making them somewhat resilient to some working
+ * memory actions. Although, this copy is costly. For the cases where
+ * no concurrency exists between query execution and other working memory
+ * action, a light weight listener implementation can be used, preventing
+ * the copy and improving query performance significantly.
+ *
+ *
+ * @author etirelli
+ */
+public enum QueryListenerOption implements SingleValueKnowledgeSessionOption {
+
+ STANDARD("standard"),
+ LIGHTWEIGHT("lightweight");
+
+ /**
+ * The property name for the clock type configuration
+ */
+ public static final String PROPERTY_NAME = "drools.queryListener";
+
+ private String option;
+
+ QueryListenerOption(String option) {
+ this.option = option;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getPropertyName() {
+ return PROPERTY_NAME;
+ }
+
+ public String getAsString() {
+ return option;
+ }
+
+ public String toString() {
+ return "QueryListenerClassOption( " + option + " )";
+ }
+
+ public static QueryListenerOption determineQueryListenerClassOption(String option) {
+ if ( STANDARD.getAsString().equalsIgnoreCase( option ) ) {
+ return STANDARD;
+ } else if ( LIGHTWEIGHT.getAsString().equalsIgnoreCase( option ) ) {
+ return LIGHTWEIGHT;
+ }
+ throw new IllegalArgumentException( "Illegal enum value '" + option + "' for QueryListenerOption" );
+ }
+
+}
Property changes on: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/runtime/conf/QueryListenerOption.java
___________________________________________________________________
Name: svn:executable
+ *
Deleted: labs/jbossrules/trunk/drools-api/src/main/java/org/drools/runtime/rule/QueryViewChangedEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-api/src/main/java/org/drools/runtime/rule/QueryViewChangedEventListener.java 2010-07-27 17:28:25 UTC (rev 34228)
+++ labs/jbossrules/trunk/drools-api/src/main/java/org/drools/runtime/rule/QueryViewChangedEventListener.java 2010-07-27 19:18:25 UTC (rev 34229)
@@ -1,20 +0,0 @@
-package org.drools.runtime.rule;
-
-/**
- * Copyright 2010 JBoss Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-public interface QueryViewChangedEventListener {
-
-}
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/QueryTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/QueryTest.java 2010-07-27 17:28:25 UTC (rev 34228)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/QueryTest.java 2010-07-27 19:18:25 UTC (rev 34229)
@@ -48,7 +48,7 @@
import org.drools.rule.Variable;
import org.drools.runtime.KnowledgeSessionConfiguration;
import org.drools.runtime.StatefulKnowledgeSession;
-import org.drools.runtime.conf.QueryListenerClassOption;
+import org.drools.runtime.conf.QueryListenerOption;
import org.drools.runtime.rule.LiveQuery;
import org.drools.runtime.rule.QueryResultsRow;
import org.drools.runtime.rule.Row;
@@ -754,14 +754,14 @@
}
public void testStandardQueryListener() {
- runQueryListenerTest( QueryListenerClassOption.get( StandardQueryViewChangedEventListener.class ) );
+ runQueryListenerTest( QueryListenerOption.STANDARD );
}
public void testNonCloningQueryListener() {
- runQueryListenerTest( QueryListenerClassOption.get( NonCloningQueryViewListener.class ) );
+ runQueryListenerTest( QueryListenerOption.LIGHTWEIGHT );
}
- public void runQueryListenerTest( QueryListenerClassOption option ) {
+ public void runQueryListenerTest( QueryListenerOption option ) {
String str = "";
str += "package org.drools\n";
str += "query cheeses(String $type) \n";
@@ -803,7 +803,7 @@
}
long end = System.currentTimeMillis();
- //System.out.println("Query time = "+(end-start));
+ System.out.println("Query time = "+(end-start));
}
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/SessionConfiguration.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/SessionConfiguration.java 2010-07-27 17:28:25 UTC (rev 34228)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/SessionConfiguration.java 2010-07-27 19:18:25 UTC (rev 34229)
@@ -24,8 +24,6 @@
import java.util.Map;
import java.util.Properties;
-import org.drools.base.InternalViewChangedEventListener;
-import org.drools.base.StandardQueryViewChangedEventListener;
import org.drools.command.CommandService;
import org.drools.core.util.ConfFileUtils;
import org.drools.core.util.StringUtils;
@@ -38,11 +36,10 @@
import org.drools.runtime.conf.KeepReferenceOption;
import org.drools.runtime.conf.KnowledgeSessionOption;
import org.drools.runtime.conf.MultiValueKnowledgeSessionOption;
-import org.drools.runtime.conf.QueryListenerClassOption;
+import org.drools.runtime.conf.QueryListenerOption;
import org.drools.runtime.conf.SingleValueKnowledgeSessionOption;
import org.drools.runtime.conf.WorkItemHandlerOption;
import org.drools.runtime.process.WorkItemHandler;
-import org.drools.runtime.rule.QueryViewChangedEventListener;
import org.drools.util.ChainedProperties;
import org.drools.util.ClassLoaderUtil;
import org.mvel2.MVEL;
@@ -79,7 +76,7 @@
private ClockType clockType;
- private QueryListenerClassOption queryListener;
+ private QueryListenerOption queryListener;
private Map<String, WorkItemHandler> workItemHandlers;
private ProcessInstanceManagerFactory processInstanceManagerFactory;
@@ -94,7 +91,7 @@
out.writeBoolean( immutable );
out.writeBoolean( keepReference );
out.writeObject( clockType );
- out.writeObject( queryListener.getQueryListenerClass().getName() );
+ out.writeObject( queryListener );
}
@SuppressWarnings("unchecked")
@@ -104,9 +101,7 @@
immutable = in.readBoolean();
keepReference = in.readBoolean();
clockType = (ClockType) in.readObject();
- queryListener = QueryListenerClassOption.get( (Class< ? extends QueryViewChangedEventListener>) Class.forName( (String) in.readObject(),
- true,
- this.classLoader ) );
+ queryListener = (QueryListenerOption) in.readObject();
}
/**
@@ -151,10 +146,10 @@
"true" ) ).booleanValue() );
setClockType( ClockType.resolveClockType( this.chainedProperties.getProperty( ClockTypeOption.PROPERTY_NAME,
- "realtime" ) ) );
+ ClockType.REALTIME_CLOCK.getId() ) ) );
- setQueryListenerClass( this.chainedProperties.getProperty( QueryListenerClassOption.PROPERTY_NAME,
- StandardQueryViewChangedEventListener.class.getName() ) );
+ setQueryListenerClass( this.chainedProperties.getProperty( QueryListenerOption.PROPERTY_NAME,
+ QueryListenerOption.STANDARD.getAsString() ) );
}
public void addProperties(Properties properties) {
@@ -174,8 +169,8 @@
setKeepReference( StringUtils.isEmpty( value ) ? true : Boolean.parseBoolean( value ) );
} else if ( name.equals( ClockTypeOption.PROPERTY_NAME ) ) {
setClockType( ClockType.resolveClockType( StringUtils.isEmpty( value ) ? "realtime" : value ) );
- } else if ( name.equals( QueryListenerClassOption.PROPERTY_NAME ) ) {
- setQueryListenerClass( StringUtils.isEmpty( value ) ? StandardQueryViewChangedEventListener.class.getName() : value );
+ } else if ( name.equals( QueryListenerOption.PROPERTY_NAME ) ) {
+ setQueryListenerClass( StringUtils.isEmpty( value ) ? QueryListenerOption.STANDARD.getAsString() : value );
}
}
@@ -189,10 +184,9 @@
return Boolean.toString( this.keepReference );
} else if ( name.equals( ClockTypeOption.PROPERTY_NAME ) ) {
return this.clockType.toExternalForm();
- } else if ( name.equals( QueryListenerClassOption.PROPERTY_NAME ) ) {
- return this.queryListener.getQueryListenerClass().getName();
+ } else if ( name.equals( QueryListenerOption.PROPERTY_NAME ) ) {
+ return this.queryListener.getAsString();
}
-
return null;
}
@@ -240,19 +234,12 @@
@SuppressWarnings("unchecked")
private void setQueryListenerClass(String property) {
checkCanChange();
- try {
- Class< ? extends InternalViewChangedEventListener> listenerClass = (Class< ? extends InternalViewChangedEventListener>) Class.forName( property,
- true,
- this.classLoader );
- setQueryListenerClass( listenerClass );
- } catch ( ClassNotFoundException e ) {
- throw new RuntimeDroolsException("Unable to find query listener class : '"+property+"'", e);
- }
+ this.queryListener = QueryListenerOption.determineQueryListenerClassOption( property );
}
- private void setQueryListenerClass(Class< ? extends InternalViewChangedEventListener> listenerClass) {
+ private void setQueryListenerClass( QueryListenerOption option ) {
checkCanChange();
- this.queryListener = QueryListenerClassOption.get( listenerClass );
+ this.queryListener = option;
}
public Map<String, WorkItemHandler> getWorkItemHandlers() {
@@ -456,7 +443,7 @@
return (T) ClockTypeOption.get( getClockType().toExternalForm() );
} else if ( KeepReferenceOption.class.equals( option ) ) {
return (T) (this.keepReference ? KeepReferenceOption.YES : KeepReferenceOption.NO);
- } else if ( QueryListenerClassOption.class.equals( option ) ) {
+ } else if ( QueryListenerOption.class.equals( option ) ) {
return (T) this.queryListener;
}
return null;
@@ -480,8 +467,8 @@
} else if ( option instanceof WorkItemHandlerOption ) {
getWorkItemHandlers().put( ((WorkItemHandlerOption) option).getName(),
((WorkItemHandlerOption) option).getHandler() );
- } else if ( option instanceof QueryListenerClassOption ) {
- this.queryListener = (QueryListenerClassOption) option;
+ } else if ( option instanceof QueryListenerOption ) {
+ this.queryListener = (QueryListenerOption) option;
}
}
@@ -493,7 +480,7 @@
this.classLoader = classLoader;
}
- public QueryListenerClassOption getQueryListenerOption() {
+ public QueryListenerOption getQueryListenerOption() {
return this.queryListener;
}
Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/InternalViewChangedEventListener.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/InternalViewChangedEventListener.java 2010-07-27 17:28:25 UTC (rev 34228)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/base/InternalViewChangedEventListener.java 2010-07-27 19:18:25 UTC (rev 34229)
@@ -21,10 +21,9 @@
import org.drools.common.InternalWorkingMemory;
import org.drools.reteoo.LeftTuple;
import org.drools.rule.Rule;
-import org.drools.runtime.rule.QueryViewChangedEventListener;
import org.drools.spi.PropagationContext;
-public interface InternalViewChangedEventListener extends QueryViewChangedEventListener {
+public interface InternalViewChangedEventListener {
public void rowAdded(Rule rule,
LeftTuple tuple,
PropagationContext context,
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-07-27 17:28:25 UTC (rev 34228)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/reteoo/ReteooWorkingMemory.java 2010-07-27 19:18:25 UTC (rev 34229)
@@ -27,6 +27,8 @@
import org.drools.SessionConfiguration;
import org.drools.base.DroolsQuery;
import org.drools.base.InternalViewChangedEventListener;
+import org.drools.base.NonCloningQueryViewListener;
+import org.drools.base.StandardQueryViewChangedEventListener;
import org.drools.common.AbstractWorkingMemory;
import org.drools.common.DefaultAgenda;
import org.drools.common.EventFactHandle;
@@ -99,6 +101,7 @@
this.agenda = new DefaultAgenda( ruleBase );
this.agenda.setWorkingMemory( this );
}
+
public ReteooWorkingMemory(final int id,
final InternalRuleBase ruleBase,
final SessionConfiguration config,
@@ -106,20 +109,19 @@
final WorkingMemoryEventSupport workingMemoryEventSupport,
final AgendaEventSupport agendaEventSupport,
final RuleFlowEventSupport ruleFlowEventSupport) {
- super( id,
+ super( id,
ruleBase,
ruleBase.newFactHandleFactory(),
config,
environment,
workingMemoryEventSupport,
agendaEventSupport,
- ruleFlowEventSupport);
+ ruleFlowEventSupport );
this.agenda = new DefaultAgenda( ruleBase );
this.agenda.setWorkingMemory( this );
-}
+ }
-
public ReteooWorkingMemory(final int id,
final InternalRuleBase ruleBase,
final FactHandleFactory handleFactory,
@@ -167,7 +169,7 @@
this.lock.lock();
DroolsQuery queryObject = new DroolsQuery( query,
arguments,
- (InternalViewChangedEventListener) this.config.getQueryListenerOption().newQueryListenerInstance(),
+ getQueryListenerInstance(),
false );
InternalFactHandle handle = this.handleFactory.newFactHandle( queryObject,
this.getObjectTypeConfigurationRegistry().getObjectTypeConf( EntryPoint.DEFAULT,
@@ -198,10 +200,20 @@
endOperation();
}
}
-
+
+ private InternalViewChangedEventListener getQueryListenerInstance() {
+ switch ( this.config.getQueryListenerOption() ) {
+ case STANDARD :
+ return new StandardQueryViewChangedEventListener();
+ case LIGHTWEIGHT :
+ return new NonCloningQueryViewListener();
+ }
+ return null;
+ }
+
public LiveQuery openLiveQuery(final String query,
- final Object[] arguments,
- final ViewChangedEventListener listener) {
+ final Object[] arguments,
+ final ViewChangedEventListener listener) {
try {
startOperation();
@@ -209,7 +221,7 @@
this.lock.lock();
DroolsQuery queryObject = new DroolsQuery( query,
arguments,
- new OpenQueryViewChangedEventListenerAdapter(listener),
+ new OpenQueryViewChangedEventListenerAdapter( listener ),
true );
InternalFactHandle handle = this.handleFactory.newFactHandle( queryObject,
this.getObjectTypeConfigurationRegistry().getObjectTypeConf( EntryPoint.DEFAULT,
@@ -222,36 +234,37 @@
null,
this.typeConfReg.getObjectTypeConf( this.entryPoint,
queryObject ) );
-
- return new LiveQueryImpl( this, handle );
+
+ return new LiveQueryImpl( this,
+ handle );
} finally {
this.lock.unlock();
this.ruleBase.readUnlock();
endOperation();
}
- }
+ }
public void closeLiveQuery(final InternalFactHandle factHandle) {
- try {
- startOperation();
- this.ruleBase.readLock();
- this.lock.lock();
+ try {
+ startOperation();
+ this.ruleBase.readLock();
+ this.lock.lock();
- getEntryPointNode().retractObject( factHandle,
- null,
- this.getObjectTypeConfigurationRegistry().getObjectTypeConf( this.getEntryPoint(),
- factHandle.getObject() ),
- this );
- getFactHandleFactory().destroyFactHandle( factHandle );
-
- } finally {
- this.lock.unlock();
- this.ruleBase.readUnlock();
- endOperation();
- }
- }
-
+ getEntryPointNode().retractObject( factHandle,
+ null,
+ this.getObjectTypeConfigurationRegistry().getObjectTypeConf( this.getEntryPoint(),
+ factHandle.getObject() ),
+ this );
+ getFactHandleFactory().destroyFactHandle( factHandle );
+
+ } finally {
+ this.lock.unlock();
+ this.ruleBase.readUnlock();
+ endOperation();
+ }
+ }
+
public static class WorkingMemoryReteAssertAction
implements
WorkingMemoryAction {
More information about the jboss-svn-commits
mailing list