Problem/Motivation
On a site with many entity references ToneExtraFields::getExtraFieldInfo()
does too much work in order to figure out whether to yield an extra field definition for a given combination of entity type and bundle. This is due to the fact that ToneExtraFields::containsToneReference()
is executed hundreds of times due to its recursive nature.
Steps to reproduce
Try to use the tone module on a site with many entity references. CRUD of fields leads to CPU spikes during tens of seconds.
Proposed resolution
Rewrite ToneExtraFields::getExtraFieldInfo()
in a smarter way.
The approach in 3341063-toneextrafieldsgetextrafieldinfo-is-inefficient
branch replaces the recursive algorithm by a reverse dependency graph based on all entity reference fields. Nodes are pairs of entity_type_id:bundle_name
while edges represent target entity -> source entity relationships while edge label is used to store the field name on the source.
Departing from tone bundles, the graph is walked in a breadth-first search manner in order to discover entity bundles which are embedding tone entities either directly or indirectly (by referencing entity bundles which are referencing tone entities directly). Per default, only two iterations are performed (this setting is unchanged in comparison to the original approach).
This algorithm performs much better on big sites than the original one. XHProf was used to record the runtime of ToneExtraFields::getExtraFieldInfo()
while creating a new content block type. The numbers were captured on a site with roughly 170 entity reference field instances:
Inclusive Wall time of ToneExtraFields::getExtraFieldInfo()
in microseconds:
Remaining tasks
User interface changes
API changes
Data model changes