From 4a3529afdf9c0ad56abaae5ce14081fc185537b8 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Sat, 30 Nov 2013 16:47:23 +0100 Subject: [PATCH] [IMP] Performance improvement: improved cache with context, better get_object bzr revid: fp@tinyerp.com-20131130154723-05r90b2yhwwovpx4 --- openerp/addons/base/ir/ir_model.py | 5 +---- openerp/addons/base/ir/ir_ui_view.py | 4 ++++ openerp/addons/base/res/res_users.py | 8 +++----- openerp/tools/cache.py | 36 ++++++++++++++++++++++++++++++---- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index ae4643a..ba0b67a 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -887,10 +887,7 @@ class ir_model_data(osv.osv): def get_object(self, cr, uid, module, xml_id, context=None): """Returns a browsable record for the given module name and xml_id or raise ValueError if not found""" res_model, res_id = self.get_object_reference(cr, uid, module, xml_id) - result = self.pool[res_model].browse(cr, uid, res_id, context=context) - if not result.exists(): - raise ValueError('No record found for unique ID %s.%s. It may have been deleted.' % (module, xml_id)) - return result + return self.pool[res_model].browse(cr, uid, res_id, context=context) def _update_dummy(self,cr, uid, model, module, xml_id=False, store=True): if not xml_id: diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py index bf21f4e..67cd853 100644 --- a/openerp/addons/base/ir/ir_ui_view.py +++ b/openerp/addons/base/ir/ir_ui_view.py @@ -152,6 +152,8 @@ class view(osv.osv): if not values.get('name'): values['name'] = "%s %s" % (values['model'], values['type']) + + self.read_template.clear_cache(self) return super(view, self).create(cr, uid, values, context) def write(self, cr, uid, ids, vals, context=None): @@ -164,6 +166,7 @@ class view(osv.osv): if custom_view_ids: self.pool.get('ir.ui.view.custom').unlink(cr, uid, custom_view_ids) + self.read_template.clear_cache(self) return super(view, self).write(cr, uid, ids, vals, context) # default view selection @@ -668,6 +671,7 @@ class view(osv.osv): # view used as templates + @tools.ormcache_context(accepted_keys=('lang','inherit_branding')) def read_template(self, cr, uid, id_, context=None): try: id_ = int(id_) diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index 160ac6a..f817d94 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -707,11 +707,9 @@ class groups_view(osv.osv): return True def get_user_groups_view(self, cr, uid, context=None): - try: - view = self.pool['ir.model.data'].get_object(cr, SUPERUSER_ID, 'base', 'user_groups_view', context) - assert view and view._table_name == 'ir.ui.view' - except Exception: - view = False + view = self.pool['ir.model.data'].get_object(cr, SUPERUSER_ID, 'base', 'user_groups_view', context) + if not view.exists() or not (view._table_name == 'ir.ui.view'): + view == False return view def get_application_groups(self, cr, uid, domain=None, context=None): diff --git a/openerp/tools/cache.py b/openerp/tools/cache.py index 268ef0f..a23641a 100644 --- a/openerp/tools/cache.py +++ b/openerp/tools/cache.py @@ -17,8 +17,8 @@ class ormcache(object): def __call__(self,m): self.method = m - def lookup(self2, cr, *args): - r = self.lookup(self2, cr, *args) + def lookup(self2, cr, *args, **argv): + r = self.lookup(self2, cr, *args, **argv) return r lookup.clear_cache = self.clear return lookup @@ -37,7 +37,7 @@ class ormcache(object): d = ormcache[self.method] = lru.LRU(self.size) return d - def lookup(self, self2, cr, *args): + def lookup(self, self2, cr, *args, **argv): d = self.lru(self2) key = args[self.skiparg-2:] try: @@ -63,12 +63,39 @@ class ormcache(object): d.clear() self2.pool._any_cache_cleared = True +class ormcache_context(ormcache): + def __init__(self, skiparg=2, size=8192, accepted_keys=()): + super(ormcache_context,self).__init__(skiparg,size) + self.accepted_keys = accepted_keys + + def lookup(self, self2, cr, *args, **argv): + d = self.lru(self2) + + context = argv.get('context', {}) + ckey = filter(lambda x: x[0] in self.accepted_keys, context.items()) + ckey.sort() + + d = self.lru(self2) + key = args[self.skiparg-2:]+tuple(ckey) + try: + r = d[key] + self.stat_hit += 1 + return r + except KeyError: + self.stat_miss += 1 + value = d[key] = self.method(self2, cr, *args, **argv) + return value + except TypeError: + self.stat_err += 1 + return self.method(self2, cr, *args, **argv) + + class ormcache_multi(ormcache): def __init__(self, skiparg=2, size=8192, multi=3): super(ormcache_multi,self).__init__(skiparg,size) self.multi = multi - 2 - def lookup(self, self2, cr, *args): + def lookup(self, self2, cr, *args, **argv): d = self.lru(self2) args = list(args) multi = self.multi @@ -129,6 +156,7 @@ if __name__ == '__main__': print r for i in a._ormcache: print a._ormcache[i].d + a.m.clear_cache() a.n.clear_cache(a,1,1) r=a.n("cr",1,[1,2]) print r -- 1.7.10.4