From 08bf243d3fc4d341a15de28e5cd23495b6548200 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Fri, 23 Feb 2024 13:05:25 +0000
Subject: [PATCH] Issue #3423272 by catch, kristiaanvandeneynde: Return early
 from more cache tag operations

---
 core/lib/Drupal/Core/Cache/CacheTagsChecksumTrait.php |  6 +++++-
 .../src/Cache/CacheTagsChecksumDecorator.php          | 11 +++++++++++
 .../FunctionalJavascript/StandardPerformanceTest.php  |  5 +++--
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/core/lib/Drupal/Core/Cache/CacheTagsChecksumTrait.php b/core/lib/Drupal/Core/Cache/CacheTagsChecksumTrait.php
index 25bc3673fbb1..8083cba8950b 100644
--- a/core/lib/Drupal/Core/Cache/CacheTagsChecksumTrait.php
+++ b/core/lib/Drupal/Core/Cache/CacheTagsChecksumTrait.php
@@ -51,7 +51,6 @@ public function rootTransactionEndCallback($success) {
    * Implements \Drupal\Core\Cache\CacheTagsInvalidatorInterface::invalidateTags()
    */
   public function invalidateTags(array $tags) {
-    // Only invalidate tags once per request unless they are written again.
     foreach ($tags as $key => $tag) {
       if (isset($this->invalidatedTags[$tag])) {
         unset($tags[$key]);
@@ -139,6 +138,11 @@ public function isValid($checksum, array $tags) {
    */
   protected function calculateChecksum(array $tags) {
     $checksum = 0;
+    // If there are no cache tags, then there is no cache tag to checksum,
+    // so return early..
+    if (empty($tags)) {
+      return $checksum;
+    }
 
     $query_tags = array_diff($tags, array_keys($this->tagCache));
     if ($query_tags) {
diff --git a/core/modules/system/tests/modules/performance_test/src/Cache/CacheTagsChecksumDecorator.php b/core/modules/system/tests/modules/performance_test/src/Cache/CacheTagsChecksumDecorator.php
index f1695fd2947f..e39a4f48af28 100644
--- a/core/modules/system/tests/modules/performance_test/src/Cache/CacheTagsChecksumDecorator.php
+++ b/core/modules/system/tests/modules/performance_test/src/Cache/CacheTagsChecksumDecorator.php
@@ -19,6 +19,12 @@ public function __construct(protected readonly CacheTagsChecksumInterface $check
    * {@inheritdoc}
    */
   public function getCurrentChecksum(array $tags) {
+    // If there are no cache tags, there is no checksum to get and the decorated
+    // method will be a no-op, so don't log anything.
+    if (empty($tags)) {
+      return $this->checksumInvalidator->getCurrentChecksum($tags);
+    }
+
     $start = microtime(TRUE);
     $return = $this->checksumInvalidator->getCurrentChecksum($tags);
     $stop = microtime(TRUE);
@@ -46,6 +52,11 @@ public function isValid($checksum, array $tags) {
    * {@inheritdoc}
    */
   public function invalidateTags(array $tags) {
+    // If there are no cache tags, there is nothing to invalidate, and the
+    // decorated method will be a no-op, so don't log anything.
+    if (empty($tags)) {
+      return $this->checksumInvalidator->invalidateTags($tags);
+    }
     $start = microtime(TRUE);
     $return = $this->checksumInvalidator->invalidateTags($tags);
     $stop = microtime(TRUE);
diff --git a/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php b/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php
index 1cf1cdf6acb1..7148acd8f5e5 100644
--- a/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php
+++ b/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php
@@ -59,7 +59,7 @@ public function testAnonymous() {
     $this->assertSame(137, $performance_data->getCacheGetCount());
     $this->assertSame(47, $performance_data->getCacheSetCount());
     $this->assertSame(0, $performance_data->getCacheDeleteCount());
-    $this->assertCountBetween(143, 146, $performance_data->getCacheTagChecksumCount());
+    $this->assertCountBetween(40, 43, $performance_data->getCacheTagChecksumCount());
     $this->assertCountBetween(47, 50, $performance_data->getCacheTagIsValidCount());
     $this->assertSame(0, $performance_data->getCacheTagInvalidationCount());
 
@@ -73,7 +73,7 @@ public function testAnonymous() {
     $this->assertSame(95, $performance_data->getCacheGetCount());
     $this->assertSame(16, $performance_data->getCacheSetCount());
     $this->assertSame(0, $performance_data->getCacheDeleteCount());
-    $this->assertCountBetween(79, 80, $performance_data->getCacheTagChecksumCount());
+    $this->assertCountBetween(24, 25, $performance_data->getCacheTagChecksumCount());
     $this->assertCountBetween(41, 42, $performance_data->getCacheTagIsValidCount());
     $this->assertSame(0, $performance_data->getCacheTagInvalidationCount());
 
@@ -87,6 +87,7 @@ public function testAnonymous() {
     $this->assertSame(81, $performance_data->getCacheGetCount());
     $this->assertSame(16, $performance_data->getCacheSetCount());
     $this->assertSame(0, $performance_data->getCacheDeleteCount());
+    $this->assertCountBetween(24, 25, $performance_data->getCacheTagChecksumCount());
     $this->assertCountBetween(36, 37, $performance_data->getCacheTagIsValidCount());
     $this->assertSame(0, $performance_data->getCacheTagInvalidationCount());
   }
-- 
GitLab