Introduce wp_cache_switch_to_blog() and WP_Object_Cache::switch_to_blog() as a lighter/faster way to switch the cache to a new blog id.

Add the blog id to the cache keys for multisite installs.

Use wp_cache_switch_to_blog() instead of wp_cache_init() in switch_to_blog().

Use wp_cache_switch_to_blog() instead of wp_cache_reset() in wp_start_object_cache().

Deprecate wp_cache_reset().

This avoids the many queries needed to re-prime the cache after switch_to_blog() on multisite installs using the default cache backend.

fixes #21434



git-svn-id: http://core.svn.wordpress.org/trunk@21403 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
ryan 2012-08-02 18:31:14 +00:00
parent a7b6455c97
commit 295ca4d76f
3 changed files with 115 additions and 38 deletions

View File

@ -179,6 +179,19 @@ function wp_cache_set($key, $data, $group = '', $expire = 0) {
return $wp_object_cache->set($key, $data, $group, $expire);
}
/**
* Switch the interal blog id.
*
* This changes the blog id used to create keys in blog specific groups.
*
* @param int $blog_id Blog ID
*/
function wp_cache_switch_to_blog( $blog_id ) {
global $wp_object_cache;
return $wp_object_cache->switch_to_blog( $blog_id );
}
/**
* Adds a group or set of groups to the list of global groups.
*
@ -189,7 +202,7 @@ function wp_cache_set($key, $data, $group = '', $expire = 0) {
function wp_cache_add_global_groups( $groups ) {
global $wp_object_cache;
return $wp_object_cache->add_global_groups($groups);
return $wp_object_cache->add_global_groups( $groups );
}
/**
@ -209,8 +222,11 @@ function wp_cache_add_non_persistent_groups( $groups ) {
* this function instructs the backend to reset those keys and perform any cleanup since blog or site IDs have changed since cache init.
*
* @since 2.6.0
* @deprecated 3.5.0
*/
function wp_cache_reset() {
_deprecated_function( __FUNCTION__, '3.5', 'wp_cache_switch_to_blog()' );
global $wp_object_cache;
return $wp_object_cache->reset();
@ -270,6 +286,15 @@ class WP_Object_Cache {
*/
var $global_groups = array();
/**
* The blog prefix to prepend to keys in non-global groups.
*
* @var int
* @access private
* @since 3.5.0
*/
var $blog_prefix;
/**
* Adds data to the cache if it doesn't already exist.
*
@ -292,7 +317,11 @@ class WP_Object_Cache {
if ( empty( $group ) )
$group = 'default';
if ( $this->_exists($key, $group) )
$id = $key;
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
$id = $this->blog_prefix . $key;
if ( $this->_exists( $id, $group ) )
return false;
return $this->set($key, $data, $group, $expire);
@ -308,8 +337,8 @@ class WP_Object_Cache {
function add_global_groups( $groups ) {
$groups = (array) $groups;
$this->global_groups = array_merge($this->global_groups, $groups);
$this->global_groups = array_unique($this->global_groups);
$groups = array_fill_keys( $groups, true );
$this->global_groups = array_merge( $this->global_groups, $groups );
}
/**
@ -325,7 +354,10 @@ class WP_Object_Cache {
function decr( $key, $offset = 1, $group = 'default' ) {
if ( empty( $group ) )
$group = 'default';
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
$key = $this->blog_prefix . $key;
if ( ! $this->_exists( $key, $group ) )
return false;
@ -361,6 +393,9 @@ class WP_Object_Cache {
if ( empty( $group ) )
$group = 'default';
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
$key = $this->blog_prefix . $key;
if ( ! $force && ! $this->_exists( $key, $group ) )
return false;
@ -402,6 +437,9 @@ class WP_Object_Cache {
if ( empty( $group ) )
$group = 'default';
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
$key = $this->blog_prefix . $key;
if ( $this->_exists( $key, $group ) ) {
$found = true;
$this->cache_hits += 1;
@ -430,6 +468,9 @@ class WP_Object_Cache {
if ( empty( $group ) )
$group = 'default';
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
$key = $this->blog_prefix . $key;
if ( ! $this->_exists( $key, $group ) )
return false;
@ -458,26 +499,33 @@ class WP_Object_Cache {
* @param int $expire When to expire the cache contents
* @return bool False if not exists, true if contents were replaced
*/
function replace($key, $data, $group = 'default', $expire = '') {
function replace( $key, $data, $group = 'default', $expire = '' ) {
if ( empty( $group ) )
$group = 'default';
if ( ! $this->_exists( $key, $group ) )
$id = $key;
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
$id = $this->blog_prefix . $key;
if ( ! $this->_exists( $id, $group ) )
return false;
return $this->set($key, $data, $group, $expire);
return $this->set( $key, $data, $group, $expire );
}
/**
* Reset keys
*
* @since 3.0.0
* @deprecated 3.5.0
*/
function reset() {
_deprecated_function( __FUNCTION__, '3.5', 'switch_to_blog()' );
// Clear out non-global caches since the blog ID has changed.
foreach ( array_keys($this->cache) as $group ) {
if ( !in_array($group, $this->global_groups) )
unset($this->cache[$group]);
foreach ( array_keys( $this->cache ) as $group ) {
if ( ! isset( $this->global_groups[ $group ] ) )
unset( $this->cache[ $group ] );
}
}
@ -505,7 +553,10 @@ class WP_Object_Cache {
if ( empty( $group ) )
$group = 'default';
if ( is_object($data) )
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
$key = $this->blog_prefix . $key;
if ( is_object( $data ) )
$data = clone $data;
$this->cache[$group][$key] = $data;
@ -532,6 +583,18 @@ class WP_Object_Cache {
echo '</ul>';
}
/**
* Switch the interal blog id.
*
* This changes the blog id used to create keys in blog specific groups.
*
* @param int $blog_id Blog ID
*/
function switch_to_blog( $blog_id ) {
$blog_id = (int) $blog_id;
$this->blog_prefix = $this->multisite ? $blog_id . ':' : '';
}
/**
* Utility function to determine whether a key exists in the cache.
*
@ -550,11 +613,17 @@ class WP_Object_Cache {
* @return null|WP_Object_Cache If cache is disabled, returns null.
*/
function __construct() {
global $blog_id;
$this->multisite = is_multisite();
$this->blog_prefix = $this->multisite ? $blog_id . ':' : '';
/**
* @todo This should be moved to the PHP4 style constructor, PHP5
* already calls __destruct()
*/
register_shutdown_function(array(&$this, "__destruct"));
register_shutdown_function( array( &$this, '__destruct' ) );
}
/**

View File

@ -381,7 +381,7 @@ function wp_set_wpdb_vars() {
* @since 3.0.0
*/
function wp_start_object_cache() {
global $_wp_using_ext_object_cache;
global $_wp_using_ext_object_cache, $blog_id;
$first_init = false;
if ( ! function_exists( 'wp_cache_init' ) ) {
@ -403,8 +403,8 @@ function wp_start_object_cache() {
// If cache supports reset, reset instead of init if already initialized.
// Reset signals to the cache that global IDs have changed and it may need to update keys
// and cleanup caches.
if ( !$first_init && function_exists('wp_cache_reset') )
wp_cache_reset();
if ( ! $first_init && function_exists( 'wp_cache_switch_to_blog' ) )
wp_cache_switch_to_blog( $blog_id );
else
wp_cache_init();

View File

@ -487,18 +487,22 @@ function switch_to_blog( $new_blog, $validate = false ) {
$current_user->for_blog( $blog_id );
}
if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
$global_groups = $wp_object_cache->global_groups;
else
$global_groups = false;
wp_cache_init();
if ( function_exists('wp_cache_add_global_groups') ) {
if ( is_array( $global_groups ) )
wp_cache_add_global_groups( $global_groups );
if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
wp_cache_switch_to_blog( $blog_id );
} else {
if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
$global_groups = $wp_object_cache->global_groups;
else
wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts' ) );
wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' ));
$global_groups = false;
wp_cache_init();
if ( function_exists('wp_cache_add_global_groups') ) {
if ( is_array( $global_groups ) )
wp_cache_add_global_groups( $global_groups );
else
wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts' ) );
wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' ));
}
}
do_action('switch_blog', $blog_id, $prev_blog_id);
@ -551,18 +555,22 @@ function restore_current_blog() {
$current_user->for_blog( $blog_id );
}
if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
$global_groups = $wp_object_cache->global_groups;
else
$global_groups = false;
wp_cache_init();
if ( function_exists('wp_cache_add_global_groups') ) {
if ( is_array( $global_groups ) )
wp_cache_add_global_groups( $global_groups );
if ( function_exists( 'wp_cache_switch_to_blog' ) ) {
wp_cache_switch_to_blog( $blog_id );
} else {
if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) )
$global_groups = $wp_object_cache->global_groups;
else
wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts' ) );
wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' ));
$global_groups = false;
wp_cache_init();
if ( function_exists('wp_cache_add_global_groups') ) {
if ( is_array( $global_groups ) )
wp_cache_add_global_groups( $global_groups );
else
wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts' ) );
wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' ));
}
}
do_action('switch_blog', $blog_id, $prev_blog_id);