[IMP] Performance improvement: improved cache with context, better get_object
authorFabien Pinckaers <fp@tinyerp.com>
Sat, 30 Nov 2013 15:47:23 +0000 (16:47 +0100)
committerFabien Pinckaers <fp@tinyerp.com>
Sat, 30 Nov 2013 15:47:23 +0000 (16:47 +0100)
bzr revid: fp@tinyerp.com-20131130154723-05r90b2yhwwovpx4

openerp/addons/base/ir/ir_model.py
openerp/addons/base/ir/ir_ui_view.py
openerp/addons/base/res/res_users.py
openerp/tools/cache.py

index ae4643a..ba0b67a 100644 (file)
@@ -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:
index bf21f4e..67cd853 100644 (file)
@@ -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_)
index 160ac6a..f817d94 100644 (file)
@@ -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):
index 268ef0f..a23641a 100644 (file)
@@ -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