From d7f305c923f6adf7497a2bd3dd389aeefb89e757 Mon Sep 17 00:00:00 2001 From: Vo Minh Thu Date: Wed, 8 Feb 2012 16:19:42 +0100 Subject: [PATCH] [IMP] ir_ui_menu: no more shared cache in menu visibility computation. 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 | 112 +++++++++++---------------- 1 file changed, 44 insertions(+), 68 deletions(-) diff --git a/openerp/addons/base/ir/ir_ui_menu.py b/openerp/addons/base/ir/ir_ui_menu.py index db5afcb7585..8c044fa1ad5 100644 --- a/openerp/addons/base/ir/ir_ui_menu.py +++ b/openerp/addons/base/ir/ir_ui_menu.py @@ -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)