[IMP] core: group all field_inverses dicts on registry
This makes the union of many dicts into a single dict. On a registry with 296 modules, this saves 300 kilobytes of memory, which is about 3% of the registry's memory footprint.
This commit is contained in:
@@ -756,7 +756,7 @@ class IrModelFields(models.Model):
|
||||
for dep in model._dependent_fields(field):
|
||||
if dep.manual:
|
||||
failed_dependencies.append((field, dep))
|
||||
for inverse in model._field_inverses.get(field, ()):
|
||||
for inverse in model.pool.field_inverses[field]:
|
||||
if inverse.manual and inverse.type == 'one2many':
|
||||
failed_dependencies.append((field, inverse))
|
||||
|
||||
|
||||
+15
-15
@@ -721,7 +721,7 @@ class Field(MetaField('DummyField', (object,), {})):
|
||||
yield tuple(field_seq)
|
||||
|
||||
if field.type in ('one2many', 'many2many'):
|
||||
for inv_field in Model._field_inverses[field]:
|
||||
for inv_field in Model.pool.field_inverses[field]:
|
||||
yield tuple(field_seq) + (inv_field,)
|
||||
|
||||
model_name = field.comodel_name
|
||||
@@ -2846,7 +2846,7 @@ class Many2one(_Relational):
|
||||
# align(id) returns a NewId if records are new, a real id otherwise
|
||||
align = (lambda id_: id_) if all(record_ids) else (lambda id_: id_ and NewId(id_))
|
||||
|
||||
for invf in records._field_inverses[self]:
|
||||
for invf in records.pool.field_inverses[self]:
|
||||
corecords = records.env[self.comodel_name].browse(
|
||||
align(id_) for id_ in cache.get_values(records, self)
|
||||
)
|
||||
@@ -2862,7 +2862,7 @@ class Many2one(_Relational):
|
||||
return
|
||||
cache = records.env.cache
|
||||
corecord = self.convert_to_record(value, records)
|
||||
for invf in records._field_inverses[self]:
|
||||
for invf in records.pool.field_inverses[self]:
|
||||
valid_records = records.filtered_domain(invf.get_domain_list(corecord))
|
||||
if not valid_records:
|
||||
continue
|
||||
@@ -2905,7 +2905,7 @@ class Many2oneReference(Integer):
|
||||
record_ids = set(records._ids)
|
||||
model_ids = self._record_ids_per_res_model(records)
|
||||
|
||||
for invf in records._field_inverses[self]:
|
||||
for invf in records.pool.field_inverses[self]:
|
||||
records = records.browse(model_ids[invf.model_name])
|
||||
if not records:
|
||||
continue
|
||||
@@ -2925,7 +2925,7 @@ class Many2oneReference(Integer):
|
||||
cache = records.env.cache
|
||||
model_ids = self._record_ids_per_res_model(records)
|
||||
|
||||
for invf in records._field_inverses[self]:
|
||||
for invf in records.pool.field_inverses[self]:
|
||||
records = records.browse(model_ids[invf.model_name])
|
||||
if not records:
|
||||
continue
|
||||
@@ -3198,7 +3198,7 @@ class _RelationalMulti(_Relational):
|
||||
return val._origin if isinstance(val, BaseModel) else val
|
||||
|
||||
# make result with new and existing records
|
||||
inv_names = {field.name for field in record._field_inverses[self]}
|
||||
inv_names = {field.name for field in record.pool.field_inverses[self]}
|
||||
result = [Command.set([])]
|
||||
for record in value:
|
||||
origin = record._origin
|
||||
@@ -3332,8 +3332,8 @@ class One2many(_RelationalMulti):
|
||||
if isinstance(invf, (Many2one, Many2oneReference)):
|
||||
# setting one2many fields only invalidates many2one inverses;
|
||||
# integer inverses (res_model/res_id pairs) are not supported
|
||||
model._field_inverses.add(self, invf)
|
||||
comodel._field_inverses.add(invf, self)
|
||||
model.pool.field_inverses.add(self, invf)
|
||||
comodel.pool.field_inverses.add(invf, self)
|
||||
|
||||
_description_relation_field = property(attrgetter('inverse_name'))
|
||||
|
||||
@@ -3679,10 +3679,10 @@ class Many2many(_RelationalMulti):
|
||||
raise TypeError(msg % (self, field))
|
||||
fields.append(self)
|
||||
|
||||
# retrieve inverse fields, and link them in _field_inverses
|
||||
# retrieve inverse fields, and link them in field_inverses
|
||||
for field in m2m[(self.relation, self.column2, self.column1)]:
|
||||
model._field_inverses.add(self, field)
|
||||
model.env[field.model_name]._field_inverses.add(field, self)
|
||||
model.pool.field_inverses.add(self, field)
|
||||
model.pool.field_inverses.add(field, self)
|
||||
|
||||
def update_db(self, model, columns):
|
||||
cr = model._cr
|
||||
@@ -3854,7 +3854,7 @@ class Many2many(_RelationalMulti):
|
||||
y_to_xs = defaultdict(set)
|
||||
for x, y in pairs:
|
||||
y_to_xs[y].add(x)
|
||||
for invf in records._field_inverses[self]:
|
||||
for invf in records.pool.field_inverses[self]:
|
||||
domain = invf.get_domain_list(comodel)
|
||||
valid_ids = set(records.filtered_domain(domain)._ids)
|
||||
if not valid_ids:
|
||||
@@ -3892,7 +3892,7 @@ class Many2many(_RelationalMulti):
|
||||
cr.execute(query, params)
|
||||
|
||||
# update the cache of inverse fields
|
||||
for invf in records._field_inverses[self]:
|
||||
for invf in records.pool.field_inverses[self]:
|
||||
for y, xs in y_to_xs.items():
|
||||
corecord = comodel.browse(y)
|
||||
try:
|
||||
@@ -3968,7 +3968,7 @@ class Many2many(_RelationalMulti):
|
||||
y_to_xs = defaultdict(set)
|
||||
for x, y in pairs:
|
||||
y_to_xs[y].add(x)
|
||||
for invf in records._field_inverses[self]:
|
||||
for invf in records.pool.field_inverses[self]:
|
||||
domain = invf.get_domain_list(comodel)
|
||||
valid_ids = set(records.filtered_domain(domain)._ids)
|
||||
if not valid_ids:
|
||||
@@ -3989,7 +3989,7 @@ class Many2many(_RelationalMulti):
|
||||
y_to_xs = defaultdict(set)
|
||||
for x, y in pairs:
|
||||
y_to_xs[y].add(x)
|
||||
for invf in records._field_inverses[self]:
|
||||
for invf in records.pool.field_inverses[self]:
|
||||
for y, xs in y_to_xs.items():
|
||||
corecord = comodel.browse([y])
|
||||
try:
|
||||
|
||||
+5
-7
@@ -2898,8 +2898,6 @@ class BaseModel(metaclass=MetaModel):
|
||||
self._add_inherited_fields()
|
||||
|
||||
# 4. initialize more field metadata
|
||||
cls._field_inverses = Collector() # inverse fields for related fields
|
||||
|
||||
cls._setup_done = True
|
||||
|
||||
for field in cls._fields.values():
|
||||
@@ -3690,7 +3688,7 @@ Fields:
|
||||
# DLE P150: `test_cancel_propagation`, `test_manufacturing_3_steps`, `test_manufacturing_flow`
|
||||
# TODO: check whether still necessary
|
||||
records_to_inverse[field] = self.filtered('id')
|
||||
if field.relational or self._field_inverses[field]:
|
||||
if field.relational or self.pool.field_inverses[field]:
|
||||
relational_names.append(fname)
|
||||
if field.inverse or (field.compute and not field.readonly):
|
||||
if field.store or field.type not in ('one2many', 'many2many'):
|
||||
@@ -4079,7 +4077,7 @@ Fields:
|
||||
else:
|
||||
cache_value = field.convert_to_cache(value, record)
|
||||
self.env.cache.set(record, field, cache_value)
|
||||
if field.type in ('many2one', 'many2one_reference') and record._field_inverses[field]:
|
||||
if field.type in ('many2one', 'many2one_reference') and self.pool.field_inverses[field]:
|
||||
inverses_update[(field, cache_value)].append(record.id)
|
||||
|
||||
for (field, value), record_ids in inverses_update.items():
|
||||
@@ -5230,7 +5228,7 @@ Fields:
|
||||
inv_recs = self[field.name].filtered(lambda r: not r.id)
|
||||
if not inv_recs:
|
||||
continue
|
||||
for invf in self._field_inverses[field]:
|
||||
for invf in self.pool.field_inverses[field]:
|
||||
# DLE P98: `test_40_new_fields`
|
||||
# /home/dle/src/odoo/master-nochange-fp/odoo/addons/test_new_api/tests/test_new_fields.py
|
||||
# Be careful to not break `test_onchange_taxes_1`, `test_onchange_taxes_2`, `test_onchange_taxes_3`
|
||||
@@ -5813,7 +5811,7 @@ Fields:
|
||||
|
||||
# invalidate fields and inverse fields, too
|
||||
spec = [(f, ids) for f in fields] + \
|
||||
[(invf, None) for f in fields for invf in self._field_inverses[f]]
|
||||
[(invf, None) for f in fields for invf in self.pool.field_inverses[f]]
|
||||
self.env.cache.invalidate(spec)
|
||||
|
||||
def modified(self, fnames, create=False, before=False):
|
||||
@@ -5914,7 +5912,7 @@ Fields:
|
||||
else:
|
||||
# val is another tree of dependencies
|
||||
model = self.env[key.model_name]
|
||||
for invf in model._field_inverses[key]:
|
||||
for invf in model.pool.field_inverses[key]:
|
||||
# use an inverse of field without domain
|
||||
if not (invf.type in ('one2many', 'many2many') and invf.domain):
|
||||
if invf.type == 'many2one_reference':
|
||||
|
||||
@@ -135,6 +135,7 @@ class Registry(Mapping):
|
||||
# field dependencies
|
||||
self.field_depends = Collector()
|
||||
self.field_depends_context = Collector()
|
||||
self.field_inverses = Collector()
|
||||
|
||||
# Inter-process signaling:
|
||||
# The `base_registry_signaling` sequence indicates the whole registry
|
||||
@@ -271,20 +272,23 @@ class Registry(Mapping):
|
||||
for model in models:
|
||||
model._prepare_setup()
|
||||
|
||||
# do the actual setup from a clean state
|
||||
self._m2m = defaultdict(list)
|
||||
self.field_depends.clear()
|
||||
self.field_depends_context.clear()
|
||||
self.field_inverses.clear()
|
||||
|
||||
# do the actual setup
|
||||
for model in models:
|
||||
model._setup_base()
|
||||
|
||||
self._m2m = defaultdict(list)
|
||||
for model in models:
|
||||
model._setup_fields()
|
||||
del self._m2m
|
||||
|
||||
for model in models:
|
||||
model._setup_complete()
|
||||
|
||||
# determine field_depends and field_depends_context
|
||||
self.field_depends.clear()
|
||||
self.field_depends_context.clear()
|
||||
for model in models:
|
||||
for field in model._fields.values():
|
||||
depends, depends_context = field.get_depends(model)
|
||||
|
||||
Reference in New Issue
Block a user