From 8f00a9a1ee79ca74d77ab4b7b153518855a605d7 Mon Sep 17 00:00:00 2001 From: Nathaniel Catchpole Date: Mon, 27 Aug 2018 19:51:11 +0900 Subject: [PATCH] Issue #2983887 by Berdir: Add static cache to \Drupal\Core\Entity\ContentEntityStorageBase::getLatest*RevisionId() --- .../Core/Entity/ContentEntityStorageBase.php | 47 +++++++++++++------ .../src/Functional/ModerationLocaleTest.php | 3 ++ ...tentTranslationPendingRevisionTestBase.php | 3 ++ 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php index 2eb7c2f6b91d..d38244bd65dd 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php @@ -7,6 +7,7 @@ use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Cache\MemoryCache\MemoryCacheInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface; +use Drupal\Core\Language\LanguageInterface; use Drupal\Core\TypedData\TranslationStatusInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -36,6 +37,13 @@ abstract class ContentEntityStorageBase extends EntityStorageBase implements Con */ protected $cacheBackend; + /** + * Stores the latest revision IDs for entities. + * + * @var array + */ + protected $latestRevisionIds = []; + /** * Constructs a ContentEntityStorageBase object. * @@ -350,13 +358,17 @@ abstract class ContentEntityStorageBase extends EntityStorageBase implements Con return NULL; } - $result = $this->getQuery() - ->latestRevision() - ->condition($this->entityType->getKey('id'), $entity_id) - ->accessCheck(FALSE) - ->execute(); + if (!isset($this->latestRevisionIds[$entity_id][LanguageInterface::LANGCODE_DEFAULT])) { + $result = $this->getQuery() + ->latestRevision() + ->condition($this->entityType->getKey('id'), $entity_id) + ->accessCheck(FALSE) + ->execute(); - return key($result); + $this->latestRevisionIds[$entity_id][LanguageInterface::LANGCODE_DEFAULT] = key($result); + } + + return $this->latestRevisionIds[$entity_id][LanguageInterface::LANGCODE_DEFAULT]; } /** @@ -371,16 +383,19 @@ abstract class ContentEntityStorageBase extends EntityStorageBase implements Con return $this->getLatestRevisionId($entity_id); } - $result = $this->getQuery() - ->allRevisions() - ->condition($this->entityType->getKey('id'), $entity_id) - ->condition($this->entityType->getKey('revision_translation_affected'), 1, '=', $langcode) - ->range(0, 1) - ->sort($this->entityType->getKey('revision'), 'DESC') - ->accessCheck(FALSE) - ->execute(); + if (!isset($this->latestRevisionIds[$entity_id][$langcode])) { + $result = $this->getQuery() + ->allRevisions() + ->condition($this->entityType->getKey('id'), $entity_id) + ->condition($this->entityType->getKey('revision_translation_affected'), 1, '=', $langcode) + ->range(0, 1) + ->sort($this->entityType->getKey('revision'), 'DESC') + ->accessCheck(FALSE) + ->execute(); - return key($result); + $this->latestRevisionIds[$entity_id][$langcode] = key($result); + } + return $this->latestRevisionIds[$entity_id][$langcode]; } /** @@ -1005,6 +1020,7 @@ abstract class ContentEntityStorageBase extends EntityStorageBase implements Con if ($this->entityType->isPersistentlyCacheable()) { $cids = []; foreach ($ids as $id) { + unset($this->latestRevisionIds[$id]); $cids[] = $this->buildCacheId($id); } $this->cacheBackend->deleteMultiple($cids); @@ -1015,6 +1031,7 @@ abstract class ContentEntityStorageBase extends EntityStorageBase implements Con if ($this->entityType->isPersistentlyCacheable()) { Cache::invalidateTags([$this->entityTypeId . '_values']); } + $this->latestRevisionIds = []; } } diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationLocaleTest.php b/core/modules/content_moderation/tests/src/Functional/ModerationLocaleTest.php index 28de50c53549..1bdbb7e46110 100644 --- a/core/modules/content_moderation/tests/src/Functional/ModerationLocaleTest.php +++ b/core/modules/content_moderation/tests/src/Functional/ModerationLocaleTest.php @@ -482,6 +482,9 @@ class ModerationLocaleTest extends ModerationStateTestBase { protected function loadTranslation(NodeInterface $node, $langcode) { /** @var \Drupal\node\NodeStorageInterface $storage */ $storage = $this->container->get('entity_type.manager')->getStorage('node'); + // Explicitly invalidate the cache for that node, as the call below is + // statically cached. + $storage->resetCache([$node->id()]); /** @var \Drupal\node\NodeInterface $node */ $node = $storage->loadRevision($storage->getLatestRevisionId($node->id())); return $node->getTranslation($langcode); diff --git a/core/modules/content_translation/tests/src/Functional/ContentTranslationPendingRevisionTestBase.php b/core/modules/content_translation/tests/src/Functional/ContentTranslationPendingRevisionTestBase.php index 0984850f37c0..ef0f54aeca44 100644 --- a/core/modules/content_translation/tests/src/Functional/ContentTranslationPendingRevisionTestBase.php +++ b/core/modules/content_translation/tests/src/Functional/ContentTranslationPendingRevisionTestBase.php @@ -127,6 +127,9 @@ abstract class ContentTranslationPendingRevisionTestBase extends ContentTranslat * The active revision translation or NULL if none could be identified. */ protected function loadRevisionTranslation(ContentEntityInterface $entity, $langcode) { + // Explicitly invalidate the cache for that node, as the call below is + // statically cached. + $this->storage->resetCache([$entity->id()]); $revision_id = $this->storage->getLatestTranslationAffectedRevisionId($entity->id(), $langcode); /** @var \Drupal\Core\Entity\ContentEntityInterface $revision */ $revision = $revision_id ? $this->storage->loadRevision($revision_id) : NULL;