diff --git a/core/core.services.yml b/core/core.services.yml index 31167bd..e405ac6 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -68,18 +68,18 @@ services: factory_service: cache_factory arguments: [path] cache_tag_factory: - class: Drupal\Core\Cache\CacheTagFactory + class: Drupal\Core\Cache\CacheTagBackendFactory arguments: ['@settings'] calls: - [setContainer, ['@service_container']] cache.tag.database: - class: Drupal\Core\Cache\DatabaseTag + class: Drupal\Core\Cache\DatabaseTagBackend arguments: ['@database'] tags: - { name: cache.tag } - { name: persist } cache.tag.memory: - class: Drupal\Core\Cache\MemoryTag + class: Drupal\Core\Cache\MemoryTagBackend tags: - { name: cache.tag } - { name: persist } diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index c70360b..a69df30 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -382,7 +382,7 @@ function install_begin_request(&$install_state) { ->addArgument(new Reference('event_dispatcher')) ->addArgument(new Reference('config.typed')); - $container->register('cache.tag.memory', 'Drupal\Core\Cache\MemoryTag'); + $container->register('cache.tag.memory', 'Drupal\Core\Cache\MemoryTagBackend'); // Register the 'language_manager' service. $container->register('language_manager', 'Drupal\Core\Language\LanguageManager') diff --git a/core/lib/Drupal/Core/Cache/CacheBackendInterface.php b/core/lib/Drupal/Core/Cache/CacheBackendInterface.php index de49e8c..234d1f1 100644 --- a/core/lib/Drupal/Core/Cache/CacheBackendInterface.php +++ b/core/lib/Drupal/Core/Cache/CacheBackendInterface.php @@ -161,7 +161,7 @@ public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = array * * @see \Drupal\Core\Cache\CacheBackendInterface::invalidate() * @see \Drupal\Core\Cache\CacheBackendInterface::deleteMultiple() - * @see \Drupal\Core\Cache\CacheTagInterface::deleteTags() + * @see \Drupal\Core\Cache\CacheTagBackendInterface::deleteTags() * @see \Drupal\Core\Cache\CacheBackendInterface::deleteAll() */ public function delete($cid); @@ -180,7 +180,7 @@ public function delete($cid); * * @see \Drupal\Core\Cache\CacheBackendInterface::invalidateMultiple() * @see \Drupal\Core\Cache\CacheBackendInterface::delete() - * @see \Drupal\Core\Cache\CacheTagInterface::deleteTags() + * @see \Drupal\Core\Cache\CacheTagBackendInterface::deleteTags() * @see \Drupal\Core\Cache\CacheBackendInterface::deleteAll() */ public function deleteMultiple(array $cids); @@ -191,7 +191,7 @@ public function deleteMultiple(array $cids); * @see \Drupal\Core\Cache\CacheBackendInterface::invalidateAll() * @see \Drupal\Core\Cache\CacheBackendInterface::delete() * @see \Drupal\Core\Cache\CacheBackendInterface::deleteMultiple() - * @see \Drupal\Core\Cache\CacheTagInterface::deleteTags() + * @see \Drupal\Core\Cache\CacheTagBackendInterface::deleteTags() */ public function deleteAll(); @@ -206,7 +206,7 @@ public function deleteAll(); * * @see \Drupal\Core\Cache\CacheBackendInterface::delete() * @see \Drupal\Core\Cache\CacheBackendInterface::invalidateMultiple() - * @see \Drupal\Core\Cache\CacheTagInterface::invalidateTags() + * @see \Drupal\Core\Cache\CacheTagBackendInterface::invalidateTags() * @see \Drupal\Core\Cache\CacheBackendInterface::invalidateAll() */ public function invalidate($cid); @@ -222,7 +222,7 @@ public function invalidate($cid); * * @see \Drupal\Core\Cache\CacheBackendInterface::deleteMultiple() * @see \Drupal\Core\Cache\CacheBackendInterface::invalidate() - * @see \Drupal\Core\Cache\CacheTagInterface::invalidateTags() + * @see \Drupal\Core\Cache\CacheTagBackendInterface::invalidateTags() * @see \Drupal\Core\Cache\CacheBackendInterface::invalidateAll() */ public function invalidateMultiple(array $cids); @@ -239,7 +239,7 @@ public function invalidateMultiple(array $cids); * @see \Drupal\Core\Cache\CacheBackendInterface::deleteAll() * @see \Drupal\Core\Cache\CacheBackendInterface::invalidate() * @see \Drupal\Core\Cache\CacheBackendInterface::invalidateMultiple() - * @see \Drupal\Core\Cache\CacheTagInterface::invalidateTags() + * @see \Drupal\Core\Cache\CacheTagBackendInterface::invalidateTags() */ public function invalidateAll(); diff --git a/core/lib/Drupal/Core/Cache/CacheTagBackendBase.php b/core/lib/Drupal/Core/Cache/CacheTagBackendBase.php new file mode 100644 index 0000000..23b007d --- /dev/null +++ b/core/lib/Drupal/Core/Cache/CacheTagBackendBase.php @@ -0,0 +1,62 @@ + $values) { + if (is_array($values)) { + foreach ($values as $value) { + $flat_tags[] = "$namespace:$value"; + } + } + else { + $flat_tags[] = "$namespace:$values"; + } + } + return $flat_tags; + } + + /** + * Raises an array of 'flattened' tags (inverse function to flattenTags()). + * + * @param array $tags + * Associative array of flat tags to raise. + * + * @return array + * An array of raised tags. + */ + public function raiseTags(array $flat_tags) { + $tags = array(); + foreach ($flat_tags as $tag) { + list($key, $value) = explode(':', $tag); + $tags[$key] = $value; + } + + return $tags; + } + +} diff --git a/core/lib/Drupal/Core/Cache/CacheTagBackendFactory.php b/core/lib/Drupal/Core/Cache/CacheTagBackendFactory.php new file mode 100644 index 0000000..a632449 --- /dev/null +++ b/core/lib/Drupal/Core/Cache/CacheTagBackendFactory.php @@ -0,0 +1,57 @@ +settings = $settings; + } + + /** + * Instantiates a cache tag class. + * + * By default, this returns an instance of the + * Drupal\Core\Cache\DatabaseBackendTag class. + * + * @return \Drupal\Core\Cache\CacheTagBackendInterface + * The cache tag instance. + */ + public function get() { + $cache_tag_service = $this->settings->get('cache_tag_service'); + + if (isset($cache_tag_service)) { + $service_name = $cache_tag_service; + } + else { + $service_name = 'cache.tag.database'; + } + + return $this->container->get($service_name); + } + +} diff --git a/core/lib/Drupal/Core/Cache/CacheTagBackendInterface.php b/core/lib/Drupal/Core/Cache/CacheTagBackendInterface.php new file mode 100644 index 0000000..7a4a629 --- /dev/null +++ b/core/lib/Drupal/Core/Cache/CacheTagBackendInterface.php @@ -0,0 +1,62 @@ +deleted should be set to TRUE if item was deleted via tags and + * $item->valid should be set to FALSE if item was invalidated. + */ + public function prepareGet(&$item); + + /** + * Clears cache tag service internal caches. + */ + public function clearCache(); +} diff --git a/core/lib/Drupal/Core/Cache/CacheTagBase.php b/core/lib/Drupal/Core/Cache/CacheTagBase.php deleted file mode 100644 index bfcc211..0000000 --- a/core/lib/Drupal/Core/Cache/CacheTagBase.php +++ /dev/null @@ -1,43 +0,0 @@ - $values) { - if (is_array($values)) { - foreach ($values as $value) { - $flat_tags[] = "$namespace:$value"; - } - } - else { - $flat_tags[] = "$namespace:$values"; - } - } - return $flat_tags; - } - -} diff --git a/core/lib/Drupal/Core/Cache/CacheTagFactory.php b/core/lib/Drupal/Core/Cache/CacheTagFactory.php deleted file mode 100644 index cb9715e..0000000 --- a/core/lib/Drupal/Core/Cache/CacheTagFactory.php +++ /dev/null @@ -1,57 +0,0 @@ -settings = $settings; - } - - /** - * Instantiates a cache tag class. - * - * By default, this returns an instance of the - * Drupal\Core\Cache\DatabaseTag class. - * - * @return \Drupal\Core\Cache\CacheTagInterface - * The cache tag instance. - */ - public function get() { - $cache_tag_service = $this->settings->get('cache_tag_service'); - - if (isset($cache_tag_service)) { - $service_name = $cache_tag_service; - } - else { - $service_name = 'cache.tag.database'; - } - - return $this->container->get($service_name); - } - -} diff --git a/core/lib/Drupal/Core/Cache/CacheTagInterface.php b/core/lib/Drupal/Core/Cache/CacheTagInterface.php deleted file mode 100644 index fac94d7..0000000 --- a/core/lib/Drupal/Core/Cache/CacheTagInterface.php +++ /dev/null @@ -1,62 +0,0 @@ -deleted should be set to TRUE if item was deleted via tags and - * $item->valid should be set to FALSE if item was invalidated. - */ - public function prepareGet(&$item); - - /** - * Clears cache tag service internal caches. - */ - public function clearCache(); -} diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php index 19ea1b3..2b836fa 100644 --- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php +++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php @@ -33,7 +33,7 @@ class DatabaseBackend implements CacheBackendInterface { /** * The cache tag service. * - * @var \Drupal\Core\Cache\CacheTagInterface + * @var \Drupal\Core\Cache\CacheTagBackendInterface */ protected $cacheTag; @@ -42,12 +42,12 @@ class DatabaseBackend implements CacheBackendInterface { * * @param \Drupal\Core\Database\Connection $connection * The database connection. - * @param \Drupal\Core\Cache\CacheTagInterface + * @param \Drupal\Core\Cache\CacheTagBackendInterface * The cache tag service. * @param string $bin * The cache bin for which the object is created. */ - public function __construct(Connection $connection, CacheTagInterface $cache_tag, $bin) { + public function __construct(Connection $connection, CacheTagBackendInterface $cache_tag, $bin) { // All cache tables should be prefixed with 'cache_', except for the // default 'cache' bin. if ($bin != 'cache') { @@ -117,7 +117,7 @@ protected function prepareItem($cache, $allow_invalid) { return FALSE; } - $cache->tags = $cache->tags ? explode(' ', $cache->tags) : array(); + $cache->tags = $cache->tags ? $this->cacheTag->raiseTags(explode(' ', $cache->tags)) : array(); // Check expire time. $cache->valid = $time_valid = $cache->expire == Cache::PERMANENT || $cache->expire >= REQUEST_TIME; diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackendFactory.php b/core/lib/Drupal/Core/Cache/DatabaseBackendFactory.php index d78f757..7046026 100644 --- a/core/lib/Drupal/Core/Cache/DatabaseBackendFactory.php +++ b/core/lib/Drupal/Core/Cache/DatabaseBackendFactory.php @@ -21,7 +21,7 @@ class DatabaseBackendFactory implements CacheFactoryInterface { /** * The cache tag factory service. * - * @var \Drupal\Core\Cache\CacheTagFactory + * @var \Drupal\Core\Cache\CacheTagBackendFactory */ protected $cacheTagFactory; @@ -30,7 +30,7 @@ class DatabaseBackendFactory implements CacheFactoryInterface { * * @param \Drupal\Core\Database\Connection $connection */ - function __construct(Connection $connection, CacheTagFactory $cache_tag_factory) { + function __construct(Connection $connection, CacheTagBackendFactory $cache_tag_factory) { $this->connection = $connection; $this->cacheTagFactory = $cache_tag_factory; } diff --git a/core/lib/Drupal/Core/Cache/DatabaseTag.php b/core/lib/Drupal/Core/Cache/DatabaseTag.php deleted file mode 100644 index a3aeb41..0000000 --- a/core/lib/Drupal/Core/Cache/DatabaseTag.php +++ /dev/null @@ -1,159 +0,0 @@ -connection = $connection; - } - - /** - * {@inheritdoc} - */ - public function invalidateTags(array $tags) { - $tag_cache = &drupal_static('Drupal\Core\Cache\CacheTagInterface::tagCache', array()); - try { - foreach ($this->flattenTags($tags) as $tag) { - unset($tag_cache[$tag]); - $this->connection->merge('cache_tags') - ->insertFields(array('invalidations' => 1)) - ->expression('invalidations', 'invalidations + 1') - ->key(array('tag' => $tag)) - ->execute(); - } - } - catch (\Exception $e) { - $this->catchException($e, 'cache_tags'); - } - } - - /** - * {@inheritdoc} - */ - public function deleteTags(array $tags) { - $deleted_tags = &drupal_static('Drupal\Core\Cache\DatabaseTag::deletedTags', array()); - $tag_cache = &drupal_static('Drupal\Core\Cache\CacheTagInterface::tagCache', array()); - foreach ($this->flattenTags($tags) as $tag) { - // Only delete tags once per request unless they are written again. - if (isset($deleted_tags[$tag])) { - continue; - } - $deleted_tags[$tag] = TRUE; - unset($tag_cache[$tag]); - try { - $this->connection->merge('cache_tags') - ->insertFields(array('deletions' => 1)) - ->expression('deletions', 'deletions + 1') - ->key(array('tag' => $tag)) - ->execute(); - } - catch (\Exception $e) { - $this->catchException($e, 'cache_tags'); - } - } - } - - /** - * {@inheritdoc} - */ - public function checksumTags(array $tags, $set_context) { - $flat_tags = $this->flattenTags($tags); - $tag_cache = &drupal_static('Drupal\Core\Cache\CacheTagInterface::tagCache', array()); - - if ($set_context) { - $deleted_tags = &drupal_static('Drupal\Core\Cache\DatabaseTag::deletedTags', array()); - // Remove tags that were already deleted during this request from the static - // cache so that another deletion for them will be correctly updated. - foreach ($flat_tags as $tag) { - if (isset($deleted_tags[$tag])) { - unset($deleted_tags[$tag]); - } - } - } - - $checksum = array( - 'invalidations' => 0, - 'deletions' => 0, - ); - - $query_tags = array_diff($flat_tags, array_keys($tag_cache)); - if ($query_tags) { - $db_tags = $this->connection->query('SELECT tag, invalidations, deletions FROM {cache_tags} WHERE tag IN (:tags)', array(':tags' => $query_tags))->fetchAllAssoc('tag', \PDO::FETCH_ASSOC); - $tag_cache += $db_tags; - - // Fill static cache with empty objects for tags not found in the database. - $tag_cache += array_fill_keys(array_diff($query_tags, array_keys($db_tags)), $checksum); - } - - foreach ($flat_tags as $tag) { - $checksum['invalidations'] += $tag_cache[$tag]['invalidations']; - $checksum['deletions'] += $tag_cache[$tag]['deletions']; - } - - return $checksum; - } - - /** - * {@inheritdoc} - */ - public function prepareGet(&$item) { - $checksum = $this->checksumTags($item->tags, FALSE); - - // Check if deleteTags() has been called with any of the entry's tags. - $item->deleted = $item->checksum_deletions != $checksum['deletions']; - - // Check if invalidateTags() has been called with any of the entry's tags. - if ($item->checksum_invalidations != $checksum['invalidations']) { - $item->valid = FALSE; - } - } - - /** - * Act on an exception when cache might be stale. - * - * If the cache_tags table does not yet exist, that's fine but if the table - * exists and yet the query failed, then the cache is stale and the - * exception needs to propagate. - * - * @param $e - * The exception. - * @param string|null $table_name - * The table name, defaults to $this->bin. Can be cache_tags. - */ - protected function catchException(\Exception $e, $table_name = NULL) { - if ($this->connection->schema()->tableExists($table_name ?: $this->bin)) { - throw $e; - } - } - - /** - * {@inheritdoc}. - */ - public function clearCache() { - // Nothing to do here. - } -} diff --git a/core/lib/Drupal/Core/Cache/DatabaseTagBackend.php b/core/lib/Drupal/Core/Cache/DatabaseTagBackend.php new file mode 100644 index 0000000..7fe2225 --- /dev/null +++ b/core/lib/Drupal/Core/Cache/DatabaseTagBackend.php @@ -0,0 +1,159 @@ +connection = $connection; + } + + /** + * {@inheritdoc} + */ + public function invalidateTags(array $tags) { + $tag_cache = &drupal_static('Drupal\Core\Cache\CacheTagBackendInterface::tagCache', array()); + try { + foreach ($this->flattenTags($tags) as $tag) { + unset($tag_cache[$tag]); + $this->connection->merge('cache_tags') + ->insertFields(array('invalidations' => 1)) + ->expression('invalidations', 'invalidations + 1') + ->key(array('tag' => $tag)) + ->execute(); + } + } + catch (\Exception $e) { + $this->catchException($e, 'cache_tags'); + } + } + + /** + * {@inheritdoc} + */ + public function deleteTags(array $tags) { + $deleted_tags = &drupal_static('Drupal\Core\Cache\DatabaseTagBackend::deletedTags', array()); + $tag_cache = &drupal_static('Drupal\Core\Cache\CacheTagBackendInterface::tagCache', array()); + foreach ($this->flattenTags($tags) as $tag) { + // Only delete tags once per request unless they are written again. + if (isset($deleted_tags[$tag])) { + continue; + } + $deleted_tags[$tag] = TRUE; + unset($tag_cache[$tag]); + try { + $this->connection->merge('cache_tags') + ->insertFields(array('deletions' => 1)) + ->expression('deletions', 'deletions + 1') + ->key(array('tag' => $tag)) + ->execute(); + } + catch (\Exception $e) { + $this->catchException($e, 'cache_tags'); + } + } + } + + /** + * {@inheritdoc} + */ + public function checksumTags(array $tags, $set_context) { + $flat_tags = $this->flattenTags($tags); + $tag_cache = &drupal_static('Drupal\Core\Cache\CacheTagBackendInterface::tagCache', array()); + + if ($set_context) { + $deleted_tags = &drupal_static('Drupal\Core\Cache\DatabaseTagBackend::deletedTags', array()); + // Remove tags that were already deleted during this request from the static + // cache so that another deletion for them will be correctly updated. + foreach ($flat_tags as $tag) { + if (isset($deleted_tags[$tag])) { + unset($deleted_tags[$tag]); + } + } + } + + $checksum = array( + 'invalidations' => 0, + 'deletions' => 0, + ); + + $query_tags = array_diff($flat_tags, array_keys($tag_cache)); + if ($query_tags) { + $db_tags = $this->connection->query('SELECT tag, invalidations, deletions FROM {cache_tags} WHERE tag IN (:tags)', array(':tags' => $query_tags))->fetchAllAssoc('tag', \PDO::FETCH_ASSOC); + $tag_cache += $db_tags; + + // Fill static cache with empty objects for tags not found in the database. + $tag_cache += array_fill_keys(array_diff($query_tags, array_keys($db_tags)), $checksum); + } + + foreach ($flat_tags as $tag) { + $checksum['invalidations'] += $tag_cache[$tag]['invalidations']; + $checksum['deletions'] += $tag_cache[$tag]['deletions']; + } + + return $checksum; + } + + /** + * {@inheritdoc} + */ + public function prepareGet(&$item) { + $checksum = $this->checksumTags($item->tags, FALSE); + + // Check if deleteTags() has been called with any of the entry's tags. + $item->deleted = $item->checksum_deletions != $checksum['deletions']; + + // Check if invalidateTags() has been called with any of the entry's tags. + if ($item->checksum_invalidations != $checksum['invalidations']) { + $item->valid = FALSE; + } + } + + /** + * Act on an exception when cache might be stale. + * + * If the cache_tags table does not yet exist, that's fine but if the table + * exists and yet the query failed, then the cache is stale and the + * exception needs to propagate. + * + * @param $e + * The exception. + * @param string|null $table_name + * The table name, defaults to $this->bin. Can be cache_tags. + */ + protected function catchException(\Exception $e, $table_name = NULL) { + if ($this->connection->schema()->tableExists($table_name ?: $this->bin)) { + throw $e; + } + } + + /** + * {@inheritdoc}. + */ + public function clearCache() { + // Nothing to do here. + } +} diff --git a/core/lib/Drupal/Core/Cache/MemoryBackend.php b/core/lib/Drupal/Core/Cache/MemoryBackend.php index 72cd1ff..9d636f5 100644 --- a/core/lib/Drupal/Core/Cache/MemoryBackend.php +++ b/core/lib/Drupal/Core/Cache/MemoryBackend.php @@ -26,17 +26,20 @@ class MemoryBackend implements CacheBackendInterface { /** * The cache tag service. * - * @var \Drupal\Core\Cache\CacheTagInterface + * @var \Drupal\Core\Cache\CacheTagBackendInterface */ protected $cacheTag; /** * Constructs a MemoryBackend object. * + * + * @param \Drupal\Core\Cache\CacheTagBackendInterface + * The cache tag service. * @param string $bin * The cache bin for which the object is created. */ - public function __construct(CacheTagInterface $cache_tag, $bin) { + public function __construct(CacheTagBackendInterface $cache_tag, $bin) { $this->cacheTag = $cache_tag; } @@ -92,6 +95,7 @@ protected function prepareItem($cache, $allow_invalid) { // Check expire time. $cache->valid = $time_valid = $cache->expire == Cache::PERMANENT || $cache->expire >= REQUEST_TIME; + $cache->tags = $this->cacheTag->raiseTags($cache->tags); $this->cacheTag->prepareGet($cache); if ($cache->deleted) { diff --git a/core/lib/Drupal/Core/Cache/MemoryBackendFactory.php b/core/lib/Drupal/Core/Cache/MemoryBackendFactory.php index 917110d..acaa82f 100644 --- a/core/lib/Drupal/Core/Cache/MemoryBackendFactory.php +++ b/core/lib/Drupal/Core/Cache/MemoryBackendFactory.php @@ -12,7 +12,7 @@ class MemoryBackendFactory implements CacheFactoryInterface { /** * The cache tag factory service. * - * @var \Drupal\Core\Cache\CacheTagFactory + * @var \Drupal\Core\Cache\CacheTagBackendFactory */ protected $cacheTagFactory; @@ -21,7 +21,7 @@ class MemoryBackendFactory implements CacheFactoryInterface { * * @param \Drupal\Core\Database\Connection $connection */ - function __construct(CacheTagFactory $cache_tag_factory) { + function __construct(CacheTagBackendFactory $cache_tag_factory) { $this->cacheTagFactory = $cache_tag_factory; } diff --git a/core/lib/Drupal/Core/Cache/MemoryTag.php b/core/lib/Drupal/Core/Cache/MemoryTag.php deleted file mode 100644 index 26952c4..0000000 --- a/core/lib/Drupal/Core/Cache/MemoryTag.php +++ /dev/null @@ -1,96 +0,0 @@ -storage[$tag])) { - $this->storage[$tag] = array( - 'invalidations' => 0, - 'deletions' => 0, - ); - } - } - - /** - * {@inheritdoc} - */ - public function invalidateTags(array $tags) { - foreach ($this->flattenTags($tags) as $tag) { - $this->ensureItem($tag); - $this->storage[$tag]['invalidations']++; - } - } - - /** - * {@inheritdoc} - */ - public function deleteTags(array $tags) { - foreach ($this->flattenTags($tags) as $tag) { - $this->ensureItem($tag); - $this->storage[$tag]['deletions']++; - } - } - - /** - * {@inheritdoc} - */ - public function checksumTags(array $tags, $set_context) { - $flat_tags = $this->flattenTags($tags); - $checksum = array( - 'invalidations' => 0, - 'deletions' => 0, - ); - - foreach ($flat_tags as $tag) { - $this->ensureItem($tag); - $checksum['invalidations'] += $this->storage[$tag]['invalidations']; - $checksum['deletions'] += $this->storage[$tag]['deletions']; - } - - return $checksum; - } - - /** - * {@inheritdoc} - */ - public function prepareGet(&$item) { - $checksum = $this->checksumTags($item->tags, FALSE); - - // Check if deleteTags() has been called with any of the entry's tags. - $item->deleted = $item->checksum_deletions != $checksum['deletions']; - - // Check if invalidateTags() has been called with any of the entry's tags. - if ($item->checksum_invalidations != $checksum['invalidations']) { - $item->valid = FALSE; - } - } - - /** - * {@inheritdoc}. - */ - public function clearCache() { - // Nothing to be done here. - } -} diff --git a/core/lib/Drupal/Core/Cache/MemoryTagBackend.php b/core/lib/Drupal/Core/Cache/MemoryTagBackend.php new file mode 100644 index 0000000..d7dba4f --- /dev/null +++ b/core/lib/Drupal/Core/Cache/MemoryTagBackend.php @@ -0,0 +1,96 @@ +storage[$tag])) { + $this->storage[$tag] = array( + 'invalidations' => 0, + 'deletions' => 0, + ); + } + } + + /** + * {@inheritdoc} + */ + public function invalidateTags(array $tags) { + foreach ($this->flattenTags($tags) as $tag) { + $this->ensureItem($tag); + $this->storage[$tag]['invalidations']++; + } + } + + /** + * {@inheritdoc} + */ + public function deleteTags(array $tags) { + foreach ($this->flattenTags($tags) as $tag) { + $this->ensureItem($tag); + $this->storage[$tag]['deletions']++; + } + } + + /** + * {@inheritdoc} + */ + public function checksumTags(array $tags, $set_context) { + $flat_tags = $this->flattenTags($tags); + $checksum = array( + 'invalidations' => 0, + 'deletions' => 0, + ); + + foreach ($flat_tags as $tag) { + $this->ensureItem($tag); + $checksum['invalidations'] += $this->storage[$tag]['invalidations']; + $checksum['deletions'] += $this->storage[$tag]['deletions']; + } + + return $checksum; + } + + /** + * {@inheritdoc} + */ + public function prepareGet(&$item) { + $checksum = $this->checksumTags($item->tags, FALSE); + + // Check if deleteTags() has been called with any of the entry's tags. + $item->deleted = $item->checksum_deletions != $checksum['deletions']; + + // Check if invalidateTags() has been called with any of the entry's tags. + if ($item->checksum_invalidations != $checksum['invalidations']) { + $item->valid = FALSE; + } + } + + /** + * {@inheritdoc}. + */ + public function clearCache() { + // Nothing to be done here. + } +} diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index b03d826..a6afe92 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -1058,8 +1058,8 @@ protected function resetAll() { protected function refreshVariables() { // Clear the tag cache. $this->container->get('cache.tag.database')->clearCache(); - drupal_static_reset('Drupal\Core\Cache\CacheTagInterface::tagCache'); - drupal_static_reset('Drupal\Core\Cache\DatabaseTag::deletedTags'); + drupal_static_reset('Drupal\Core\Cache\CacheTagBackendInterface::tagCache'); + drupal_static_reset('Drupal\Core\Cache\DatabaseTagBackend::deletedTags'); $this->container->get('config.factory')->reset(); $this->container->get('state')->resetCache(); diff --git a/core/modules/system/lib/Drupal/system/Tests/Cache/BackendChainUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Cache/BackendChainUnitTest.php index c2207d5..dc97dc4 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Cache/BackendChainUnitTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Cache/BackendChainUnitTest.php @@ -9,7 +9,7 @@ use Drupal\Core\Cache\BackendChain; use Drupal\Core\Cache\MemoryBackend; -use Drupal\Core\Cache\MemoryTag; +use Drupal\Core\Cache\MemoryTagBackend; /** * Tests BackendChain using GenericCacheBackendUnitTestBase. @@ -28,7 +28,7 @@ protected function createCacheBackend($bin) { $chain = new BackendChain($bin); // We need to create some various backends in the chain. - $cache_tag = new MemoryTag(); + $cache_tag = new MemoryTagBackend(); $chain ->appendBackend(new MemoryBackend($cache_tag, 'foo')) ->prependBackend(new MemoryBackend($cache_tag, 'bar')) diff --git a/core/modules/system/lib/Drupal/system/Tests/Cache/MemoryBackendUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Cache/MemoryBackendUnitTest.php index 9ae5488..f6cf75c 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Cache/MemoryBackendUnitTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Cache/MemoryBackendUnitTest.php @@ -8,7 +8,7 @@ namespace Drupal\system\Tests\Cache; use Drupal\Core\Cache\MemoryBackend; -use Drupal\Core\Cache\MemoryTag; +use Drupal\Core\Cache\MemoryTagBackend; /** * Tests MemoryBackend using GenericCacheBackendUnitTestBase. @@ -30,6 +30,6 @@ public static function getInfo() { * A new MemoryBackend object. */ protected function createCacheBackend($bin) { - return new MemoryBackend(new MemoryTag(), $bin); + return new MemoryBackend(new MemoryTagBackend(), $bin); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/CacheDecoratorTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/CacheDecoratorTest.php index 2deb327..75fe0a6 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Plugin/CacheDecoratorTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/CacheDecoratorTest.php @@ -7,9 +7,8 @@ namespace Drupal\system\Tests\Plugin; -use Drupal\Core\Cache\MemoryBackendFactory; use Drupal\Core\Cache\MemoryBackend; -use Drupal\Core\Cache\MemoryTag; +use Drupal\Core\Cache\MemoryTagBackend; use Drupal\system\Tests\Plugin\Discovery\DiscoveryTestBase; use Drupal\Component\Plugin\Discovery\StaticDiscovery; use Drupal\Core\Plugin\Discovery\CacheDecorator; @@ -48,7 +47,7 @@ public function setUp() { // Use a non-db cache backend, so that we can use DiscoveryTestBase (which // extends UnitTestBase). // @todo switch to injecting the MemoryBackend http://drupal.org/node/1903346 - \Drupal::getContainer()->set("cache.$this->cacheBin", new MemoryBackend(new MemoryTag(), $this->cacheBin)); + \Drupal::getContainer()->set("cache.$this->cacheBin", new MemoryBackend(new MemoryTagBackend(), $this->cacheBin)); // Create discovery objects to test. $this->emptyDiscovery = new StaticDiscovery(); diff --git a/core/tests/Drupal/Tests/Core/Cache/BackendChainImplementationUnitTest.php b/core/tests/Drupal/Tests/Core/Cache/BackendChainImplementationUnitTest.php index 8841720..7b36ce9 100644 --- a/core/tests/Drupal/Tests/Core/Cache/BackendChainImplementationUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Cache/BackendChainImplementationUnitTest.php @@ -10,7 +10,7 @@ use Drupal\Core\Cache\BackendChain; use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\MemoryBackend; -use Drupal\Core\Cache\MemoryTag; +use Drupal\Core\Cache\MemoryTagBackend; use Drupal\Tests\UnitTestCase; /** @@ -60,7 +60,7 @@ public function setUp() { parent::setUp(); // Set up three memory backends to be used in the chain. - $cache_tag = new MemoryTag(); + $cache_tag = new MemoryTagBackend(); $this->firstBackend = new MemoryBackend($cache_tag, 'foo'); $this->secondBackend = new MemoryBackend($cache_tag, 'bar'); $this->thirdBackend = new MemoryBackend($cache_tag, 'baz'); diff --git a/core/tests/Drupal/Tests/Core/Cache/CacheCollectorTest.php b/core/tests/Drupal/Tests/Core/Cache/CacheCollectorTest.php index 7740523..0b85e6d 100644 --- a/core/tests/Drupal/Tests/Core/Cache/CacheCollectorTest.php +++ b/core/tests/Drupal/Tests/Core/Cache/CacheCollectorTest.php @@ -29,7 +29,7 @@ class CacheCollectorTest extends UnitTestCase { /** * The cache tag backend to use. * - * @var \Drupal\Core\Cache\CacheTagInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Drupal\Core\Cache\CacheTagBackendInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $cacheTag; @@ -67,7 +67,7 @@ public static function getInfo() { */ protected function setUp() { $this->cache = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); - $this->cacheTag = $this->getMock('Drupal\Core\Cache\CacheTagInterface'); + $this->cacheTag = $this->getMock('Drupal\Core\Cache\CacheTagBackendInterface'); $this->lock = $this->getMock('Drupal\Core\Lock\LockBackendInterface'); $this->cid = $this->randomName(); $this->collector = new CacheCollectorHelper($this->cid, $this->cache, $this->lock); diff --git a/core/tests/Drupal/Tests/Core/Config/CachedStorageTest.php b/core/tests/Drupal/Tests/Core/Config/CachedStorageTest.php index 81a6248..a742bf7 100644 --- a/core/tests/Drupal/Tests/Core/Config/CachedStorageTest.php +++ b/core/tests/Drupal/Tests/Core/Config/CachedStorageTest.php @@ -2,12 +2,11 @@ namespace Drupal\Tests\Core\Config; -use Drupal\Core\Cache\MemoryTag; +use Drupal\Core\Cache\MemoryTagBackend; use Drupal\Tests\UnitTestCase; use Drupal\Core\Config\CachedStorage; use Drupal\Core\Cache\MemoryBackend; use Drupal\Core\Cache\NullBackend; -use Drupal\Core\Cache\CacheBackendInterface; /** * Tests the interaction of cache and file storage in CachedStorage. @@ -52,7 +51,7 @@ public function testListAllPrimedPersistentCache() { $storage->expects($this->never())->method('listAll'); $response = array("$prefix." . $this->randomName(), "$prefix." . $this->randomName()); - $cache = new MemoryBackend(new MemoryTag(), __FUNCTION__); + $cache = new MemoryBackend(new MemoryTagBackend(), __FUNCTION__); $cache->set('find:' . $prefix, $response); $cachedStorage = new CachedStorage($storage, $cache); $this->assertEquals($response, $cachedStorage->listAll($prefix)); @@ -76,7 +75,7 @@ public function testGetMultipleOnPrimedCache() { ); $storage = $this->getMock('Drupal\Core\Config\StorageInterface'); $storage->expects($this->never())->method('readMultiple'); - $cache = new MemoryBackend(new MemoryTag(), __FUNCTION__); + $cache = new MemoryBackend(new MemoryTagBackend(), __FUNCTION__); foreach ($configCacheValues as $key => $value) { $cache->set($key, $value); } @@ -103,7 +102,7 @@ public function testGetMultipleOnPartiallyPrimedCache() { 'foo' => 'bar', ), ); - $cache = new MemoryBackend(new MemoryTag(), __FUNCTION__); + $cache = new MemoryBackend(new MemoryTagBackend(), __FUNCTION__); foreach ($configCacheValues as $key => $value) { $cache->set($key, $value); } @@ -138,7 +137,7 @@ public function testGetMultipleOnPartiallyPrimedCache() { */ public function testReadNonExistentFileCacheMiss() { $name = 'config.does_not_exist'; - $cache = new MemoryBackend(new MemoryTag(), __FUNCTION__); + $cache = new MemoryBackend(new MemoryTagBackend(), __FUNCTION__); $storage = $this->getMock('Drupal\Core\Config\StorageInterface'); $storage->expects($this->once()) ->method('read') @@ -158,7 +157,7 @@ public function testReadNonExistentFileCacheMiss() { */ public function testReadNonExistentFileCached() { $name = 'config.does_not_exist'; - $cache = new MemoryBackend(new MemoryTag(), __FUNCTION__); + $cache = new MemoryBackend(new MemoryTagBackend(), __FUNCTION__); $cache->set($name, FALSE); $storage = $this->getMock('Drupal\Core\Config\StorageInterface'); diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php index 7ea1e3b..2c109dd 100644 --- a/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php @@ -68,7 +68,7 @@ class EntityManagerTest extends UnitTestCase { /** * The cache tag backend to use. * - * @var \Drupal\Core\Cache\CacheTagInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Drupal\Core\Cache\CacheTagBackendInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $cacheTag; @@ -118,7 +118,7 @@ protected function setUp() { $this->cache = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); - $this->cacheTag = $this->getMock('Drupal\Core\Cache\CacheTagInterface'); + $this->cacheTag = $this->getMock('Drupal\Core\Cache\CacheTagBackendInterface'); $this->languageManager = $this->getMockBuilder('Drupal\Core\Language\LanguageManager') ->disableOriginalConstructor() diff --git a/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php b/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php index e2816db..277bb1c 100644 --- a/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php +++ b/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php @@ -46,7 +46,7 @@ class ThemeHandlerTest extends UnitTestCase { /** * The mocked cache tag service. * - * @var \Drupal\Core\Cache\CacheTagInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Drupal\Core\Cache\CacheTagBackendInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $cacheTag; @@ -103,7 +103,7 @@ protected function setUp() { $this->configFactory = $this->getConfigFactoryStub(array('system.theme' => array(), 'system.theme.disabled' => array())); $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); $this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); - $this->cacheTag = $this->getMock('Drupal\Core\Cache\CacheTagInterface'); + $this->cacheTag = $this->getMock('Drupal\Core\Cache\CacheTagBackendInterface'); $this->infoParser = $this->getMock('Drupal\Core\Extension\InfoParserInterface'); $this->configInstaller = $this->getMock('Drupal\Core\Config\ConfigInstallerInterface'); $this->routeBuilder = $this->getMockBuilder('Drupal\Core\Routing\RouteBuilder') diff --git a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php index cf4692e..0cecfe9 100644 --- a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php +++ b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php @@ -161,7 +161,7 @@ public function testDefaultPluginManagerWithFilledCache() { */ public function testCacheClearWithTags() { $cid = $this->randomName(); - $memory_tag = $this->getMockBuilder('Drupal\Core\Cache\MemoryTag') + $memory_tag = $this->getMockBuilder('Drupal\Core\Cache\MemoryTagBackend') ->disableOriginalConstructor() ->getMock(); $memory_tag diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php index ba1b821..9de71a1 100644 --- a/core/tests/Drupal/Tests/UnitTestCase.php +++ b/core/tests/Drupal/Tests/UnitTestCase.php @@ -9,8 +9,7 @@ use Drupal\Component\Utility\Random; use Drupal\Component\Utility\String; -use Drupal\Core\Cache\CacheBackendInterface; -use Drupal\Core\Cache\CacheTagInterface; +use Drupal\Core\Cache\CacheTagBackendInterface; use Drupal\Core\DependencyInjection\ContainerBuilder; /** @@ -199,13 +198,13 @@ public function getStringTranslationStub() { /** * Sets up a container with cache bins. * - * @param \Drupal\Core\Cache\CacheTagInterface $backend + * @param \Drupal\Core\Cache\CacheTagBackendInterface $backend * The cache tag to set up. * * @return \Symfony\Component\DependencyInjection\ContainerInterface|\PHPUnit_Framework_MockObject_MockObject * The container with the cache bins set up. */ - protected function getContainerWithCacheTags(CacheTagInterface $backend) { + protected function getContainerWithCacheTags(CacheTagBackendInterface $backend) { $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); $container->expects($this->any()) ->method('getParameter')