<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[13066] trunk/wp-includes:
  Preload commonly loaded site options when running multisite without a persistent cache
 .</title>
</head>
<body>

<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.wordpress.org/changeset/13066">13066</a></dd>
<dt>Author</dt> <dd>ryan</dd>
<dt>Date</dt> <dd>2010-02-12 17:06:43 +0000 (Fri, 12 Feb 2010)</dd>
</dl>

<h3>Log Message</h3>
<pre>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.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkwpincludescachephp">trunk/wp-includes/cache.php</a></li>
<li><a href="#trunkwpincludesfunctionsphp">trunk/wp-includes/functions.php</a></li>
<li><a href="#trunkwpincludesloadphp">trunk/wp-includes/load.php</a></li>
<li><a href="#trunkwpincludesmsloadphp">trunk/wp-includes/ms-load.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkwpincludescachephp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/cache.php (13065 => 13066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/cache.php        2010-02-12 08:22:34 UTC (rev 13065)
+++ trunk/wp-includes/cache.php        2010-02-12 17:06:43 UTC (rev 13066)
</span><span class="lines">@@ -149,8 +149,9 @@
</span><span class="cx">  * @param string|array $groups A group or an array of groups to add
</span><span class="cx">  */
</span><span class="cx"> function wp_cache_add_global_groups( $groups ) {
</span><del>-        // Default cache doesn't persist so nothing to do here.
-        return;
</del><ins>+        global $wp_object_cache;
+
+        return $wp_object_cache-&gt;add_global_groups($groups);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> /**
</span><span class="lines">@@ -166,6 +167,20 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> /**
</span><ins>+ * 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-&gt;reset();
+}
+
+/**
</ins><span class="cx">  * WordPress Object Cache
</span><span class="cx">  *
</span><span class="cx">  * The WordPress Object Cache is used to save on trips to the database. The
</span><span class="lines">@@ -220,6 +235,15 @@
</span><span class="cx">         var $cache_misses = 0;
</span><span class="cx"> 
</span><span class="cx">         /**
</span><ins>+         * List of global groups
+         *
+         * @var array
+         * @access protected
+         * @since 3.0.0
+         */
+        var $global_groups = array();
+
+        /**
</ins><span class="cx">          * Adds data to the cache if it doesn't already exist.
</span><span class="cx">          *
</span><span class="cx">          * @uses WP_Object_Cache::get Checks to see if the cache already has data.
</span><span class="lines">@@ -234,8 +258,8 @@
</span><span class="cx">          * @param int $expire When to expire the cache contents
</span><span class="cx">          * @return bool False if cache ID and group already exists, true on success
</span><span class="cx">          */
</span><del>-        function add($id, $data, $group = 'default', $expire = '') {
-                if (empty ($group))
</del><ins>+        function add( $id, $data, $group = 'default', $expire = '' ) {
+                if ( empty ($group) )
</ins><span class="cx">                         $group = 'default';
</span><span class="cx"> 
</span><span class="cx">                 if (false !== $this-&gt;get($id, $group))
</span><span class="lines">@@ -245,6 +269,20 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         /**
</span><ins>+         * 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-&gt;global_groups = array_merge($this-&gt;global_groups, $groups);
+                $this-&gt;global_groups = array_unique($this-&gt;global_groups);
+        }
+
+        /**
</ins><span class="cx">          * Remove the contents of the cache ID in the group
</span><span class="cx">          *
</span><span class="cx">          * If the cache ID does not exist in the group and $force parameter is set
</span><span class="lines">@@ -308,10 +346,10 @@
</span><span class="cx">          *                contents on success
</span><span class="cx">          */
</span><span class="cx">         function get($id, $group = 'default') {
</span><del>-                if (empty ($group))
</del><ins>+                if ( empty ($group) )
</ins><span class="cx">                         $group = 'default';
</span><span class="cx"> 
</span><del>-                if (isset ($this-&gt;cache[$group][$id])) {
</del><ins>+                if ( isset ($this-&gt;cache[$group][$id]) ) {
</ins><span class="cx">                         $this-&gt;cache_hits += 1;
</span><span class="cx">                         if ( is_object($this-&gt;cache[$group][$id]) )
</span><span class="cx">                                 return wp_clone($this-&gt;cache[$group][$id]);
</span><span class="lines">@@ -343,13 +381,26 @@
</span><span class="cx">                 if (empty ($group))
</span><span class="cx">                         $group = 'default';
</span><span class="cx"> 
</span><del>-                if (false === $this-&gt;get($id, $group))
</del><ins>+                if ( false === $this-&gt;get($id, $group) )
</ins><span class="cx">                         return false;
</span><span class="cx"> 
</span><span class="cx">                 return $this-&gt;set($id, $data, $group, $expire);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         /**
</span><ins>+         * Reset keys
+         *
+         * @since 3.0.0
+         */
+        function reset() {
+                // Clear out non-global caches since the blog ID has changed.
+                foreach ( array_keys($this-&gt;cache) as $group ) {
+                        if ( !in_array($group, $this-&gt;global_groups) )
+                                unset($this-&gt;cache[$group]);
+                }
+        }
+
+        /**
</ins><span class="cx">          * Sets the data contents into the cache
</span><span class="cx">          *
</span><span class="cx">          * The cache contents is grouped by the $group parameter followed by the
</span><span class="lines">@@ -370,10 +421,10 @@
</span><span class="cx">          * @return bool Always returns true
</span><span class="cx">          */
</span><span class="cx">         function set($id, $data, $group = 'default', $expire = '') {
</span><del>-                if (empty ($group))
</del><ins>+                if ( empty ($group) )
</ins><span class="cx">                         $group = 'default';
</span><span class="cx"> 
</span><del>-                if (NULL === $data)
</del><ins>+                if ( NULL === $data )
</ins><span class="cx">                         $data = '';
</span><span class="cx"> 
</span><span class="cx">                 if ( is_object($data) )
</span><span class="lines">@@ -381,7 +432,7 @@
</span><span class="cx"> 
</span><span class="cx">                 $this-&gt;cache[$group][$id] = $data;
</span><span class="cx"> 
</span><del>-                if(isset($this-&gt;non_existent_objects[$group][$id]))
</del><ins>+                if ( isset($this-&gt;non_existent_objects[$group][$id]) )
</ins><span class="cx">                         unset ($this-&gt;non_existent_objects[$group][$id]);
</span><span class="cx"> 
</span><span class="cx">                 return true;
</span></span></pre></div>
<a id="trunkwpincludesfunctionsphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/functions.php (13065 => 13066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/functions.php        2010-02-12 08:22:34 UTC (rev 13065)
+++ trunk/wp-includes/functions.php        2010-02-12 17:06:43 UTC (rev 13066)
</span><span class="lines">@@ -437,6 +437,29 @@
</span><span class="cx">         return $alloptions;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+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-&gt;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 = &quot;'&quot; . implode(&quot;', '&quot;, $core_options) . &quot;'&quot;;
+        $options = $wpdb-&gt;get_results( $wpdb-&gt;prepare(&quot;SELECT meta_key, meta_value FROM $wpdb-&gt;sitemeta WHERE meta_key IN ($core_options_in) AND site_id = %d&quot;, $site_id) );
+
+        foreach ( $options as $option ) {
+                $key = $option-&gt;meta_key;
+                $cache_key = &quot;{$site_id}:$key&quot;;
+                $option-&gt;meta_value = maybe_unserialize( $option-&gt;meta_value );
+
+                wp_cache_set( $cache_key, $option-&gt;meta_value, 'site-options' );
+        }
+}
+
</ins><span class="cx"> /**
</span><span class="cx">  * Update the value of an option that was already added.
</span><span class="cx">  *
</span><span class="lines">@@ -3320,19 +3343,20 @@
</span><span class="cx">         if ( !is_multisite() ) {
</span><span class="cx">                 $value = get_option($key, $default);
</span><span class="cx">         } else {
</span><del>-                $cache_key = &quot;{$wpdb-&gt;siteid}:$key&quot;;
</del><ins>+                $cache_key = &quot;$wpdb-&gt;siteid:$key&quot;;
+                if ( $use_cache )
+                        $value = wp_cache_get($cache_key, 'site-options');
</ins><span class="cx"> 
</span><del>-                if ( $use_cache == true &amp;&amp; $value = wp_cache_get($cache_key, 'site-options') )
-                        return $value;
</del><ins>+                if ( false === $value ) {
+                        $value = $wpdb-&gt;get_var( $wpdb-&gt;prepare(&quot;SELECT meta_value FROM $wpdb-&gt;sitemeta WHERE meta_key = %s AND site_id = %d&quot;, $key, $wpdb-&gt;siteid) );
</ins><span class="cx"> 
</span><del>-                $value = $wpdb-&gt;get_var( $wpdb-&gt;prepare(&quot;SELECT meta_value FROM $wpdb-&gt;sitemeta WHERE meta_key = %s AND site_id = %d&quot;, $key, $wpdb-&gt;siteid) );
</del><ins>+                        if ( is_null($value) )
+                                $value = $default;
</ins><span class="cx"> 
</span><del>-                if ( is_null($value) )
-                        $value = $default;
</del><ins>+                        $value = maybe_unserialize( $value );
</ins><span class="cx"> 
</span><del>-                $value = maybe_unserialize( $value );
-
-                wp_cache_set( $cache_key, $value, 'site-options' );
</del><ins>+                        wp_cache_set( $cache_key, $value, 'site-options' );
+                }
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">          return apply_filters( 'site_option_' . $key, $value );
</span></span></pre></div>
<a id="trunkwpincludesloadphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/load.php (13065 => 13066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/load.php        2010-02-12 08:22:34 UTC (rev 13065)
+++ trunk/wp-includes/load.php        2010-02-12 17:06:43 UTC (rev 13066)
</span><span class="lines">@@ -318,7 +318,8 @@
</span><span class="cx">  * @since 3.0.0
</span><span class="cx">  */
</span><span class="cx"> function wp_start_object_cache() {
</span><del>-        if ( ! function_exists( 'wp_cache_init' ) ) {
</del><ins>+        $first_init = false;
+         if ( ! function_exists( 'wp_cache_init' ) ) {
</ins><span class="cx">                 global $_wp_using_ext_object_cache;
</span><span class="cx">                 if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
</span><span class="cx">                         require_once ( WP_CONTENT_DIR . '/object-cache.php' );
</span><span class="lines">@@ -327,9 +328,17 @@
</span><span class="cx">                         require_once ( ABSPATH . WPINC . '/cache.php' );
</span><span class="cx">                         $_wp_using_ext_object_cache = false;
</span><span class="cx">                 }
</span><ins>+                $first_init = true;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><del>-        wp_cache_init();
</del><ins>+        // 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 &amp;&amp; function_exists('wp_cache_reset') )
+                wp_cache_reset();
+        else
+                wp_cache_init();
+
</ins><span class="cx">         if ( function_exists( 'wp_cache_add_global_groups' ) ) {
</span><span class="cx">                 wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss' ) );
</span><span class="cx">                 wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );
</span></span></pre></div>
<a id="trunkwpincludesmsloadphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/ms-load.php (13065 => 13066)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/ms-load.php        2010-02-12 08:22:34 UTC (rev 13065)
+++ trunk/wp-includes/ms-load.php        2010-02-12 17:06:43 UTC (rev 13066)
</span><span class="lines">@@ -75,11 +75,14 @@
</span><span class="cx">  */
</span><span class="cx"> function get_current_site_name( $current_site ) {
</span><span class="cx">         global $wpdb;
</span><del>-        $current_site-&gt;site_name = wp_cache_get( $current_site-&gt;id . ':current_site_name', &quot;site-options&quot; );
</del><ins>+        $current_site-&gt;site_name = wp_cache_get( $current_site-&gt;id . ':current_site_name', 'site-options' );
</ins><span class="cx">         if ( ! $current_site-&gt;site_name ) {
</span><del>-                $current_site-&gt;site_name = $wpdb-&gt;get_var( $wpdb-&gt;prepare( &quot;SELECT meta_value FROM $wpdb-&gt;sitemeta WHERE site_id = %d AND meta_key = 'site_name'&quot;, $current_site-&gt;id ) );
-                if ( ! $current_site-&gt;site_name )
-                        $current_site-&gt;site_name = ucfirst( $current_site-&gt;domain );
</del><ins>+                $current_site-&gt;site_name = wp_cache_get( $current_site-&gt;id . ':site_name', 'site-options' );
+                if ( ! $current_site-&gt;site_name ) {
+                        $current_site-&gt;site_name = $wpdb-&gt;get_var( $wpdb-&gt;prepare( &quot;SELECT meta_value FROM $wpdb-&gt;sitemeta WHERE site_id = %d AND meta_key = 'site_name'&quot;, $current_site-&gt;id ) );
+                        if ( ! $current_site-&gt;site_name )
+                                $current_site-&gt;site_name = ucfirst( $current_site-&gt;domain );
+                }
</ins><span class="cx">                 wp_cache_set( $current_site-&gt;id . ':current_site_name', $current_site-&gt;site_name, 'site-options' );
</span><span class="cx">         }
</span><span class="cx">         return $current_site;
</span><span class="lines">@@ -107,6 +110,8 @@
</span><span class="cx">                 else
</span><span class="cx">                         $current_site-&gt;cookie_domain = $current_site-&gt;domain;
</span><span class="cx"> 
</span><ins>+                wp_load_core_site_options($current_site-&gt;id);
+
</ins><span class="cx">                 return $current_site;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -116,6 +121,7 @@
</span><span class="cx"> 
</span><span class="cx">         $sites = $wpdb-&gt;get_results( &quot;SELECT * FROM $wpdb-&gt;site&quot; ); // usually only one site
</span><span class="cx">         if ( 1 == count( $sites ) ) {
</span><ins>+                wp_load_core_site_options($current_site-&gt;id);
</ins><span class="cx">                 $current_site = $sites[0];
</span><span class="cx">                 $path = $current_site-&gt;path;
</span><span class="cx">                 $current_site-&gt;blog_id = $wpdb-&gt;get_var( $wpdb-&gt;prepare( &quot;SELECT blog_id FROM $wpdb-&gt;blogs WHERE domain = %s AND path = %s&quot;, $current_site-&gt;domain, $current_site-&gt;path ) );
</span></span></pre>
</div>
</div>

</body>
</html>