only in patch2: unchanged: --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php @@ -82,6 +82,17 @@ class ConfigEntityStorage extends EntityStorageBase implements ConfigEntityStora protected $languageManager; /** + * Static cache of entities, keyed first by entity ID, then by an extra key. + * + * The second layer cache key is to maintain separate caches for different + * states of config overrides. + * + * @var array + * @see \Drupal\Core\Config\ConfigFactoryInterface::getCacheKey(). + */ + protected $entities = array(); + + /** * Constructs a ConfigEntityStorage object. * * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type @@ -255,6 +266,46 @@ protected function has($id, EntityInterface $entity) { } /** + * Gets entities from the static cache. + * + * @param array $ids + * If not empty, return entities that match these IDs. + * + * @return \Drupal\Core\Entity\EntityInterface[] + * Array of entities from the entity cache. + */ + protected function getFromStaticCache(array $ids) { + $entities = array(); + // Load any available entities from the internal cache. + if ($this->entityType->isStaticallyCacheable() && !empty($this->entities)) { + foreach ($ids as $id) { + if (!empty($this->entities[$id])) { + $key = $this->configFactory->getCacheKey($this->getConfigPrefix() . $id); + if (isset($this->entities[$id][$key])) { + $entities[$id] = $this->entities[$id][$key]; + } + } + } + } + return $entities; + } + + /** + * Stores entities in the static entity cache. + * + * @param \Drupal\Core\Entity\EntityInterface[] $entities + * Entities to store in the cache. + */ + protected function setStaticCache(array $entities) { + if ($this->entityType->isStaticallyCacheable()) { + foreach ($entities as $id => $entity) { + $key = $this->configFactory->getCacheKey($this->getConfigPrefix() . $id); + $this->entities[$id][$key] = $entity; + } + } + } + + /** * Invokes a hook on behalf of the entity. * * @param $hook only in patch2: unchanged: --- a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php @@ -648,9 +648,6 @@ protected function doDelete($entities) { $this->invokeFieldMethod('delete', $entity); $this->deleteFieldItems($entity); } - - // Reset the cache as soon as the changes have been applied. - $this->resetCache($ids); } /** @@ -709,7 +706,6 @@ protected function doSave($id, EntityInterface $entity) { if ($this->revisionTable) { $entity->setNewRevision(FALSE); } - $cache_ids = array($entity->id()); } else { // Ensure the entity is still seen as new after assigning it an id, @@ -742,12 +738,9 @@ protected function doSave($id, EntityInterface $entity) { if ($this->revisionTable) { $entity->setNewRevision(FALSE); } - // Reset general caches, but keep caches specific to certain entities. - $cache_ids = array(); } $this->invokeFieldMethod($is_new ? 'insert' : 'update', $entity); $this->saveFieldItems($entity, !$is_new); - $this->resetCache($cache_ids); if (!$is_new && $this->dataTable) { $this->invokeTranslationHooks($entity); only in patch2: unchanged: --- a/core/lib/Drupal/Core/Entity/EntityStorageBase.php +++ b/core/lib/Drupal/Core/Entity/EntityStorageBase.php @@ -339,14 +339,18 @@ public function delete(array $entities) { return; } + // Allow code to run before deleting. $entity_class = $this->entityClass; $entity_class::preDelete($this, $entities); foreach ($entities as $entity) { $this->invokeHook('predelete', $entity); } + // Perform the delete and reset the static cache for the deleted entities. $this->doDelete($entities); + $this->resetCache(array_keys($entities)); + // Allow code to run after deleting. $entity_class::postDelete($this, $entities); foreach ($entities as $entity) { $this->invokeHook('delete', $entity); @@ -391,8 +395,9 @@ public function save(EntityInterface $entity) { $entity->preSave($this); $this->invokeHook('presave', $entity); - // Perform the save. + // Perform the save and reset the static cache for the changed entity. $return = $this->doSave($id, $entity); + $this->resetCache(array($id)); // The entity is no longer new. $entity->enforceIsNew(FALSE);