[IMP] ir_ui_menu: no more shared cache in menu visibility computation.
authorVo Minh Thu <vmt@openerp.com>
Wed, 8 Feb 2012 15:19:42 +0000 (16:19 +0100)
committerVo Minh Thu <vmt@openerp.com>
Wed, 8 Feb 2012 15:19:42 +0000 (16:19 +0100)
It is slower in the GTK client (0.0050s instead of 0.00009s) to get a menu tree.

bzr revid: vmt@openerp.com-20120208151942-c8dlyleoxmaczbry

openerp/addons/base/ir/ir_ui_menu.py

index db5afcb..8c044fa 100644 (file)
@@ -40,69 +40,57 @@ def one_in(setA, setB):
 class ir_ui_menu(osv.osv):
     _name = 'ir.ui.menu'
 
-    def __init__(self, *args, **kwargs):
-        self.cache_lock = threading.RLock()
-        self.clear_cache()
-        r = super(ir_ui_menu, self).__init__(*args, **kwargs)
-        self.pool.get('ir.model.access').register_cache_clearing_method(self._name, 'clear_cache')
-        return r
-
-    def clear_cache(self):
-        with self.cache_lock:
-            # radical but this doesn't frequently happen
-            self._cache = {}
-
     def _filter_visible_menus(self, cr, uid, ids, context=None):
         """Filters the give menu ids to only keep the menu items that should be
            visible in the menu hierarchy of the current user.
            Uses a cache for speeding up the computation.
         """
-        with self.cache_lock:
-            modelaccess = self.pool.get('ir.model.access')
-            user_groups = set(self.pool.get('res.users').read(cr, 1, uid, ['groups_id'])['groups_id'])
-            result = []
-            for menu in self.browse(cr, uid, ids, context=context):
-                # this key works because user access rights are all based on user's groups (cfr ir_model_access.check)
-                key = (cr.dbname, menu.id, tuple(user_groups))
-                if key in self._cache:
-                    if self._cache[key]:
-                        result.append(menu.id)
-                    #elif not menu.groups_id and not menu.action:
-                    #    result.append(menu.id)
+        _cache = {}
+        modelaccess = self.pool.get('ir.model.access')
+        user_groups = set(self.pool.get('res.users').read(cr, 1, uid, ['groups_id'])['groups_id'])
+        result = []
+        for menu in self.browse(cr, uid, ids, context=context):
+            # this key works because user access rights are all based on user's groups (cfr ir_model_access.check)
+            key = (cr.dbname, menu.id, tuple(user_groups))
+            if key in _cache:
+                if _cache[key]:
+                    result.append(menu.id)
+                #elif not menu.groups_id and not menu.action:
+                #    result.append(menu.id)
+                continue
+
+            _cache[key] = False
+            if menu.groups_id:
+                restrict_to_groups = [g.id for g in menu.groups_id]
+                if not user_groups.intersection(restrict_to_groups):
+                    continue
+                #result.append(menu.id)
+                #_cache[key] = True
+                #continue
+
+            if menu.action:
+                # we check if the user has access to the action of the menu
+                data = menu.action
+                if data:
+                    model_field = { 'ir.actions.act_window':    'res_model',
+                                    'ir.actions.report.xml':    'model',
+                                    'ir.actions.wizard':        'model',
+                                    'ir.actions.server':        'model_id',
+                                  }
+
+                    field = model_field.get(menu.action._name)
+                    if field and data[field]:
+                        if not modelaccess.check(cr, uid, data[field], 'read', False):
+                            continue
+            else:
+                # if there is no action, it's a 'folder' menu
+                if not menu.child_id:
+                    # not displayed if there is no children
                     continue
 
-                self._cache[key] = False
-                if menu.groups_id:
-                    restrict_to_groups = [g.id for g in menu.groups_id]
-                    if not user_groups.intersection(restrict_to_groups):
-                        continue
-                    #result.append(menu.id)
-                    #self._cache[key] = True
-                    #continue
-
-                if menu.action:
-                    # we check if the user has access to the action of the menu
-                    data = menu.action
-                    if data:
-                        model_field = { 'ir.actions.act_window':    'res_model',
-                                        'ir.actions.report.xml':    'model',
-                                        'ir.actions.wizard':        'model',
-                                        'ir.actions.server':        'model_id',
-                                      }
-
-                        field = model_field.get(menu.action._name)
-                        if field and data[field]:
-                            if not modelaccess.check(cr, uid, data[field], 'read', False):
-                                continue
-                else:
-                    # if there is no action, it's a 'folder' menu
-                    if not menu.child_id:
-                        # not displayed if there is no children
-                        continue
-
-                result.append(menu.id)
-                self._cache[key] = True
-            return result
+            result.append(menu.id)
+            _cache[key] = True
+        return result
 
     def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
         if context is None:
@@ -146,18 +134,6 @@ class ir_ui_menu(osv.osv):
             parent_path = ''
         return parent_path + menu.name
 
-    def create(self, *args, **kwargs):
-        self.clear_cache()
-        return super(ir_ui_menu, self).create(*args, **kwargs)
-
-    def write(self, *args, **kwargs):
-        self.clear_cache()
-        return super(ir_ui_menu, self).write(*args, **kwargs)
-
-    def unlink(self, *args, **kwargs):
-        self.clear_cache()
-        return super(ir_ui_menu, self).unlink(*args, **kwargs)
-
     def copy(self, cr, uid, id, default=None, context=None):
         ir_values_obj = self.pool.get('ir.values')
         res = super(ir_ui_menu, self).copy(cr, uid, id, context=context)