From 1a050dc536bfa15503e8f56fa5ea9c6b76777141 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9rome=20Perrin?= <jerome@nexedi.com>
Date: Mon, 10 May 2010 14:31:04 +0000
Subject: [PATCH] fix the massive speed regression from 35109 by:  - hooking
 _aq_dynamic instead of _getOb (_getOb is called thousands of times)  - making
 portal_types the first type provider, and only looking up a type   
 information in other types providers if not found in portal_types

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@35136 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5/Document/BusinessTemplate.py |  3 ++-
 product/ERP5Type/Tool/TypesTool.py        | 32 +++++++++++++----------
 2 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/product/ERP5/Document/BusinessTemplate.py b/product/ERP5/Document/BusinessTemplate.py
index d7cd8c2a52..01ae3fdfc0 100644
--- a/product/ERP5/Document/BusinessTemplate.py
+++ b/product/ERP5/Document/BusinessTemplate.py
@@ -1786,7 +1786,8 @@ class PortalTypeTemplateItem(ObjectTemplateItem):
     portal = obj.getPortalObject()
     types_tool = portal.portal_types
     type_container_id = obj.getParentId()
-    if type_container_id not in types_tool.type_provider_list:
+    if type_container_id != 'portal_types' and \
+        type_container_id not in types_tool.type_provider_list:
       types_tool.type_provider_list = tuple(types_tool.type_provider_list) + (
           type_container_id,)
 
diff --git a/product/ERP5Type/Tool/TypesTool.py b/product/ERP5Type/Tool/TypesTool.py
index d513d42126..554996754a 100644
--- a/product/ERP5Type/Tool/TypesTool.py
+++ b/product/ERP5Type/Tool/TypesTool.py
@@ -38,8 +38,6 @@ class TypeProvider(BaseTool, CMFCore_TypesTool):
   zope.interface.implements(ITypeProvider)
 
 
-_MARKER = []
-
 class TypesTool(TypeProvider):
   """Provides a configurable registry of portal content types
   """
@@ -51,7 +49,7 @@ class TypesTool(TypeProvider):
   zope.interface.implements(ITypesTool)
 
   # TODO: UI to configure this is missing
-  type_provider_list = ( 'portal_types', )
+  type_provider_list = ( )
 
   security = ClassSecurityInfo()
   security.declareObjectProtected(Permissions.AccessContentsInformation)
@@ -60,28 +58,34 @@ class TypesTool(TypeProvider):
     """List type information from all providers
     """
     listTypeInfo = CMFCore_TypesTool.listTypeInfo
-    type_info_list = []
+    type_info_list = listTypeInfo(self, container=container)
+    portal = self.getPortalObject()
     for provider in self.type_provider_list:
-      provider_value = getattr(self, provider, None)
+      provider_value = portal._getOb(provider, None)
       if provider_value is not None:
         type_info_list.extend(
             listTypeInfo(provider_value, container=container))
     return type_info_list
-
-  def _getOb(self, id, default=_MARKER):
+  
+  def _aq_dynamic(self, id):
     """Get a type information from a provider
     """
-    _getOb = CMFCore_TypesTool._getOb
+    result = BaseTool._aq_dynamic(self, id)
+    if result is not None:
+      return result
+
+    if id in self.type_provider_list:
+      return None
+
+    default = []
     for provider in self.type_provider_list:
       provider_value = getattr(self, provider, None)
       if provider_value is not None:
-        ob = _getOb(provider_value, id, default=default)
+        ob = provider_value._getOb(id, default=default)
         if ob is not default:
           return ob
-    if ob is _MARKER:
-      raise AttributeError, id
-    return ob
-    
+    return None
+
   security.declarePrivate('getActionListFor')
   def getActionListFor(self, ob=None):
     """Return all actions applicable to the object"""
@@ -100,7 +104,7 @@ class TypesTool(TypeProvider):
         portal_type = aq_base(portal_type).getPortalType()
       except AttributeError:
         return None
-    return self._getOb(portal_type, None)
+    return getattr(self, portal_type, None)
 
   security.declareProtected(Permissions.AddPortalContent, 'listDefaultTypeInformation')
   def listDefaultTypeInformation(self):
-- 
2.30.9