Skip to content
Snippets Groups Projects
Commit e7b8e107 authored by Raphael Collet's avatar Raphael Collet
Browse files

[IMP] fields: update inverse fields lazily for performance

When a relational field is assigned in an onchange, its inverse field is
updated in cache.  Reading the current value of the inverse field may be
costly, for instance in the case of a one2many field with thousands of records
as a value.  Instead, put in cache a SpecialValue that reads and updates the
field; it will be triggered only when it is accessed.
parent 4a102958
No related branches found
No related tags found
No related merge requests found
......@@ -1386,13 +1386,32 @@ class Many2one(_Relational):
record[self.name] = record.env[self.comodel_name].new()
class UnionUpdate(SpecialValue):
""" Placeholder for a value update; when this value is taken from the cache,
it returns ``record[field.name] | value`` and stores it in the cache.
"""
def __init__(self, field, record, value):
self.args = (field, record, value)
def get(self):
field, record, value = self.args
# in order to read the current field's value, remove self from cache
del record._cache[field]
# read the current field's value, and update it in cache only
record._cache[field] = new_value = record[field.name] | value
return new_value
class _RelationalMulti(_Relational):
""" Abstract class for relational fields *2many. """
def _update(self, records, value):
""" Update the cached value of `self` for `records` with `value`. """
for record in records:
record._cache[self] = record[self.name] | value
if self in record._cache:
record._cache[self] = record[self.name] | value
else:
record._cache[self] = UnionUpdate(self, record, value)
def convert_to_cache(self, value, record, validate=True):
if isinstance(value, BaseModel):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment