summaryrefslogtreecommitdiff
path: root/odoo/api.py
diff options
context:
space:
mode:
authorDenis Ledoux <dle@odoo.com>2018-12-20 12:26:10 +0000
committerRaphael Collet <rco@odoo.com>2019-01-03 12:39:04 +0000
commitf70877b040c7aee630839b9df86ac57ff3217681 (patch)
treeceb8162f46bafe0d8bc74c1cfb97ac9318f042b4 /odoo/api.py
parentcdc01c50b3691ac9e5d550afeb9085ff7476daed (diff)
[IMP] api: gain some memory by not creating the cache_key tuple multiple times
Diffstat (limited to 'odoo/api.py')
-rw-r--r--odoo/api.py45
1 files changed, 24 insertions, 21 deletions
diff --git a/odoo/api.py b/odoo/api.py
index 75d04ad21c3..36e75608e72 100644
--- a/odoo/api.py
+++ b/odoo/api.py
@@ -801,6 +801,7 @@ class Environment(Mapping):
self.cr, self.uid, self.context = self.args = (cr, uid, frozendict(context))
self.registry = Registry(cr.dbname)
self.cache = envs.cache
+ self._cache_key = (cr, uid)
self._protected = StackMap() # {field: ids, ...}
self.dirty = defaultdict(set) # {record: set(field_name), ...}
self.all = envs
@@ -995,6 +996,12 @@ class Environment(Mapping):
finally:
self.all.recompute = tmp
+ def cache_key(self, field):
+ """ Return the key to store the value of ``field`` in cache, the full
+ cache key being ``(field, record.id, key)``.
+ """
+ return self if field.context_dependent else self._cache_key
+
class Environments(object):
""" A common object for all environments in a request. """
@@ -1022,12 +1029,12 @@ class Cache(object):
def contains(self, record, field):
""" Return whether ``record`` has a value for ``field``. """
- key = field.cache_key(record)
+ key = record.env.cache_key(field)
return key in self._data[field].get(record.id, ())
def get(self, record, field):
""" Return the value of ``field`` for ``record``. """
- key = field.cache_key(record)
+ key = record.env.cache_key(field)
try:
value = self._data[field][record.id][key]
except KeyError:
@@ -1037,35 +1044,35 @@ class Cache(object):
def set(self, record, field, value):
""" Set the value of ``field`` for ``record``. """
- key = field.cache_key(record)
+ key = record.env.cache_key(field)
self._data[field][record.id][key] = value
def remove(self, record, field):
""" Remove the value of ``field`` for ``record``. """
- key = field.cache_key(record)
+ key = record.env.cache_key(field)
del self._data[field][record.id][key]
def contains_value(self, record, field):
""" Return whether ``record`` has a regular value for ``field``. """
- key = field.cache_key(record)
+ key = record.env.cache_key(field)
value = self._data[field][record.id].get(key, SpecialValue(None))
return not isinstance(value, SpecialValue)
def get_value(self, record, field, default=None):
""" Return the regular value of ``field`` for ``record``. """
- key = field.cache_key(record)
+ key = record.env.cache_key(field)
value = self._data[field][record.id].get(key, SpecialValue(None))
return default if isinstance(value, SpecialValue) else value
def get_special(self, record, field, default=None):
""" Return the special value of ``field`` for ``record``. """
- key = field.cache_key(record)
+ key = record.env.cache_key(field)
value = self._data[field][record.id].get(key)
return value.get if isinstance(value, SpecialValue) else default
def set_special(self, record, field, getter):
""" Set the value of ``field`` for ``record`` to return ``getter()``. """
- key = field.cache_key(record)
+ key = record.env.cache_key(field)
self._data[field][record.id][key] = SpecialValue(getter)
def set_failed(self, records, fields, exception):
@@ -1079,14 +1086,13 @@ class Cache(object):
def get_fields(self, record):
""" Return the fields with a value for ``record``. """
for name, field in record._fields.items():
- key = field.cache_key(record)
+ key = record.env.cache_key(field)
if name != 'id' and key in self._data[field].get(record.id, ()):
yield field
def get_records(self, model, field):
""" Return the records of ``model`` that have a value for ``field``. """
- key = field.cache_key(model)
- # optimization: do not field.cache_key(record) for each record in cache
+ key = model.env.cache_key(field)
ids = [
record_id
for record_id, field_record_cache in self._data[field].items()
@@ -1096,7 +1102,7 @@ class Cache(object):
def get_missing_ids(self, records, field):
""" Return the ids of ``records`` that have no value for ``field``. """
- key = field.cache_key(records)
+ key = records.env.cache_key(field)
field_cache = self._data[field]
for record_id in records._ids:
if key not in field_cache.get(record_id, ()):
@@ -1104,11 +1110,10 @@ class Cache(object):
def copy(self, records, env):
""" Copy the cache of ``records`` to ``env``. """
- src = records
- dst = records.with_env(env)
+ src, dst = records.env, env
for field, field_cache in self._data.items():
- src_key = field.cache_key(src)
- dst_key = field.cache_key(dst)
+ src_key = src.cache_key(field)
+ dst_key = dst.cache_key(field)
for record_cache in field_cache.values():
if src_key in record_cache and not isinstance(record_cache[src_key], SpecialValue):
# But not if it's a SpecialValue, which often is an access error
@@ -1134,12 +1139,10 @@ class Cache(object):
# make a full copy of the cache, and invalidate it
dump = defaultdict(dict)
for field, field_cache in self._data.items():
- browse = env[field.model_name].browse
+ key = env.cache_key(field)
for record_id, field_record_cache in field_cache.items():
- if record_id:
- key = field.cache_key(browse(record_id))
- if key in field_record_cache:
- dump[field][record_id] = field_record_cache[key]
+ if record_id and key in field_record_cache:
+ dump[field][record_id] = field_record_cache[key]
self.invalidate()