From 66dce233c83b41ccd3c77a9bab926298f5ffd608 Mon Sep 17 00:00:00 2001
From: Bob Vincent <bobvin@pillars.net>
Date: Sun, 2 Oct 2011 00:17:51 -0400
Subject: [PATCH] Issue #1272706 by cache: Remove backwards compatibility
 layer from cache API.

---
 includes/cache.inc                  |  324 +++++++----------------------------
 includes/menu.inc                   |   12 +--
 includes/module.inc                 |    8 +-
 includes/theme.inc                  |    2 +-
 modules/field/field.attach.inc      |    2 +-
 modules/simpletest/tests/cache.test |    2 +-
 modules/system/system.install       |    2 +-
 modules/update/update.module        |    8 +-
 8 files changed, 79 insertions(+), 281 deletions(-)

diff --git a/includes/cache.inc b/includes/cache.inc
index caa5c032db70d59e68c42e327b4d00f111e3352c..3a9b818bd101f832bf35569b738f101c1a1c3d09 100644
--- a/includes/cache.inc
+++ b/includes/cache.inc
@@ -1,25 +1,41 @@
 <?php
 
 /**
- * Factory for instantiating and statically caching the correct class for a cache bin.
+ * Factory for instantiating and statically caching the class for a cache bin.
  *
  * By default, this returns an instance of the DrupalDatabaseCache class.
- * Classes implementing DrupalCacheInterface can register themselves both as a
- * default implementation and for specific bins.
+ * Classes implementing DrupalCacheInterface can be used instead, either as a
+ * default for all cache requests, or for specific bins.
  *
- * @see DrupalCacheInterface
+ * Configuration of cache bins should be done in settings.php
+ *
+ * For example, to use "MyCustomCache" for the "page" bin, set the following
+ * variables:
+ *
+ * @code
+ * $conf['cache_backends'] = array(
+ *  'DrupalDatabaseCache' => 'includes/cache.inc',
+ *  'MyCustomCache' => 'sites/all/modules/mycustomcache/MyCustomCache.inc',
+ * );
+ * $conf['cache_class_page'] = 'MyCustomCache',
+ * @endcode
+ *
+ * Additionally, you can register your cache implementation to be used by
+ * default for all cache bins by setting the variable "cache_default_class" to
+ * the name of your implementation of the DrupalCacheInterface.  For example:
+ *
+ * @code
+ * $conf['cache_default_class'] = 'MyCustomCache';
+ * @endcode
  *
  * @param $bin
  *   The cache bin for which the cache object should be returned, defaults to
  *   'cache'.
+ *
  * @return DrupalCacheInterface
  *   The cache object associated with the specified bin.
  */
 function cache($bin = 'cache') {
-  // Temporary backwards compatibiltiy layer, allow old style prefixed cache
-  // bin names to be passed as arguments.
-  $bin = str_replace('cache_', '', $bin);
-
   $cache_objects = &drupal_static('cache_objects', array());
 
   if (!isset($cache_objects[$bin])) {
@@ -33,195 +49,24 @@ function cache($bin = 'cache') {
 }
 
 /**
- * Return data from the persistent cache
- *
- * Data may be stored as either plain text or as serialized data. cache_get
- * will automatically return unserialized objects and arrays.
- *
- * @param $cid
- *   The cache ID of the data to retrieve.
- * @param $bin
- *   The cache bin to store the data in. Valid core values are 'cache_block',
- *   'cache_bootstrap', 'cache_field', 'cache_filter', 'cache_form',
- *   'cache_menu', 'cache_page', 'cache_path', 'cache_update' or 'cache' for
- *   the default cache.
- *
- * @return
- *   The cache or FALSE on failure.
+ * Expire temporary items from the page and block caches.
  */
-function cache_get($cid, $bin = 'cache') {
-  return cache($bin)->get($cid);
-}
-
-/**
- * Return data from the persistent cache when given an array of cache IDs.
- *
- * @param $cids
- *   An array of cache IDs for the data to retrieve. This is passed by
- *   reference, and will have the IDs successfully returned from cache removed.
- * @param $bin
- *   The cache bin where the data is stored.
- * @return
- *   An array of the items successfully returned from cache indexed by cid.
- */
-function cache_get_multiple(array &$cids, $bin = 'cache') {
-  return cache($bin)->getMultiple($cids);
-}
-
-/**
- * Store data in the persistent cache.
- *
- * The persistent cache is split up into several cache bins. In the default
- * cache implementation, each cache bin corresponds to a database table by the
- * same name. Other implementations might want to store several bins in data
- * structures that get flushed together. While it is not a problem for most
- * cache bins if the entries in them are flushed before their expire time, some
- * might break functionality or are extremely expensive to recalculate. These
- * will be marked with a (*). The other bins expired automatically by core.
- * Contributed modules can add additional bins and get them expired
- * automatically by implementing hook_flush_caches().
- *
- *  - cache: Generic cache storage bin (used for variables, theme registry,
- *  locale date, list of simpletest tests etc).
- *
- *  - cache_block: Stores the content of various blocks.
- *
- *  - cache field: Stores the field data belonging to a given object.
- *
- *  - cache_filter: Stores filtered pieces of content.
- *
- *  - cache_form(*): Stores multistep forms. Flushing this bin means that some
- *  forms displayed to users lose their state and the data already submitted
- *  to them.
- *
- *  - cache_menu: Stores the structure of visible navigation menus per page.
- *
- *  - cache_page: Stores generated pages for anonymous users. It is flushed
- *  very often, whenever a page changes, at least for every ode and comment
- *  submission. This is the only bin affected by the page cache setting on
- *  the administrator panel.
- *
- *  - cache path: Stores the system paths that have an alias.
- *
- *  - cache update(*): Stores available releases. The update server (for
- *  example, drupal.org) needs to produce the relevant XML for every project
- *  installed on the current site. As this is different for (almost) every
- *  site, it's very expensive to recalculate for the update server.
- *
- * The reasons for having several bins are as follows:
- *
- * - smaller bins mean smaller database tables and allow for faster selects and
- *   inserts
- * - we try to put fast changing cache items and rather static ones into
- *   different bins. The effect is that only the fast changing bins will need a
- *   lot of writes to disk. The more static bins will also be better cacheable
- *   with MySQL's query cache.
- *
- * @param $cid
- *   The cache ID of the data to store.
- * @param $data
- *   The data to store in the cache. Complex data types will be automatically
- *   serialized before insertion.
- *   Strings will be stored as plain text and not serialized.
- * @param $bin
- *   The cache bin to store the data in. Valid core values are 'cache_block',
- *   'cache_bootstrap', 'cache_field', 'cache_filter', 'cache_form',
- *   'cache_menu', 'cache_page', 'cache_update' or 'cache' for the default
- *   cache.
- * @param $expire
- *   One of the following values:
- *   - CACHE_PERMANENT: Indicates that the item should never be removed unless
- *     explicitly told to using cache_clear_all() with a cache ID.
- *   - CACHE_TEMPORARY: Indicates that the item should be removed at the next
- *     general cache wipe.
- *   - A Unix timestamp: Indicates that the item should be kept at least until
- *     the given time, after which it behaves like CACHE_TEMPORARY.
- */
-function cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) {
-  return cache($bin)->set($cid, $data, $expire);
-}
-
-/**
- * Expire data from the cache.
- *
- * If called without arguments, expirable entries will be cleared from the
- * cache_page and cache_block bins.
- *
- * @param $cid
- *   If set, the cache ID to delete. Otherwise, all cache entries that can
- *   expire are deleted.
- *
- * @param $bin
- *   If set, the bin $bin to delete from. Mandatory
- *   argument if $cid is set.
- *
- * @param $wildcard
- *   If $wildcard is TRUE, cache IDs starting with $cid are deleted in
- *   addition to the exact cache ID specified by $cid.  If $wildcard is
- *   TRUE and $cid is '*' then the entire bin $bin is emptied.
- */
-function cache_clear_all($cid = NULL, $bin = NULL, $wildcard = FALSE) {
-  if (!isset($cid) && !isset($bin)) {
-    // Clear the block cache first, so stale data will
-    // not end up in the page cache.
-    if (module_exists('block')) {
-      cache('block')->expire();
-    }
-    cache('page')->expire();
-    return;
+function cache_clear_all() {
+  if (module_exists('block')) {
+    // Clear the block cache first, so stale data will not end up in the page
+    // cache.
+    cache('block')->expire();
   }
-  return cache($bin)->clear($cid, $wildcard);
+  cache('page')->expire();
 }
 
 /**
- * Check if a cache bin is empty.
- *
- * A cache bin is considered empty if it does not contain any valid data for any
- * cache ID.
- *
- * @param $bin
- *   The cache bin to check.
- * @return
- *   TRUE if the cache bin specified is empty.
- */
-function cache_is_empty($bin) {
-  return cache($bin)->isEmpty();
-}
-
-/**
- * Interface for cache implementations.
+ * Provides the interface for cache implementations.
  *
  * All cache implementations have to implement this interface.
- * DrupalDatabaseCache provides the default implementation, which can be
+ * DrupalDatabaseCache provides the default implementation, which may be
  * consulted as an example.
  *
- * To make Drupal use your implementation for a certain cache bin, you have to
- * set a variable with the name of the cache bin as its key and the name of
- * your class as its value. For example, if your implementation of
- * DrupalCacheInterface was called MyCustomCache, the following line would make
- * Drupal use it for the 'cache_page' bin:
- * @code
- *  variable_set('cache_class_cache_page', 'MyCustomCache');
- * @endcode
- *
- * Additionally, you can register your cache implementation to be used by
- * default for all cache bins by setting the variable 'cache_default_class' to
- * the name of your implementation of the DrupalCacheInterface, e.g.
- * @code
- *  variable_set('cache_default_class', 'MyCustomCache');
- * @endcode
- *
- * To implement a completely custom cache bin, use the same variable format:
- * @code
- *  variable_set('cache_class_custom_bin', 'MyCustomCache');
- * @endcode
- * To access your custom cache bin, specify the name of the bin when storing
- * or retrieving cached data:
- * @code
- *  cache_set($cid, $data, 'custom_bin', $expire);
- *  cache_get($cid, 'custom_bin');
- * @endcode
- *
  * @see cache()
  * @see DrupalDatabaseCache
  */
@@ -235,38 +80,40 @@ interface DrupalCacheInterface {
   function __construct($bin);
 
   /**
-   * Return data from the persistent cache. Data may be stored as either plain
-   * text or as serialized data. cache_get will automatically return
-   * unserialized objects and arrays.
+   * Returns data from the persistent cache. Data may be stored as either plain
+   * text or as serialized data. Will automatically return unserialized objects
+   * and arrays.
    *
    * @param $cid
    *   The cache ID of the data to retrieve.
+   *
    * @return
    *   The cache or FALSE on failure.
    */
   function get($cid);
 
   /**
-   * Return data from the persistent cache when given an array of cache IDs.
+   * Returns data from the persistent cache when given an array of cache IDs.
    *
    * @param $cids
    *   An array of cache IDs for the data to retrieve. This is passed by
    *   reference, and will have the IDs successfully returned from cache
    *   removed.
+   *
    * @return
    *   An array of the items successfully returned from cache indexed by cid.
    */
    function getMultiple(&$cids);
 
   /**
-   * Store data in the persistent cache.
+   * Stores data in the persistent cache.
    *
    * @param $cid
    *   The cache ID of the data to store.
    * @param $data
    *   The data to store in the cache. Complex data types will be automatically
-   *   serialized before insertion.
-   *   Strings will be stored as plain text and not serialized.
+   *   serialized before insertion. Strings will be stored as plain text and not
+   *   serialized.
    * @param $expire
    *   One of the following values:
    *   - CACHE_PERMANENT: Indicates that the item should never be removed unless
@@ -279,7 +126,7 @@ interface DrupalCacheInterface {
   function set($cid, $data, $expire = CACHE_PERMANENT);
 
   /**
-   * Delete an item from the cache.
+   * Deletes an item from the cache.
    *
    * @param $cid
    *    The cache ID to delete.
@@ -287,7 +134,7 @@ interface DrupalCacheInterface {
   function delete($cid);
 
   /**
-   * Delete multiple items from the cache.
+   * Deletes multiple items from the cache.
    *
    * @param $cids
    *   An array of $cids to delete.
@@ -295,7 +142,7 @@ interface DrupalCacheInterface {
   function deleteMultiple(Array $cids);
 
   /**
-   * Delete items from the cache using a wildcard prefix.
+   * Deletes items from the cache using a wildcard prefix.
    *
    * @param $prefix
    *   A wildcard prefix.
@@ -303,45 +150,28 @@ interface DrupalCacheInterface {
   function deletePrefix($prefix);
 
   /**
-   * Flush all cache items in a bin.
+   * Flushes all cache items in a bin.
    */
   function flush();
 
   /**
-   * Expire temporary items from cache.
+   * Expires temporary items from cache.
    */
   function expire();
 
   /**
-   * Perform garbage collection on a cache bin.
+   * Performs garbage collection on a cache bin.
    */
   function garbageCollection();
 
   /**
-   * Expire data from the cache. If called without arguments, expirable
-   * entries will be cleared from the cache_page and cache_block bins.
-   *
-   * @param $cid
-   *   If set, the cache ID to delete. Otherwise, all cache entries that can
-   *   expire are deleted.
-   * @param $wildcard
-   *   If set to TRUE, the $cid is treated as a substring
-   *   to match rather than a complete ID. The match is a right hand
-   *   match. If '*' is given as $cid, the bin $bin will be emptied.
-   *
-   * @todo: this method is deprecated, as it's functionality is covered by
-   * more targeted methods in the interface.
-   */
-  function clear($cid = NULL, $wildcard = FALSE);
-
-  /**
-   * Check if a cache bin is empty.
+   * Checks whether a cache bin is empty.
    *
    * A cache bin is considered empty if it does not contain any valid data for
    * any cache ID.
    *
    * @return
-   *   TRUE if the cache bin specified is empty.
+   *   TRUE if the cache bin specified is empty; FALSE otherwise.
    */
   function isEmpty();
 }
@@ -391,7 +221,7 @@ class DrupalNullCache implements DrupalCacheInterface {
 }
 
 /**
- * Default cache implementation.
+ * Provides the default cache implementation.
  *
  * This is Drupal's default cache implementation. It uses the database to store
  * cached data. Each cache bin corresponds to a database table by the same name.
@@ -400,8 +230,8 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
   protected $bin;
 
   function __construct($bin) {
-    // All cache tables should be prefixed with 'cache_', apart from the
-    // default 'cache' bin, which would look silly.
+    // All cache tables should be prefixed with 'cache_', except for the
+    // default 'cache' bin.
     if ($bin != 'cache') {
       $bin = 'cache_' . $bin;
     }
@@ -445,13 +275,14 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
   }
 
   /**
-   * Prepare a cached item.
+   * Prepares a cached item.
    *
    * Checks that items are either permanent or did not expire, and unserializes
    * data as appropriate.
    *
    * @param $cache
-   *   An item loaded from cache_get() or cache_get_multiple().
+   *   An item loaded from DrupalDatabaseCache::get() or
+   *   DrupalDatabaseCache::getMultiple().
    * @return
    *   The item with data unserialized as appropriate or FALSE if there is no
    *   valid item to load.
@@ -465,9 +296,9 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
     // If enforcing a minimum cache lifetime, validate that the data is
     // currently valid for this user before we return it by making sure the cache
     // entry was created before the timestamp in the current session's cache
-    // timer. The cache variable is loaded into the $user object by _drupal_session_read()
-    // in session.inc. If the data is permanent or we're not enforcing a minimum
-    // cache lifetime always return the cached data.
+    // timer. The cache variable is loaded into the $user object by
+    // _drupal_session_read() in session.inc. If the data is permanent or we're
+    // not enforcing a minimum cache lifetime always return the cached data.
     if ($cache->expire != CACHE_PERMANENT && variable_get('cache_lifetime', 0) && $user->cache > $cache->created) {
       // This cache data is too old and thus not valid for us, ignore it.
       return FALSE;
@@ -502,7 +333,7 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
         ->execute();
     }
     catch (Exception $e) {
-      // The database may not be available, so we'll ignore cache_set requests.
+      // The database may not be available, so we'll ignore these calls.
     }
   }
 
@@ -542,12 +373,12 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
 
       $cache_flush = variable_get('cache_flush_' . $this->bin, 0);
       if ($cache_flush == 0) {
-        // This is the first request to clear the cache, start a timer.
+        // This is the first request to clear the cache; start a timer.
         variable_set('cache_flush_' . $this->bin, REQUEST_TIME);
       }
       elseif (REQUEST_TIME > ($cache_flush + variable_get('cache_lifetime', 0))) {
-        // Clear the cache for everyone, cache_lifetime seconds have
-        // passed since the first request to clear the cache.
+        // Clear the cache for everyone; cache_lifetime seconds have passed
+        // since the first request to clear the cache.
         db_delete($this->bin)
           ->condition('expire', CACHE_PERMANENT, '<>')
           ->condition('expire', REQUEST_TIME, '<')
@@ -556,7 +387,7 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
       }
     }
     else {
-      // No minimum cache lifetime, flush all temporary cache entries now.
+      // No minimum cache lifetime; flush all temporary cache entries now.
       db_delete($this->bin)
         ->condition('expire', CACHE_PERMANENT, '<>')
         ->condition('expire', REQUEST_TIME, '<')
@@ -571,7 +402,8 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
     // often since this will remove temporary cache items indiscriminately.
     $cache_flush = variable_get('cache_flush_' . $this->bin, 0);
     if ($cache_flush && ($cache_flush + variable_get('cache_lifetime', 0) <= REQUEST_TIME)) {
-      // Reset the variable immediately to prevent a meltdown in heavy load situations.
+      // Reset the variable immediately to prevent a meltdown in heavy load
+      // situations.
       variable_set('cache_flush_' . $this->bin, 0);
       // Time to flush old cache data
       db_delete($this->bin)
@@ -581,30 +413,6 @@ class DrupalDatabaseCache implements DrupalCacheInterface {
     }
   }
 
-  function clear($cid = NULL, $wildcard = FALSE) {
-    global $user;
-
-    if (empty($cid)) {
-      $this->expire();
-    }
-    else {
-      if ($wildcard) {
-        if ($cid == '*') {
-          $this->flush();
-        }
-        else {
-          $this->deletePrefix($cid);
-        }
-      }
-      elseif (is_array($cid)) {
-        $this->deleteMultiple($cid);
-      }
-      else {
-        $this->delete($cid);
-      }
-    }
-  }
-
   function isEmpty() {
     $this->garbageCollection();
     $query = db_select($this->bin);
diff --git a/includes/menu.inc b/includes/menu.inc
index f23eb0d4dff292089445e74eff07ed02e6708708..04c331e1de2080eb6308df108ff396b2db05a218 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -2574,17 +2574,7 @@ function menu_link_load($mlid) {
  * Clears the cached cached data for a single named menu.
  */
 function menu_cache_clear($menu_name = 'navigation') {
-  $cache_cleared = &drupal_static(__FUNCTION__, array());
-
-  if (empty($cache_cleared[$menu_name])) {
-    cache('menu')->deletePrefix('links:' . $menu_name . ':');
-    $cache_cleared[$menu_name] = 1;
-  }
-  elseif ($cache_cleared[$menu_name] == 1) {
-    drupal_register_shutdown_function('cache_clear_all', 'links:' . $menu_name . ':', 'cache_menu', TRUE);
-    $cache_cleared[$menu_name] = 2;
-  }
-
+  cache('menu')->deletePrefix('links:' . $menu_name . ':');
   // Also clear the menu system static caches.
   menu_reset_static_cache();
 }
diff --git a/includes/module.inc b/includes/module.inc
index e20e164a173cd3c1cc1603776f7e986fccd3552c..6c74780f7ce4d47387ad523e601b604597c09c32 100644
--- a/includes/module.inc
+++ b/includes/module.inc
@@ -700,10 +700,10 @@ function module_implements_reset() {
   // request. Benchmarks show that the benefit of this caching outweighs the
   // additional database hit even when using the default database caching
   // backend and only a small number of modules are enabled. The cost of the
-  // cache_get() is more or less constant and reduced further when non-database
-  // caching backends are used, so there will be more significant gains when a
-  // large number of modules are installed or hooks invoked, since this can
-  // quickly lead to module_hook() being called several thousand times
+  // cache('bootstrap')->get() is more or less constant and reduced further when
+  // non-database caching backends are used, so there will be more significant
+  // gains when a large number of modules are installed or hooks invoked, since
+  // this can quickly lead to module_hook() being called several thousand times
   // per request.
   drupal_static_reset('module_implements');
   cache('bootstrap')->set('module_implements', array());
diff --git a/includes/theme.inc b/includes/theme.inc
index 6b8b2715d9604f18ece6623adf0a30fc5b3b8283..a81125a8772cbdda0ec41a08aed44dc1d976fc03 100644
--- a/includes/theme.inc
+++ b/includes/theme.inc
@@ -528,7 +528,7 @@ function _theme_build_registry($theme, $base_theme, $theme_engine) {
   // serve as the basic registry. Since the list of enabled modules is the same
   // regardless of the theme used, this is cached in its own entry to save
   // building it for every theme.
-  if ($cached = cache_get('theme_registry:build:modules')) {
+  if ($cached = cache()->get('theme_registry:build:modules')) {
     $cache = $cached->data;
   }
   else {
diff --git a/modules/field/field.attach.inc b/modules/field/field.attach.inc
index c643e401662872e6d90e7a04a64fa8b3e0b1cdfd..8bccc54edce5bbefd9c1ef795bbfb94543961d28 100644
--- a/modules/field/field.attach.inc
+++ b/modules/field/field.attach.inc
@@ -634,7 +634,7 @@ function field_attach_load($entity_type, $entities, $age = FIELD_LOAD_CURRENT, $
     foreach ($entities as $id => $entity) {
       $cids[] = "field:$entity_type:$id";
     }
-    $cache = cache_get_multiple($cids, 'cache_field');
+    $cache = cache('field')->getMultiple($cids);
     // Put the cached field values back into the entities and remove them from
     // the list of entities to query.
     foreach ($entities as $id => $entity) {
diff --git a/modules/simpletest/tests/cache.test b/modules/simpletest/tests/cache.test
index 664247b8ab58b7576606c4c3813c1b2490f9cf1b..7f46e3983b1fb94ef77e6c7290c9b562c24deb50 100644
--- a/modules/simpletest/tests/cache.test
+++ b/modules/simpletest/tests/cache.test
@@ -1,7 +1,7 @@
 <?php
 
 class CacheTestCase extends DrupalWebTestCase {
-  protected $default_bin = 'cache_page';
+  protected $default_bin = 'page';
   protected $default_cid = 'test_temporary';
   protected $default_value = 'CacheTest';
 
diff --git a/modules/system/system.install b/modules/system/system.install
index 24933e2d9b698fdbbfd330feb256bf11279e698a..5e6bacf22b5ee328e24ecdae7e1357a5e8f57271 100644
--- a/modules/system/system.install
+++ b/modules/system/system.install
@@ -1471,7 +1471,7 @@ function system_schema() {
         'default' => 0,
       ),
       'cache' => array(
-        'description' => "The time of this user's last post. This is used when the site has specified a minimum_cache_lifetime. See cache_get().",
+        'description' => "The time of this user's last post. This is used when the site has specified a minimum_cache_lifetime. See DrupalCacheInterface::get().",
         'type' => 'int',
         'not null' => TRUE,
         'default' => 0,
diff --git a/modules/update/update.module b/modules/update/update.module
index a2d705a0eb02bc5eed090c5f254caa85b863b3a0..98c6cebac61aadc68ebf30ea049b4f98be172484 100644
--- a/modules/update/update.module
+++ b/modules/update/update.module
@@ -724,10 +724,10 @@ function update_verify_update_archive($project, $archive_file, $directory) {
  * plug-able cache system that assumes volatile caches.
  *
  * Update module still uses the {cache_update} table, but instead of using
- * cache_set(), cache_get(), and cache_clear_all(), there are private helper
- * functions that implement these same basic tasks but ensure that the cache
- * is not prematurely cleared, and that the data is always stored in the
- * database, even if memcache or another cache backend is in use.
+ * the cache API, there are private helper functions that implement these same
+ * basic tasks but ensure that the cache is not prematurely cleared, and that
+ * the data is always stored in the database, even if memcache or another cache
+ * backend is in use.
  */
 
 /**
-- 
1.7.5.4

