summaryrefslogtreecommitdiff
path: root/odoo
diff options
context:
space:
mode:
authorDenis Ledoux <dle@odoo.com>2019-08-22 11:29:38 +0000
committerRaphael Collet <rco@odoo.com>2019-09-11 07:55:17 +0000
commit3d1c924cffd839c076d9bacaf8bab9d995aee01e (patch)
treef9b0929cfd8f14ddc7f4056d530a95473f4b0f8c /odoo
parent0e028de72ea0f49586790b580774bac203a8ed96 (diff)
[FIX] fields.py: improve computation time of records having a different value in cache
Instead of using a filtered with `cache.get`, use a dedicated method in the Cache class to get the records having a different value in cache then asked. This is mainly to avoid the creation of intermediate `browse` of 1 record, when doing `for rec in self` in `filtered`. Creating browses is costly, and avoiding it leads to performance gains. The dedicated method `get_records_different_from` loops on the record ids, instead of on browse records
Diffstat (limited to 'odoo')
-rw-r--r--odoo/api.py18
-rw-r--r--odoo/fields.py12
2 files changed, 22 insertions, 8 deletions
diff --git a/odoo/api.py b/odoo/api.py
index 1bba63b4400..65ae87f2b92 100644
--- a/odoo/api.py
+++ b/odoo/api.py
@@ -766,6 +766,24 @@ class Cache(object):
except KeyError:
pass
+ def get_records_different_from(self, records, field, value):
+ """ Return the subset of ``records`` that has not ``value`` for ``field``. """
+ field_cache = self._data[field]
+ key = self._get_context_key(records.env, field) if field.depends_context else None
+ ids = []
+ for record_id in records._ids:
+ try:
+ if key:
+ val = field_cache[record_id][key]
+ else:
+ val = field_cache[record_id]
+ except KeyError:
+ ids.append(record_id)
+ else:
+ if val != value:
+ ids.append(record_id)
+ return records.browse(ids)
+
def get_fields(self, record):
""" Return the fields with a value for ``record``. """
for name, field in record._fields.items():
diff --git a/odoo/fields.py b/odoo/fields.py
index 9e285517674..e82bc06ee98 100644
--- a/odoo/fields.py
+++ b/odoo/fields.py
@@ -967,9 +967,8 @@ class Field(MetaField('DummyField', (object,), {})):
# update the cache, and discard the records that are not modified
cache = records.env.cache
- NOTHING = object()
cache_value = self.convert_to_cache(value, records)
- records = records.filtered(lambda record: cache.get(record, self, NOTHING) != cache_value)
+ records = cache.get_records_different_from(records, self, cache_value)
if not records:
return records
cache.update(records, self, [cache_value] * len(records))
@@ -1386,9 +1385,8 @@ class _String(Field):
# update the cache, and discard the records that are not modified
cache = records.env.cache
- NOTHING = object()
cache_value = self.convert_to_cache(value, records)
- records = records.filtered(lambda record: cache.get(record, self, NOTHING) != cache_value)
+ records = cache.get_records_different_from(records, self, cache_value)
if not records:
return records
cache.update(records, self, [cache_value] * len(records))
@@ -1912,9 +1910,8 @@ class Binary(Field):
# update the cache, and discard the records that are not modified
cache = records.env.cache
- NOTHING = object()
cache_value = self.convert_to_cache(value, records)
- records = records.filtered(lambda record: cache.get(record, self, NOTHING) != cache_value)
+ records = cache.get_records_different_from(records, self, cache_value)
if not records:
return records
cache.update(records, self, [cache_value] * len(records))
@@ -2396,9 +2393,8 @@ class Many2one(_Relational):
# discard the records that are not modified
cache = records.env.cache
- NOTHING = object()
cache_value = self.convert_to_cache(value, records)
- records = records.filtered(lambda record: cache.get(record, self, NOTHING) != cache_value)
+ records = cache.get_records_different_from(records, self, cache_value)
if not records:
return records