[IMP] Yaml scripts calls on_changes and fields_view_get by defaults
[odoo/odoo.git] / openerp / tools / cache.py
1 import lru
2
3 class ormcache(object):
4     """ LRU cache decorator for orm methods,
5     """
6
7     def __init__(self, skiparg=2, size=8192, multi=None, timeout=None):
8         self.skiparg = skiparg
9         self.size = size
10         self.method = None
11         self.stat_miss = 0
12         self.stat_hit = 0
13         self.stat_err = 0
14
15     def __call__(self,m):
16         self.method = m
17         def lookup(self2, cr, *args):
18             r = self.lookup(self2, cr, *args)
19             return r
20         lookup.clear_cache = self.clear
21         return lookup
22
23     def stat(self):
24         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) )
25
26     def lru(self, self2):
27         try:
28             ormcache = getattr(self2, '_ormcache')
29         except AttributeError:
30             ormcache = self2._ormcache = {}
31         try:
32             d = ormcache[self.method]
33         except KeyError:
34             d = ormcache[self.method] = lru.LRU(self.size)
35         return d
36
37     def lookup(self, self2, cr, *args):
38         d = self.lru(self2)
39         key = args[self.skiparg-2:]
40         try:
41            r = d[key]
42            self.stat_hit += 1
43            return r
44         except KeyError:
45            self.stat_miss += 1
46            value = d[args] = self.method(self2, cr, *args)
47            return value
48         except TypeError:
49            self.stat_err += 1
50            return self.method(self2, cr, *args)
51
52     def clear(self, self2, *args):
53         """ Remove *args entry from the cache or all keys if *args is undefined 
54         """
55         d = self.lru(self2)
56         if args:
57             try:
58                 key = args[self.skiparg-2:]
59                 del d[key]
60             except KeyError:
61                 pass
62         else:
63             d.clear()
64
65 class ormcache_multi(ormcache):
66     def __init__(self, skiparg=2, size=8192, multi=3):
67         super(ormcache_multi,self).__init__(skiparg,size)
68         self.multi = multi - 2
69
70     def lookup(self, self2, cr, *args):
71         d = self.lru(self2)
72         args = list(args)
73         multi = self.multi
74         ids = args[multi]
75         r = {}
76         miss = []
77
78         for i in ids:
79             args[multi] = i
80             key = tuple(args[self.skiparg-2:])
81             try:
82                r[i] = d[key]
83                self.stat_hit += 1
84             except Exception:
85                self.stat_miss += 1
86                miss.append(i)
87
88         if miss:
89             args[multi] = miss
90             r.update(self.method(self2, cr, *args))
91
92         for i in miss:
93             args[multi] = i
94             key = tuple(args[self.skiparg-2:])
95             d[key] = r[i]
96
97         return r
98
99 class dummy_cache(object):
100     """ Cache decorator replacement to actually do no caching.
101     """
102     def __init__(self, *l, **kw):
103         pass
104     def __call__(self, fn):
105         fn.clear_cache = self.clear
106         return fn
107     def clear(self, *l, **kw):
108         pass
109
110 if __name__ == '__main__':
111
112     class A():
113         @ormcache()
114         def m(self,a,b):
115             print  "A::m(", self,a,b
116             return 1
117
118         @ormcache_multi(multi=3)
119         def n(self,cr,uid,ids):
120             print  "m", self,cr,uid,ids
121             return dict([(i,i) for i in ids])
122
123     a=A()
124     r=a.m(1,2)
125     r=a.m(1,2)
126     r=a.n("cr",1,[1,2,3,4])
127     r=a.n("cr",1,[1,2])
128     print r
129     for i in a._ormcache:
130         print a._ormcache[i].d
131     a.n.clear_cache(a,1,1)
132     r=a.n("cr",1,[1,2])
133     print r
134     r=a.n("cr",1,[1,2])
135
136 # For backward compatibility
137 cache = ormcache