Preload commonly loaded site options when running multisite without a persistent cache. Introduce wp_cache_reset() and call it instead of wp_cache_init() when re-initing after the blog ID chanages to avoid throwing out the entire cache. Pass cached site options through the site option filter when fetching.

git-svn-id: http://svn.automattic.com/wordpress/trunk@13066 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
ryan 2010-02-12 17:06:43 +00:00
parent b20c3c41d4
commit f97aa91a68
4 changed files with 115 additions and 25 deletions

View File

@ -149,8 +149,9 @@ function wp_cache_set($key, $data, $flag = '', $expire = 0) {
* @param string|array $groups A group or an array of groups to add * @param string|array $groups A group or an array of groups to add
*/ */
function wp_cache_add_global_groups( $groups ) { function wp_cache_add_global_groups( $groups ) {
// Default cache doesn't persist so nothing to do here. global $wp_object_cache;
return;
return $wp_object_cache->add_global_groups($groups);
} }
/** /**
@ -165,6 +166,20 @@ function wp_cache_add_non_persistent_groups( $groups ) {
return; return;
} }
/**
* Reset internal cache keys and structures. If the cache backend uses global blog or site IDs as part of its cache keys,
* 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
*
* @param string|array $groups A group or an array of groups to add
*/
function wp_cache_reset() {
global $wp_object_cache;
return $wp_object_cache->reset();
}
/** /**
* WordPress Object Cache * WordPress Object Cache
* *
@ -219,6 +234,15 @@ class WP_Object_Cache {
*/ */
var $cache_misses = 0; var $cache_misses = 0;
/**
* List of global groups
*
* @var array
* @access protected
* @since 3.0.0
*/
var $global_groups = array();
/** /**
* Adds data to the cache if it doesn't already exist. * Adds data to the cache if it doesn't already exist.
* *
@ -234,8 +258,8 @@ class WP_Object_Cache {
* @param int $expire When to expire the cache contents * @param int $expire When to expire the cache contents
* @return bool False if cache ID and group already exists, true on success * @return bool False if cache ID and group already exists, true on success
*/ */
function add($id, $data, $group = 'default', $expire = '') { function add( $id, $data, $group = 'default', $expire = '' ) {
if (empty ($group)) if ( empty ($group) )
$group = 'default'; $group = 'default';
if (false !== $this->get($id, $group)) if (false !== $this->get($id, $group))
@ -244,6 +268,20 @@ class WP_Object_Cache {
return $this->set($id, $data, $group, $expire); return $this->set($id, $data, $group, $expire);
} }
/**
* Sets the list of global groups.
*
* @since 3.0.0
*
* @param array $groups List of groups that are global.
*/
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);
}
/** /**
* Remove the contents of the cache ID in the group * Remove the contents of the cache ID in the group
* *
@ -308,10 +346,10 @@ class WP_Object_Cache {
* contents on success * contents on success
*/ */
function get($id, $group = 'default') { function get($id, $group = 'default') {
if (empty ($group)) if ( empty ($group) )
$group = 'default'; $group = 'default';
if (isset ($this->cache[$group][$id])) { if ( isset ($this->cache[$group][$id]) ) {
$this->cache_hits += 1; $this->cache_hits += 1;
if ( is_object($this->cache[$group][$id]) ) if ( is_object($this->cache[$group][$id]) )
return wp_clone($this->cache[$group][$id]); return wp_clone($this->cache[$group][$id]);
@ -343,12 +381,25 @@ class WP_Object_Cache {
if (empty ($group)) if (empty ($group))
$group = 'default'; $group = 'default';
if (false === $this->get($id, $group)) if ( false === $this->get($id, $group) )
return false; return false;
return $this->set($id, $data, $group, $expire); return $this->set($id, $data, $group, $expire);
} }
/**
* Reset keys
*
* @since 3.0.0
*/
function reset() {
// 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]);
}
}
/** /**
* Sets the data contents into the cache * Sets the data contents into the cache
* *
@ -370,10 +421,10 @@ class WP_Object_Cache {
* @return bool Always returns true * @return bool Always returns true
*/ */
function set($id, $data, $group = 'default', $expire = '') { function set($id, $data, $group = 'default', $expire = '') {
if (empty ($group)) if ( empty ($group) )
$group = 'default'; $group = 'default';
if (NULL === $data) if ( NULL === $data )
$data = ''; $data = '';
if ( is_object($data) ) if ( is_object($data) )
@ -381,7 +432,7 @@ class WP_Object_Cache {
$this->cache[$group][$id] = $data; $this->cache[$group][$id] = $data;
if(isset($this->non_existent_objects[$group][$id])) if ( isset($this->non_existent_objects[$group][$id]) )
unset ($this->non_existent_objects[$group][$id]); unset ($this->non_existent_objects[$group][$id]);
return true; return true;

View File

@ -437,6 +437,29 @@ function wp_load_alloptions() {
return $alloptions; return $alloptions;
} }
function wp_load_core_site_options( $site_id = null ) {
global $wpdb, $_wp_using_ext_object_cache;
if ( !is_multisite() || $_wp_using_ext_object_cache || defined( 'WP_INSTALLING' ) )
return;
if ( empty($site_id) )
$site_id = $wpdb->siteid;
$core_options = array('site_name', 'siteurl', 'active_sitewide_plugins', '_site_transient_timeout_theme_roots', '_site_transient_theme_roots', 'site_admins', 'dashboard_blog');
$core_options_in = "'" . implode("', '", $core_options) . "'";
$options = $wpdb->get_results( $wpdb->prepare("SELECT meta_key, meta_value FROM $wpdb->sitemeta WHERE meta_key IN ($core_options_in) AND site_id = %d", $site_id) );
foreach ( $options as $option ) {
$key = $option->meta_key;
$cache_key = "{$site_id}:$key";
$option->meta_value = maybe_unserialize( $option->meta_value );
wp_cache_set( $cache_key, $option->meta_value, 'site-options' );
}
}
/** /**
* Update the value of an option that was already added. * Update the value of an option that was already added.
* *
@ -3320,11 +3343,11 @@ function get_site_option( $key, $default = false, $use_cache = true ) {
if ( !is_multisite() ) { if ( !is_multisite() ) {
$value = get_option($key, $default); $value = get_option($key, $default);
} else { } else {
$cache_key = "{$wpdb->siteid}:$key"; $cache_key = "$wpdb->siteid:$key";
if ( $use_cache )
if ( $use_cache == true && $value = wp_cache_get($cache_key, 'site-options') ) $value = wp_cache_get($cache_key, 'site-options');
return $value;
if ( false === $value ) {
$value = $wpdb->get_var( $wpdb->prepare("SELECT meta_value FROM $wpdb->sitemeta WHERE meta_key = %s AND site_id = %d", $key, $wpdb->siteid) ); $value = $wpdb->get_var( $wpdb->prepare("SELECT meta_value FROM $wpdb->sitemeta WHERE meta_key = %s AND site_id = %d", $key, $wpdb->siteid) );
if ( is_null($value) ) if ( is_null($value) )
@ -3334,6 +3357,7 @@ function get_site_option( $key, $default = false, $use_cache = true ) {
wp_cache_set( $cache_key, $value, 'site-options' ); wp_cache_set( $cache_key, $value, 'site-options' );
} }
}
return apply_filters( 'site_option_' . $key, $value ); return apply_filters( 'site_option_' . $key, $value );
} }

View File

@ -318,6 +318,7 @@ function wp_set_wpdb_vars() {
* @since 3.0.0 * @since 3.0.0
*/ */
function wp_start_object_cache() { function wp_start_object_cache() {
$first_init = false;
if ( ! function_exists( 'wp_cache_init' ) ) { if ( ! function_exists( 'wp_cache_init' ) ) {
global $_wp_using_ext_object_cache; global $_wp_using_ext_object_cache;
if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) { if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
@ -327,9 +328,17 @@ function wp_start_object_cache() {
require_once ( ABSPATH . WPINC . '/cache.php' ); require_once ( ABSPATH . WPINC . '/cache.php' );
$_wp_using_ext_object_cache = false; $_wp_using_ext_object_cache = false;
} }
$first_init = true;
} }
// 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();
else
wp_cache_init(); wp_cache_init();
if ( function_exists( 'wp_cache_add_global_groups' ) ) { if ( function_exists( 'wp_cache_add_global_groups' ) ) {
wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss' ) ); wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss' ) );
wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) ); wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );

View File

@ -75,11 +75,14 @@ function ms_site_check() {
*/ */
function get_current_site_name( $current_site ) { function get_current_site_name( $current_site ) {
global $wpdb; global $wpdb;
$current_site->site_name = wp_cache_get( $current_site->id . ':current_site_name', "site-options" ); $current_site->site_name = wp_cache_get( $current_site->id . ':current_site_name', 'site-options' );
if ( ! $current_site->site_name ) {
$current_site->site_name = wp_cache_get( $current_site->id . ':site_name', 'site-options' );
if ( ! $current_site->site_name ) { if ( ! $current_site->site_name ) {
$current_site->site_name = $wpdb->get_var( $wpdb->prepare( "SELECT meta_value FROM $wpdb->sitemeta WHERE site_id = %d AND meta_key = 'site_name'", $current_site->id ) ); $current_site->site_name = $wpdb->get_var( $wpdb->prepare( "SELECT meta_value FROM $wpdb->sitemeta WHERE site_id = %d AND meta_key = 'site_name'", $current_site->id ) );
if ( ! $current_site->site_name ) if ( ! $current_site->site_name )
$current_site->site_name = ucfirst( $current_site->domain ); $current_site->site_name = ucfirst( $current_site->domain );
}
wp_cache_set( $current_site->id . ':current_site_name', $current_site->site_name, 'site-options' ); wp_cache_set( $current_site->id . ':current_site_name', $current_site->site_name, 'site-options' );
} }
return $current_site; return $current_site;
@ -107,6 +110,8 @@ function wpmu_current_site() {
else else
$current_site->cookie_domain = $current_site->domain; $current_site->cookie_domain = $current_site->domain;
wp_load_core_site_options($current_site->id);
return $current_site; return $current_site;
} }
@ -116,6 +121,7 @@ function wpmu_current_site() {
$sites = $wpdb->get_results( "SELECT * FROM $wpdb->site" ); // usually only one site $sites = $wpdb->get_results( "SELECT * FROM $wpdb->site" ); // usually only one site
if ( 1 == count( $sites ) ) { if ( 1 == count( $sites ) ) {
wp_load_core_site_options($current_site->id);
$current_site = $sites[0]; $current_site = $sites[0];
$path = $current_site->path; $path = $current_site->path;
$current_site->blog_id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s", $current_site->domain, $current_site->path ) ); $current_site->blog_id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s", $current_site->domain, $current_site->path ) );