[Erp5-report] r42497 nicolas.dumazet - /erp5/trunk/products/ERP5Type/Base.py

nobody at svn.erp5.org nobody at svn.erp5.org
Thu Jan 20 09:13:56 CET 2011


Author: nicolas.dumazet
Date: Thu Jan 20 09:13:56 2011
New Revision: 42497

URL: http://svn.erp5.org?rev=42497&view=rev
Log:
and finally avoid iterating twice over the interaction list

It seems that the only methods that we wanted to match in the second pass
are class methods created during the first pass:
finding the newly created candidates is easy if we keep track of class methods before and after the first pass

And then, the ony interactions than *can* augment the existing workflow definitions
are the ones using regular expressions, according to the code comments.
Queue those interactions during the first pass to reduce the space search.

Finally, the second pass is cheaper because we *know* that methods do exist
and _are_ Workflow methods already.


The overall cost of creating workflow methods should be lower thanks to those
efforts.

Modified:
    erp5/trunk/products/ERP5Type/Base.py

Modified: erp5/trunk/products/ERP5Type/Base.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/Base.py?rev=42497&r1=42496&r2=42497&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/Base.py [utf8] (original)
+++ erp5/trunk/products/ERP5Type/Base.py [utf8] Thu Jan 20 09:13:56 2011
@@ -700,25 +700,29 @@ def initializePortalTypeDynamicWorkflowM
   if not interaction_workflow_dict:
     return
 
+  class_method_list = prop_holder.getClassMethodIdList(klass)
   # only compute once this (somehow) costly list
   all_method_id_list = prop_holder.getAccessorMethodIdList() + \
                        prop_holder.getWorkflowMethodIdList() + \
-                       prop_holder.getClassMethodIdList(klass)
+                       class_method_list
 
+  interaction_queue = []
   # XXX This part is (more or less...) a copy and paste
-  # We need to run this part twice in order to handle interactions of interactions
-  # ex. an interaction workflow creates a workflow method which matches
-  # the regexp of another interaction workflow
-  for wf_id in interaction_workflow_dict.keys()*2:
-    transition_id_set, trigger_dict = interaction_workflow_dict[wf_id]
+  for wf_id, v in interaction_workflow_dict.iteritems():
+    transition_id_set, trigger_dict = v
     for tr_id, tdef in trigger_dict.iteritems():
       # XXX Prefiltering per portal type would be more efficient
       for imethod_id in tdef.method_id:
         if wildcard_interaction_method_id_match(imethod_id):
           # Interactions workflows can use regexp based wildcard methods
-          method_id_matcher = re.compile(imethod_id) # XXX What happens if exception ?
+          # XXX What happens if exception ?
+          method_id_matcher = re.compile(imethod_id).match
+
+          # queue transitions using regexps for later examination
+          interaction_queue.append((wf_id, tr_id, tdef, method_id_matcher))
+
           # XXX - class stuff is missing here
-          method_id_list = filter(method_id_matcher.match, all_method_id_list)
+          method_id_list = filter(method_id_matcher, all_method_id_list)
         else:
           # Single method
           # XXX What if the method does not exist ?
@@ -733,7 +737,7 @@ def initializePortalTypeDynamicWorkflowM
               prop_holder.security.declareProtected(
                   Permissions.AccessContentsInformation, method_id)
             prop_holder.registerWorkflowMethod(method_id, wf_id, tr_id,
-                                                   tdef.once_per_transaction)
+                                               tdef.once_per_transaction)
             continue
 
           # Wrap method
@@ -757,6 +761,26 @@ def initializePortalTypeDynamicWorkflowM
           else:
             method.registerTransitionAlways(ptype, wf_id, tr_id)
 
+  if not interaction_queue:
+    return
+
+  new_method_set = set(prop_holder.getClassMethodItemList(klass))
+  added_method_set = new_method_set.difference(class_method_list)
+  # We need to run this part twice in order to handle interactions of interactions
+  # ex. an interaction workflow creates a workflow method which matches
+  # the regexp of another interaction workflow
+  for wf_id, tr_id, tdef, method_id_matcher in interaction_queue:
+    for method_id in filter(method_id_matcher, added_method_set):
+      # method must already exist and be a workflow method
+      method = getattr(klass, method_id)
+      transition_id = method.getTransitionId()
+      if transition_id in transition_id_set:
+        method.registerTransitionAlways(ptype, wf_id, transition_id)
+      if tdef.once_per_transaction:
+        method.registerTransitionOncePerTransaction(ptype, wf_id, tr_id)
+      else:
+        method.registerTransitionAlways(ptype, wf_id, tr_id)
+
 class Base( CopyContainer,
             PortalContent,
             ActiveObject,



More information about the Erp5-report mailing list