From 58b95cef472c7adadfad413e1e546f83df1298e5 Mon Sep 17 00:00:00 2001
From: Kazuhiko Shiozaki <kazuhiko@nexedi.com>
Date: Thu, 3 Jun 2010 13:34:52 +0000
Subject: [PATCH] return False immediately in Predicate.test() once any check
 fails to reduce further needless calculations.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@35952 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5/Document/Predicate.py | 32 ++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/product/ERP5/Document/Predicate.py b/product/ERP5/Document/Predicate.py
index b90b9a9312..5965070b73 100644
--- a/product/ERP5/Document/Predicate.py
+++ b/product/ERP5/Document/Predicate.py
@@ -107,24 +107,30 @@ class Predicate(XMLObject):
 #        (self.getRelativeUrl(), context.getRelativeUrl()))
     for property, value in self._identity_criterion.iteritems():
       if isinstance(value, (list, tuple)):
-        result = result and (context.getProperty(property) in value)
+        result = context.getProperty(property) in value
       else:
-        result = result and (context.getProperty(property) == value)
+        result = context.getProperty(property) == value
 #      LOG('predicate test', 0,
 #          '%s after prop %s : %s == %s' % \
 #          (result, property, context.getProperty(property), value))
+      if not result:
+        return result
     for property, (min, max) in self._range_criterion.iteritems():
       value = context.getProperty(property)
       if min is not None:
-        result = result and (value >= min)
+        result = value >= min
 #        LOG('predicate test', 0,
 #            '%s after prop %s : %s >= %s' % \
 #            (result, property, value, min))
+        if not result:
+          return result
       if max is not None:
-        result = result and (value < max)
+        result = value < max
 #        LOG('predicate test', 0,
 #            '%s after prop %s : %s < %s' % \
 #            (result, property, value, max))
+        if not result:
+          return result
     multimembership_criterion_base_category_list = \
         self.getMultimembershipCriterionBaseCategoryList()
     membership_criterion_base_category_list = \
@@ -169,6 +175,8 @@ class Predicate(XMLObject):
           tested_base_category[bc] = tested_base_category[bc] or \
                                      context.isMemberOf(c,
                                          strict_membership=strict_membership)
+        if tested_base_category.get(bc, 1) == 0:
+          break
     finally:
       if not enabled:
         disableReadOnlyTransactionCache(self)
@@ -176,17 +184,19 @@ class Predicate(XMLObject):
 #        LOG('predicate test', 0,
 #            '%s after single membership to %s' % \
 #            (tested_base_category[bc], c))
-    result = result and (0 not in tested_base_category.values())
+    result = 0 not in tested_base_category.values()
 #    LOG('predicate test', 0,
 #        '%s after category %s ' % (result, tested_base_category.items()))
+    if not result:
+      return result
     # Test method calls
     test_method_id_list = self.getTestMethodIdList()
     if test_method_id_list is not None :
       for test_method_id in test_method_id_list :
-        if (test_method_id is not None) and result:
+        if test_method_id is not None:
           method = getattr(context,test_method_id)
           try:
-            result = result and method(self)
+            result = method(self)
           except TypeError:
             if method.func_code.co_argcount != isinstance(method, MethodType):
               raise
@@ -194,9 +204,11 @@ class Predicate(XMLObject):
             warn('Predicate %s uses an old-style method (%s) that does not'
                  ' take the predicate as argument' % (
                self.getRelativeUrl(), method.__name__), DeprecationWarning)
-            result = result and method()
-#        LOG('predicate test', 0,
-#            '%s after method %s ' % (result, test_method_id))
+            result = method()
+#          LOG('predicate test', 0,
+#              '%s after method %s ' % (result, test_method_id))
+          if not result:
+            return result
     return result
 
   @UnrestrictedMethod
-- 
2.30.9