[IMP] simplified cache implementation (and stored on the osv), does not support contexts.
authorVo Minh Thu <vmt@openerp.com>
Tue, 30 Aug 2011 12:15:41 +0000 (14:15 +0200)
committerVo Minh Thu <vmt@openerp.com>
Tue, 30 Aug 2011 12:15:41 +0000 (14:15 +0200)
bzr revid: vmt@openerp.com-20110830121541-abov2wezdn6kl2dc

1  2 
openerp/addons/base/res/res_company.py
openerp/modules/registry.py
openerp/osv/orm.py
openerp/tools/cache.py

Simple merge
Simple merge
index 0000000,090651c..33a821c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,134 +1,137 @@@
+ import lru
+ class ormcache(object):
+     """ LRU cache decorator for orm methods,
+     """
+     def __init__(self, skiparg=2, size=8192, multi=None, timeout=None):
+         self.skiparg = skiparg
+         self.size = size
+         self.method = None
+         self.stat_miss = 0
+         self.stat_hit = 0
+         self.stat_err = 0
+     def __call__(self,m):
+         self.method = m
+         def lookup(self2, cr, *args):
+             r = self.lookup(self2, cr, *args)
+             return r
+         lookup.clear_cache = self.clear
+         return lookup
+     def stat(self):
+         return "lookup-stats hit=%s miss=%s err=%s ratio=%.1f" % (self.stat_hit,self.stat_miss,self.stat_err, (100*float(self.stat_hit))/(self.stat_miss+self.stat_hit) )
+     def lru(self, self2):
+         try:
+             ormcache = getattr(self2, '_ormcache')
+         except AttributeError:
+             ormcache = self2._ormcache = {}
+         try:
+             d = ormcache[self.method]
+         except KeyError:
+             d = ormcache[self.method] = lru.LRU(self.size)
+         return d
+     def lookup(self, self2, cr, *args):
+         d = self.lru(self2)
+         key = args[self.skiparg-2:]
+         try:
+            r = d[key]
+            self.stat_hit += 1
+            return r
+         except KeyError:
+            self.stat_miss += 1
+            value = d[args] = self.method(self2, cr, *args)
+            return value
+         except TypeError:
+            self.stat_err += 1
+            return self.method(self2, cr, *args)
+     def clear(self, self2, *args):
+         """ Remove *args entry from the cache or all keys if *args is undefined 
+         """
+         d = self.lru(self2)
+         if args:
+             try:
+                 key = args[self.skiparg-2:]
+                 del d[key]
+             except KeyError:
+                 pass
+         else:
+             d.clear()
+ 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):
+         d = self.lru(self2)
+         args = list(args)
+         multi = self.multi
+         ids = args[multi]
+         r = {}
+         miss = []
+         for i in ids:
+             args[multi] = i
+             key = tuple(args[self.skiparg-2:])
+             try:
+                r[i] = d[key]
+                self.stat_hit += 1
+             except Exception:
+                self.stat_miss += 1
+                miss.append(i)
+         if miss:
+             args[multi] = miss
+             r.update(self.method(self2, cr, *args))
+         for i in miss:
+             args[multi] = i
+             key = tuple(args[self.skiparg-2:])
+             d[key] = r[i]
+         return r
+ class dummy_cache(object):
+     """ Cache decorator replacement to actually do no caching.
+     """
+     def __init__(self, *l, **kw):
+         pass
+     def __call__(self, fn):
+         fn.clear_cache = self.clear
+         return fn
+     def clear(self, *l, **kw):
+         pass
+ if __name__ == '__main__':
+     class A():
+         @ormcache()
+         def m(self,a,b):
+             print  "A::m(", self,a,b
+             return 1
+         @ormcache_multi(multi=3)
+         def n(self,cr,uid,ids):
+             print  "m", self,cr,uid,ids
+             return dict([(i,i) for i in ids])
+     a=A()
+     r=a.m(1,2)
+     r=a.m(1,2)
+     r=a.n("cr",1,[1,2,3,4])
+     r=a.n("cr",1,[1,2])
+     print r
+     for i in a._ormcache:
+         print a._ormcache[i].d
+     a.n.clear_cache(a,1,1)
+     r=a.n("cr",1,[1,2])
+     print r
+     r=a.n("cr",1,[1,2])
++
++# For backward compatibility
++cache = ormcache