Commit d7fc7b6a authored by catch's avatar catch

Issue #1393392 by c960657, fubhy: Convert prefix cache clears to cache tags,...

Issue #1393392 by c960657, fubhy: Convert prefix cache clears to cache tags, then remove support for them.
parent 40245a6b
......@@ -6,6 +6,7 @@
*/
use \InvalidArgumentException;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Entity\EntityFieldQuery;
use Drupal\Core\Entity\EntityMalformedException;
use Drupal\Core\Entity\EntityStorageException;
......@@ -83,7 +84,7 @@ function entity_get_info($entity_type = NULL) {
}
// Let other modules alter the entity info.
drupal_alter('entity_info', $entity_info);
cache()->set("entity_info:$langcode", $entity_info);
cache()->set("entity_info:$langcode", $entity_info, CacheBackendInterface::CACHE_PERMANENT, array('entity_info' => TRUE));
}
}
......@@ -101,7 +102,7 @@ function entity_get_info($entity_type = NULL) {
function entity_info_cache_clear() {
drupal_static_reset('entity_get_info');
// Clear all languages.
cache()->deletePrefix('entity_info:');
cache()->invalidateTags(array('entity_info' => TRUE));
}
/**
......
......@@ -5,6 +5,7 @@
* API for the Drupal menu system.
*/
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Template\Attribute;
/**
......@@ -1109,7 +1110,7 @@ function menu_tree_all_data($menu_name, $link = NULL, $max_depth = NULL) {
}
// Cache the tree building parameters using the page-specific cid.
cache('menu')->set($cid, $tree_parameters);
cache('menu')->set($cid, $tree_parameters, CacheBackendInterface::CACHE_PERMANENT, array('menu' => $menu_name));
}
// Build the tree using the parameters; the resulting tree will be cached
......@@ -1282,7 +1283,7 @@ function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail =
$tree_parameters['active_trail'] = $active_trail;
}
// Cache the tree building parameters using the page-specific cid.
cache('menu')->set($cid, $tree_parameters);
cache('menu')->set($cid, $tree_parameters, CacheBackendInterface::CACHE_PERMANENT, array('menu' => $menu_name));
}
// Build the tree using the parameters; the resulting tree will be cached
......@@ -1419,7 +1420,7 @@ function _menu_build_tree($menu_name, array $parameters = array()) {
menu_tree_collect_node_links($data['tree'], $data['node_links']);
// Cache the data, if it is not already in the cache.
cache('menu')->set($tree_cid, $data);
cache('menu')->set($tree_cid, $data, CacheBackendInterface::CACHE_PERMANENT, array('menu' => $menu_name));
$trees[$tree_cid] = $data;
}
......@@ -2608,7 +2609,7 @@ function menu_link_load($mlid) {
* Clears the cached cached data for a single named menu.
*/
function menu_cache_clear($menu_name = 'navigation') {
cache('menu')->deletePrefix('links:' . $menu_name . ':');
cache('menu')->invalidateTags(array('menu' => $menu_name));
// Also clear the menu system static caches.
menu_reset_static_cache();
}
......
......@@ -5,6 +5,7 @@
* Schema API handling functions.
*/
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Utility\SchemaCache;
......@@ -97,7 +98,7 @@ function drupal_get_complete_schema($rebuild = FALSE) {
cache()->set('schema', $schema);
}
if ($rebuild) {
cache()->deletePrefix('schema:');
cache()->invalidateTags(array('schema' => TRUE));
}
}
}
......
......@@ -8,8 +8,9 @@
* customized by user themes.
*/
use Drupal\Core\Utility\ThemeRegistry;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Utility\ThemeRegistry;
/**
* @defgroup content_flags Content markers
......@@ -332,7 +333,7 @@ function _theme_load_registry($theme, $base_theme = NULL, $theme_engine = NULL,
return $registry;
}
else {
return new ThemeRegistry('theme_registry:runtime:' . $theme->name, 'cache');
return new ThemeRegistry('theme_registry:runtime:' . $theme->name, 'cache', array('theme_registry' => TRUE));
}
}
......@@ -340,7 +341,7 @@ function _theme_load_registry($theme, $base_theme = NULL, $theme_engine = NULL,
* Write the theme_registry cache into the database.
*/
function _theme_save_registry($theme, $registry) {
cache()->set("theme_registry:$theme->name", $registry);
cache()->set("theme_registry:$theme->name", $registry, CacheBackendInterface::CACHE_PERMANENT, array('theme_registry' => TRUE));
}
/**
......@@ -350,7 +351,7 @@ function _theme_save_registry($theme, $registry) {
*/
function drupal_theme_rebuild() {
drupal_static_reset('theme_get_registry');
cache()->deletePrefix('theme_registry');
cache()->invalidateTags(array('theme_registry' => TRUE));
}
/**
......@@ -578,7 +579,7 @@ function _theme_build_registry($theme, $base_theme, $theme_engine) {
}
// Only cache this registry if all modules are loaded.
if (module_load_all(NULL)) {
cache()->set('theme_registry:build:modules', $cache);
cache()->set("theme_registry:build:modules", $cache, CacheBackendInterface::CACHE_PERMANENT, array('theme_registry' => TRUE));
}
}
......
......@@ -129,14 +129,6 @@ function delete($cid);
*/
function deleteMultiple(Array $cids);
/**
* Deletes items from the cache using a wildcard prefix.
*
* @param $prefix
* A wildcard prefix.
*/
function deletePrefix($prefix);
/**
* Flushes all cache items in a bin.
*/
......
......@@ -168,15 +168,6 @@ function deleteMultiple(array $cids) {
while (count($cids));
}
/**
* Implements Drupal\Core\Cache\CacheBackendInterface::deletePrefix().
*/
function deletePrefix($prefix) {
Database::getConnection()->delete($this->bin)
->condition('cid', Database::getConnection()->escapeLike($prefix) . '%', 'LIKE')
->execute();
}
/**
* Implements Drupal\Core\Cache\CacheBackendInterface::flush().
*/
......
......@@ -76,18 +76,6 @@ function deleteMultiple(array $cids) {
catch (Exception $e) {}
}
/**
* Overrides Drupal\Core\Cache\DatabaseBackend::deletePrefix().
*/
function deletePrefix($prefix) {
try {
if (class_exists('Drupal\Core\Database\Database')) {
parent::deletePrefix($prefix);
}
}
catch (Exception $e) {}
}
/**
* Overrides Drupal\Core\Cache\DatabaseBackend::invalidateTags().
*/
......
......@@ -135,17 +135,6 @@ public function deleteMultiple(array $cids) {
$this->cache = array_diff_key($this->cache, array_flip($cids));
}
/**
* Implements Drupal\Core\Cache\CacheBackendInterface::deletePrefix().
*/
public function deletePrefix($prefix) {
foreach ($this->cache as $cid => $item) {
if (strpos($cid, $prefix) === 0) {
unset($this->cache[$cid]);
}
}
}
/**
* Implements Drupal\Core\Cache\CacheBackendInterface::flush().
*/
......
......@@ -54,11 +54,6 @@ function delete($cid) {}
*/
function deleteMultiple(array $cids) {}
/**
* Implements Drupal\Core\Cache\CacheBackendInterface::deletePrefix().
*/
function deletePrefix($prefix) {}
/**
* Implements Drupal\Core\Cache\CacheBackendInterface::flush().
*/
......
......@@ -8,6 +8,7 @@
namespace Drupal\Core\Utility;
use ArrayAccess;
use Drupal\Core\Cache\CacheBackendInterface;
/**
* Provides a caching wrapper to be used in place of large array structures.
......@@ -67,35 +68,53 @@ abstract class CacheArray implements ArrayAccess {
/**
* A cid to pass to cache()->set() and cache()->get().
*
* @var string
*/
protected $cid;
/**
* A tags array to pass to cache()->set().
*
* @var array
*/
protected $tags;
/**
* A bin to pass to cache()->set() and cache()->get().
*
* @var string
*/
protected $bin;
/**
* An array of keys to add to the cache at the end of the request.
*
* @var array
*/
protected $keysToPersist = array();
/**
* Storage for the data itself.
*
* @var array
*/
protected $storage = array();
/**
* Constructs a DrupalCacheArray object.
*
* @param $cid
* @param string $cid
* The cid for the array being cached.
* @param $bin
* @param string $bin
* The bin to cache the array.
* @param array $tags
* (optional) The tags to specify for the cache item.
*/
public function __construct($cid, $bin) {
public function __construct($cid, $bin, $tags = array()) {
$this->cid = $cid;
$this->bin = $bin;
$this->tags = $tags;
if ($cached = cache($bin)->get($this->cid)) {
$this->storage = $cached->data;
......@@ -185,7 +204,7 @@ protected function set($data, $lock = TRUE) {
if ($cached = cache($this->bin)->get($this->cid)) {
$data = $cached->data + $data;
}
cache($this->bin)->set($this->cid, $data);
cache($this->bin)->set($this->cid, $data, CacheBackendInterface::CACHE_PERMANENT, $this->tags);
if ($lock) {
lock()->release($lock_name);
}
......
......@@ -19,7 +19,7 @@ class SchemaCache extends CacheArray {
*/
public function __construct() {
// Cache by request method.
parent::__construct('schema:runtime:' . ($_SERVER['REQUEST_METHOD'] == 'GET'), 'cache');
parent::__construct('schema:runtime:' . ($_SERVER['REQUEST_METHOD'] == 'GET'), 'cache', array('schema' => TRUE));
}
/**
......
......@@ -7,6 +7,8 @@
namespace Drupal\Core\Utility;
use Drupal\Core\Cache\CacheBackendInterface;
/**
* Builds the run-time theme registry.
*
......@@ -31,9 +33,20 @@ class ThemeRegistry extends CacheArray {
*/
protected $completeRegistry;
function __construct($cid, $bin) {
/**
* Constructs a ThemeRegistry object.
*
* @param string $cid
* The cid for the array being cached.
* @param string $bin
* The bin to cache the array.
* @param array $tags
* (optional) The tags to specify for the cache item.
*/
function __construct($cid, $bin, $tags) {
$this->cid = $cid;
$this->bin = $bin;
$this->tags = $tags;
$this->persistable = module_load_all(NULL) && $_SERVER['REQUEST_METHOD'] == 'GET';
$data = array();
......@@ -109,7 +122,7 @@ public function set($data, $lock = TRUE) {
$registry = $this->initializeRegistry();
$data = array_merge($registry, $data);
}
cache($this->bin)->set($this->cid, $data);
cache($this->bin)->set($this->cid, $data, CacheBackendInterface::CACHE_PERMANENT, $this->tags);
if ($lock) {
lock()->release($lock_name);
}
......
......@@ -30,6 +30,8 @@ function _field_info_field_cache() {
return $info;
}
use Drupal\Core\Cache\CacheBackendInterface;
/**
* @defgroup field_info Field Info API
* @{
......@@ -159,7 +161,7 @@ function _field_info_collate_types() {
}
drupal_alter('field_storage_info', $info['storage types']);
cache('field')->set("field_info_types:$langcode", $info);
cache('field')->set("field_info_types:$langcode", $info, CacheBackendInterface::CACHE_PERMANENT, array('field_info_types' => TRUE));
}
}
......@@ -172,7 +174,7 @@ function _field_info_collate_types() {
function _field_info_collate_types_reset() {
drupal_static_reset('_field_info_collate_types');
// Clear all languages.
cache('field')->deletePrefix('field_info_types:');
cache('field')->invalidateTags(array('field_info_types' => TRUE));
}
/**
......
......@@ -7,6 +7,8 @@
namespace Drupal\field;
use Drupal\Core\Cache\CacheBackendInterface;
/**
* Provides field and instance definitions for the current runtime environment.
*
......@@ -110,7 +112,7 @@ public function flush() {
$this->bundleExtraFields = array();
cache('field')->deletePrefix('field_info:');
cache('field')->invalidateTags(array('field_info' => TRUE));
}
/**
......@@ -155,7 +157,7 @@ public function getFieldMap() {
// Save in "static" and persistent caches.
$this->fieldMap = $map;
cache('field')->set('field_info:field_map', $map);
cache('field')->set('field_info:field_map', $map, CacheBackendInterface::CACHE_PERMANENT, array('field_info' => TRUE));
return $map;
}
......@@ -183,7 +185,7 @@ public function getFields() {
}
// Store in persistent cache.
cache('field')->set('field_info:fields', $this->fieldsById);
cache('field')->set('field_info:fields', $this->fieldsById, CacheBackendInterface::CACHE_PERMANENT, array('field_info' => TRUE));
}
// Fill the name/ID map.
......@@ -234,7 +236,7 @@ public function getInstances($entity_type = NULL) {
}
// Store in persistent cache.
cache('field')->set('field_info:instances', $this->bundleInstances);
cache('field')->set('field_info:instances', $this->bundleInstances, CacheBackendInterface::CACHE_PERMANENT, array('field_info' => TRUE));
}
$this->loadedAllInstances = TRUE;
......@@ -415,7 +417,7 @@ public function getBundleInstances($entity_type, $bundle) {
foreach ($instances as $instance) {
$cache['fields'][] = $this->fieldsById[$instance['field_id']];
}
cache('field')->set("field_info:bundle:$entity_type:$bundle", $cache);
cache('field')->set("field_info:bundle:$entity_type:$bundle", $cache, CacheBackendInterface::CACHE_PERMANENT, array('field_info' => TRUE));
return $instances;
}
......@@ -456,7 +458,7 @@ public function getBundleExtraFields($entity_type, $bundle) {
// Store in the 'static' and persistent caches.
$this->bundleExtraFields[$entity_type][$bundle] = $info;
cache('field')->set("field_info:bundle_extra:$entity_type:$bundle", $info);
cache('field')->set("field_info:bundle_extra:$entity_type:$bundle", $info, CacheBackendInterface::CACHE_PERMANENT, array('field_info' => TRUE));
return $this->bundleExtraFields[$entity_type][$bundle];
}
......
......@@ -4,6 +4,7 @@
* @file
* Framework for handling the filtering of content.
*/
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Template\Attribute;
/**
......@@ -285,7 +286,7 @@ function filter_format_save($format) {
$return = SAVED_UPDATED;
// Clear the filter cache whenever a text format is updated.
cache('filter')->deletePrefix($format->format . ':');
cache('filter')->invalidateTags(array('filter_format' => $format->format));
}
filter_formats_reset();
......@@ -315,7 +316,7 @@ function filter_format_disable($format) {
// Clear the filter cache whenever a text format is disabled.
filter_formats_reset();
cache('filter')->deletePrefix($format->format . ':');
cache('filter')->invalidateTags(array('filter_format' => $format->format));
}
/**
......@@ -439,7 +440,7 @@ function filter_formats($account = NULL) {
->execute()
->fetchAllAssoc('format');
cache()->set("filter_formats:{$language_interface->langcode}", $formats['all']);
cache()->set("filter_formats:{$language_interface->langcode}", $formats['all'], CacheBackendInterface::CACHE_PERMANENT, array('filter_formats' => TRUE));
}
}
......@@ -462,8 +463,8 @@ function filter_formats($account = NULL) {
* @see filter_formats()
*/
function filter_formats_reset() {
cache()->deletePrefix('filter_formats');
cache()->deletePrefix('filter_list_format');
cache()->invalidateTags(array('filter_formats' => TRUE));
cache()->delete('filter_list_format');
drupal_static_reset('filter_list_format');
drupal_static_reset('filter_formats');
}
......@@ -810,7 +811,7 @@ function check_markup($text, $format_id = NULL, $langcode = '', $cache = FALSE)
// automatically flushed when the text format is updated.
// @see filter_format_save()
if ($cache) {
cache('filter')->set($cache_id, $text);
cache('filter')->set($cache_id, $text, CacheBackendInterface::CACHE_PERMANENT, array('filter_format' => $format->format));
}
return $text;
......
......@@ -37,7 +37,7 @@ public function __construct($langcode, $context) {
// example, strings for admin menu items and settings forms are not cached
// for anonymous users.
$rids = implode(':', array_keys($GLOBALS['user']->roles));
parent::__construct("locale:$langcode:$context:$rids", 'cache');
parent::__construct("locale:$langcode:$context:$rids", 'cache', array('locale' => TRUE));
}
/**
......
......@@ -543,7 +543,7 @@ function locale_translate_batch_finished($success, $results) {
// Clear cache and force refresh of JavaScript translations.
_locale_invalidate_js();
cache()->deletePrefix('locale:');
cache()->invalidateTags(array('locale' => TRUE));
}
}
......
......@@ -444,7 +444,7 @@ function locale_translate_edit_form_submit($form, &$form_state) {
// Force JavaScript translation file recreation for this language.
_locale_invalidate_js($langcode);
// Clear locale cache.
cache()->deletePrefix('locale:');
cache()->invalidateTags(array('locale' => TRUE));
}
/**
......
......@@ -10,6 +10,7 @@
use Symfony\Component\HttpFoundation\Response;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Database\Query\SelectExtender;
use Drupal\Core\Database\Query\SelectInterface;
......@@ -868,7 +869,7 @@ function _node_types_build($rebuild = FALSE) {
asort($_node_types->names);
cache()->set($cid, $_node_types);
cache()->set($cid, $_node_types, CacheBackendInterface::CACHE_PERMANENT, array('node_types' => TRUE));
return $_node_types;
}
......@@ -877,7 +878,7 @@ function _node_types_build($rebuild = FALSE) {
* Clears the node type cache.
*/
function node_type_cache_reset() {
cache()->deletePrefix('node_types:');
cache()->invalidateTags(array('node_types' => TRUE));
drupal_static_reset('_node_types_build');
}
......
......@@ -335,41 +335,6 @@ public function testDeleteMultiple() {
$this->assertIdentical(FALSE, $backend->get('test21'), "Cache id test21 does not exist.");
}
/**
* Test Drupal\Core\Cache\CacheBackendInterface::deletePrefix().
*/
public function testDeletePrefix() {
$backend = $this->getCacheBackend();
// Set numerous testing keys.
$backend->set('banana_test1', 1);
$backend->set('monkey_test2', 3);
$backend->set('monkey_banana_test3', 5);
$backend->set('banana_test_4', 7);
$backend->set('pony_monkey_test5_banana', 11);
$backend->set('monkey_test6', 13);
$backend->set('banana_pony_test7_monkey', 17);
$backend->deletePrefix('banana');
// Keys starting with banana have been deleted.
$this->assertIdentical(FALSE, $backend->get('banana_test1'), "Cache id banana_test1 deleted.");
$this->assertIdentical(FALSE, $backend->get('banana_test_4'), "Cache id banana_test_4 deleted.");
$this->assertIdentical(FALSE, $backend->get('banana_pony_test7_monkey'), "Cache id banana_pony_test7_monkey deleted.");
// Keys not starting with banana still exist.
$this->assertNotIdentical(FALSE, $backend->get('monkey_test2'), "Cache id monkey_test2 exists.");
$this->assertNotIdentical(FALSE, $backend->get('monkey_banana_test3'), "Cache id monkey_banana_test3 exists.");
$this->assertNotIdentical(FALSE, $backend->get('pony_monkey_test5_banana'), "Cache id poney_monkey_test5_banana exists.");
$this->assertNotIdentical(FALSE, $backend->get('monkey_test6'), "Cache id monkey_test6 exists.");
$backend->deletePrefix('monkey');
// Keys starting with monkey have been deleted.
$this->assertIdentical(FALSE, $backend->get('monkey_test2'), "Cache id monkey_test2 deleted.");
$this->assertIdentical(FALSE, $backend->get('monkey_banana_test3'), "Cache id monkey_banana_test3 deleted.");
$this->assertIdentical(FALSE, $backend->get('banana_pony_test7_monkey'), "Cache id banana_pony_test7_monkey deleted.");
// Keys not starting with monkey still exist.
$this->assertNotIdentical(FALSE, $backend->get('pony_monkey_test5_banana'), "Cache id pony_monkey_test5_banana exists.");
}
/**
* Test Drupal\Core\Cache\CacheBackendInterface::flush().
*/
......
......@@ -78,17 +78,6 @@ function testCacheInstall() {
$this->assertFalse($database_cache->get('cache_one'));
$this->assertFalse($database_cache->get('cache_two'));
// Store multiple items in the database cache, then use the installer's
// cache backend to delete them via a wildcard prefix. Afterwards, confirm
// that they are no longer in the database cache.
$database_cache->set('cache_one', 'One');
$database_cache->set('cache_two', 'Two');
$this->assertEqual($database_cache->get('cache_one')->data, 'One');
$this->assertEqual($database_cache->get('cache_two')->data, 'Two');
$install_cache->deletePrefix('cache_');
$this->assertFalse($database_cache->get('cache_one'));
$this->assertFalse($database_cache->get('cache_two'));
// Store multiple items in the database cache, then use the installer's
// cache backend to flush the cache. Afterwards, confirm that they are no
// longer in the database cache.
......@@ -117,7 +106,6 @@ function testCacheInstall() {
$install_cache->isEmpty();
$install_cache->delete('cache_one');
$install_cache->deleteMultiple(array('cache_one', 'cache_two'));
$install_cache->deletePrefix('cache_');
$install_cache->flush();
$install_cache->expire();
$install_cache->garbageCollection();
......
......@@ -40,7 +40,7 @@ function testRaceCondition() {
// Directly instantiate the theme registry, this will cause a base cache
// entry to be written in __construct().
$registry = new ThemeRegistry($cid, 'cache');
$registry = new ThemeRegistry($cid, 'cache', array('theme_registry' => TRUE));
$this->assertTrue(cache()->get($cid), 'Cache entry was created.');
......@@ -60,7 +60,7 @@ function testRaceCondition() {
// Create a new instance of the class. Confirm that both the offset
// requested previously, and one that has not yet been requested are both
// available.
$registry = new ThemeRegistry($cid, 'cache');
$registry = new ThemeRegistry($cid, 'cache', array('theme_registry' => TRUE));
$this->assertTrue($registry['theme_test_template_test'], 'Offset was returned correctly from the theme registry');
$this->assertTrue($registry['theme_test_template_test_2'], 'Offset was returned correctly from the theme registry');
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment