[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