diff --git a/core/lib/Drupal/Core/Cache/ApcuBackend.php b/core/lib/Drupal/Core/Cache/ApcuBackend.php index b8a31be..a77941a 100644 --- a/core/lib/Drupal/Core/Cache/ApcuBackend.php +++ b/core/lib/Drupal/Core/Cache/ApcuBackend.php @@ -274,9 +274,9 @@ public function invalidate($cid) { * {@inheritdoc} */ public function invalidateMultiple(array $cids) { - foreach ($this->getMultiple($cids) as $cache) { + foreach (apc_fetch(array_map(array($this, 'getApcuKey'), $cids)) as $key => $cache) { $cache->expire = REQUEST_TIME - 1; - apc_store($this->getApcuKey($cache->cid), $cache, 1); + apc_store($key, $cache, 1); } } @@ -295,11 +295,12 @@ public function invalidateAll() { */ public function deleteTags(array $tags) { foreach ($this->flattenTags($tags) as $tag) { - apc_inc($this->deletionsTagsPrefix . $tag, 1, $success); + $tag_key = $this->deletionsTagsPrefix . $tag; + apc_inc($tag_key, 1, $success); if (!$success) { - apc_store($this->deletionsTagsPrefix . $tag, 1); + apc_store($tag_key, 1); } - unset(static::$tagCache['deletions'][$tag]); + unset(static::$tagCache['deletions'][$tag_key]); } } @@ -308,11 +309,12 @@ public function deleteTags(array $tags) { */ public function invalidateTags(array $tags) { foreach ($this->flattenTags($tags) as $tag) { - apc_inc($this->invalidationsTagsPrefix . $tag, 1, $success); + $tag_key = $this->invalidationsTagsPrefix . $tag; + apc_inc($tag_key, 1, $success); if (!$success) { - apc_store($this->invalidationsTagsPrefix . $tag, 1); + apc_store($tag_key, 1); } - unset(static::$tagCache['invalidations'][$tag]); + unset(static::$tagCache['invalidations'][$tag_key]); } } @@ -359,24 +361,21 @@ protected function checksumTags(array $tags) { foreach ($this->flattenTags($tags) as $tag) { foreach (array('deletions', 'invalidations') as $type) { - if (isset(static::$tagCache[$type][$tag])) { - $checksum[$type] += static::$tagCache[$type][$tag]; + $tag_key = $this->{$type . 'TagsPrefix'} . $tag; + if (isset(static::$tagCache[$type][$tag_key])) { + $checksum[$type] += static::$tagCache[$type][$tag_key]; } else { - $query_tags[$type][] = $this->{$type . 'TagsPrefix'} . $tag; + $query_tags[$type][] = $tag_key; } } } foreach (array('deletions', 'invalidations') as $type) { if ($query_tags[$type]) { - $prefix_length = strlen($this->{$type . 'TagsPrefix'}); $result = apc_fetch($query_tags[$type]); - foreach ($result as $key => $value) { - $tag = substr($key, $prefix_length); - static::$tagCache[$type][$tag] = $value; - $checksum[$type] += $value; - } + static::$tagCache[$type] = array_merge(static::$tagCache[$type], $result); + $checksum[$type] += array_sum($result); } } diff --git a/core/modules/system/src/Tests/Cache/GenericCacheBackendUnitTestBase.php b/core/modules/system/src/Tests/Cache/GenericCacheBackendUnitTestBase.php index 6b591fa..050cf03 100644 --- a/core/modules/system/src/Tests/Cache/GenericCacheBackendUnitTestBase.php +++ b/core/modules/system/src/Tests/Cache/GenericCacheBackendUnitTestBase.php @@ -560,6 +560,12 @@ function testInvalidate() { // Calling invalidateMultiple() with an empty array should not cause an // error. $this->assertFalse($backend->invalidateMultiple(array())); + + // Test that an invalidated item is deleted with deleteTags(). + $backend->set('test5', 5, Cache::PERMANENT, array('test_tag' => 5)); + $backend->invalidate('test5'); + $backend->deleteTags(array('test_tag' => 5)); + $this->assertFalse($backend->get('test5', TRUE)); } /** @@ -643,6 +649,18 @@ public function testInvalidateAll() { $this->assertTrue($backend->get('test2', TRUE), 'Second key has not been deleted.'); // Test that calling invalidateAll() does not change data. $this->assertIdentical($backend->get('test1', TRUE)->data, 1); + + // Test that an invalidated item is deleted with deleteTags(). + $backend->set('test4', 4, Cache::PERMANENT, array('test_tag' => 4)); + $backend->invalidateAll(); + $backend->deleteTags(array('test_tag' => 4)); + $this->assertFalse($backend->get('test4', TRUE)); + + // Test that a deleted item is still deleted after invalidateAll(). + $backend->set('test5', 5, Cache::PERMANENT, array('test_tag' => 5)); + $backend->deleteTags(array('test_tag' => 5)); + $backend->invalidateAll(); + $this->assertFalse($backend->get('test5', TRUE)); } }