From 32ab847e63c3e347fa141588e9bc20fc51734781 Mon Sep 17 00:00:00 2001 From: Tazo Todua Date: Thu, 7 Feb 2019 01:04:15 +0400 Subject: [PATCH 1/6] Create index.php --- index.php | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 index.php diff --git a/index.php b/index.php new file mode 100644 index 0000000..d441ca5 --- /dev/null +++ b/index.php @@ -0,0 +1,93 @@ +destination ) ) { + if ( function_exists( 'symlink' ) ){ + symlink( $this->source, $this->destination); + } + else { + // Lets don't do it automatically, instead make a notice to user + // copy( $this->source, $this->destination ); + } + } + + } + } + + public function deactivate() { + // Only delete file if it belongs to this plugin + if ( defined($this->constName) && file_exists( $this->destination ) ) { + unlink( $this->destination ); + } + } + + // Check if current plugin is active, but it's cache not being used. If so, show warning to user to deactivate this plugin to avoid any confusion + public function check_if_activated() { + $plugin_basename= plugin_basename(__FILE__); + $plugin_name = dirname($plugin_basename); + + if ( is_plugin_active ($plugin_basename) && ! defined($this->constName) ) + { ?> +
+

+

()

+ ' . __('Memcache class is not detected in your hosting, and there is no way you can use that. You have to install it at first, or try to conctact your server administrators. Untill you do that, it\'s better to deactivate this plugin', 'memcached-enabler') .'.'; + } + else if ( ! function_exists( 'symlink' ) ) + { + ?> +
  • symlink function is not enabled in your hosting. So, you have to manually copy %s to %s. In that case, if you ever manually (beyond WP) delete this plugin, you will also need to remove that file manually, otherwise it will remain in use.', 'memcached-enabler'), $this->source, $this->destination ); ?>.
  • + destination ) ) + { + ?> +
  • %s ), probably some other plugin has replaced that file. So, this plugin ( '. basename($plugin_name).') is now non-functional. Please deactivate it to avoid any confusion. In case you really want to retain only this plugin, that remove the existing %s and re-activate this plugin', 'memcached-enabler'), basename($plugin_name), 'wp-content/'. basename($this->destination), 'wp-content/'. basename($this->destination) ) ;?>.
  • + +
  • %s) doesn\'t exist, so this plugin doesn\'t function. Not sure what has happened, but you may try to re-activate this plugin )', 'memcached-enabler'), 'wp-content/'. basename($this->destination), 'wp-content/'. basename($this->destination) ) ;?>.
  • + +

    +
    + From 8f0e5a266370235516612e78c52cd8d04a0f616a Mon Sep 17 00:00:00 2001 From: Tazo Todua Date: Thu, 7 Feb 2019 01:04:44 +0400 Subject: [PATCH 2/6] Update object-cache.php --- object-cache.php | 472 +++++++++++++++++------------------------------ 1 file changed, 165 insertions(+), 307 deletions(-) diff --git a/object-cache.php b/object-cache.php index 5f6507a..40741e4 100644 --- a/object-cache.php +++ b/object-cache.php @@ -1,37 +1,32 @@ add( $key, $data, $group, $expire ); + return $wp_object_cache->add($key, $data, $group, $expire); } -function wp_cache_incr( $key, $n = 1, $group = '' ) { +function wp_cache_incr($key, $n = 1, $group = '') { global $wp_object_cache; - return $wp_object_cache->incr( $key, $n, $group ); + return $wp_object_cache->incr($key, $n, $group); } -function wp_cache_decr( $key, $n = 1, $group = '' ) { +function wp_cache_decr($key, $n = 1, $group = '') { global $wp_object_cache; - return $wp_object_cache->decr( $key, $n, $group ); + return $wp_object_cache->decr($key, $n, $group); } function wp_cache_close() { @@ -40,10 +35,10 @@ function wp_cache_close() { return $wp_object_cache->close(); } -function wp_cache_delete( $key, $group = '' ) { +function wp_cache_delete($key, $group = '') { global $wp_object_cache; - return $wp_object_cache->delete( $key, $group ); + return $wp_object_cache->delete($key, $group); } function wp_cache_flush() { @@ -52,22 +47,10 @@ function wp_cache_flush() { return $wp_object_cache->flush(); } -function wp_cache_get( $key, $group = '', $force = false ) { +function wp_cache_get($key, $group = '', $force = false) { global $wp_object_cache; - return $wp_object_cache->get( $key, $group, $force ); -} - -/** - * Retrieve multiple cache entries - * - * @param array $groups Array of arrays, of groups and keys to retrieve - * @return mixed - */ -function wp_cache_get_multi( $groups ) { - global $wp_object_cache; - - return $wp_object_cache->get_multi( $groups ); + return $wp_object_cache->get($key, $group, $force); } function wp_cache_init() { @@ -76,20 +59,19 @@ function wp_cache_init() { $wp_object_cache = new WP_Object_Cache(); } -function wp_cache_replace( $key, $data, $group = '', $expire = 0 ) { +function wp_cache_replace($key, $data, $group = '', $expire = 0) { global $wp_object_cache; - return $wp_object_cache->replace( $key, $data, $group, $expire ); + return $wp_object_cache->replace($key, $data, $group, $expire); } -function wp_cache_set( $key, $data, $group = '', $expire = 0 ) { +function wp_cache_set($key, $data, $group = '', $expire = 0) { global $wp_object_cache; - if ( defined( 'WP_INSTALLING' ) == false ) { - return $wp_object_cache->set( $key, $data, $group, $expire ); - } else { - return $wp_object_cache->delete( $key, $group ); - } + if ( defined('WP_INSTALLING') == false ) + return $wp_object_cache->set($key, $data, $group, $expire); + else + return $wp_object_cache->delete($key, $group); } function wp_cache_switch_to_blog( $blog_id ) { @@ -101,13 +83,13 @@ function wp_cache_switch_to_blog( $blog_id ) { function wp_cache_add_global_groups( $groups ) { global $wp_object_cache; - $wp_object_cache->add_global_groups( $groups ); + $wp_object_cache->add_global_groups($groups); } function wp_cache_add_non_persistent_groups( $groups ) { global $wp_object_cache; - $wp_object_cache->add_non_persistent_groups( $groups ); + $wp_object_cache->add_non_persistent_groups($groups); } class WP_Object_Cache { @@ -115,125 +97,95 @@ class WP_Object_Cache { var $no_mc_groups = array(); - var $cache = array(); - var $mc = array(); - var $stats = array(); + var $cache = array(); + var $mc = array(); + var $stats = array(); var $group_ops = array(); - - var $flush_number = array(); + var $flush_number = array(); var $global_flush_number = null; - var $cache_enabled = true; + var $cache_enabled = true; var $default_expiration = 0; - var $max_expiration = 2592000; // 30 days - var $stats_callback = null; + function add($id, $data, $group = 'default', $expire = 0) { + $key = $this->key($id, $group); - var $connection_errors = array(); - - function add( $id, $data, $group = 'default', $expire = 0 ) { - $key = $this->key( $id, $group ); - - if ( is_object( $data ) ) { + if ( is_object( $data ) ) $data = clone $data; - } - - if ( in_array( $group, $this->no_mc_groups ) ) { - $this->cache[ $key ] = $data; + if ( in_array($group, $this->no_mc_groups) ) { + $this->cache[$key] = $data; return true; - } elseif ( isset( $this->cache[ $key ] ) && false !== $this->cache[ $key ] ) { + } elseif ( isset($this->cache[$key]) && $this->cache[$key] !== false ) { return false; } - $mc =& $this->get_mc( $group ); - - $expire = intval( $expire ); - if ( 0 === $expire || $expire > $this->max_expiration ) { - $expire = $this->default_expiration; - } - - $result = $mc->add( $key, $data, false, $expire ); + $mc =& $this->get_mc($group); + $expire = ($expire == 0) ? $this->default_expiration : $expire; + $result = $mc->add($key, $data, false, $expire); if ( false !== $result ) { - ++$this->stats['add']; - - $this->group_ops[ $group ][] = "add $id"; - $this->cache[ $key ] = $data; - } else if ( false === $result && true === isset( $this->cache[$key] ) && false === $this->cache[$key] ) { - /* - * Here we unset local cache if remote add failed and local cache value is equal to `false` in order - * to update the local cache anytime we get a new information from remote server. This way, the next - * cache get will go to remote server and will fetch recent data. - */ - unset( $this->cache[$key] ); + @ ++$this->stats['add']; + $this->group_ops[$group][] = "add $id"; + $this->cache[$key] = $data; } return $result; } - function add_global_groups( $groups ) { - if ( ! is_array( $groups ) ) { + function add_global_groups($groups) { + if ( ! is_array($groups) ) $groups = (array) $groups; - } - $this->global_groups = array_merge( $this->global_groups, $groups ); - $this->global_groups = array_unique( $this->global_groups ); + $this->global_groups = array_merge($this->global_groups, $groups); + $this->global_groups = array_unique($this->global_groups); } - function add_non_persistent_groups( $groups ) { - if ( ! is_array( $groups ) ) { + function add_non_persistent_groups($groups) { + if ( ! is_array($groups) ) $groups = (array) $groups; - } - $this->no_mc_groups = array_merge( $this->no_mc_groups, $groups ); - $this->no_mc_groups = array_unique( $this->no_mc_groups ); + $this->no_mc_groups = array_merge($this->no_mc_groups, $groups); + $this->no_mc_groups = array_unique($this->no_mc_groups); } - function incr( $id, $n = 1, $group = 'default' ) { - $key = $this->key( $id, $group ); - $mc =& $this->get_mc( $group ); - + function incr($id, $n = 1, $group = 'default' ) { + $key = $this->key($id, $group); + $mc =& $this->get_mc($group); $this->cache[ $key ] = $mc->increment( $key, $n ); - return $this->cache[ $key ]; } - function decr( $id, $n = 1, $group = 'default' ) { - $key = $this->key( $id, $group ); - $mc =& $this->get_mc( $group ); - + function decr($id, $n = 1, $group = 'default' ) { + $key = $this->key($id, $group); + $mc =& $this->get_mc($group); $this->cache[ $key ] = $mc->decrement( $key, $n ); - return $this->cache[ $key ]; } function close() { - foreach ( $this->mc as $bucket => $mc ) { + + foreach ( $this->mc as $bucket => $mc ) $mc->close(); - } } - function delete( $id, $group = 'default' ) { - $key = $this->key( $id, $group ); - - if ( in_array( $group, $this->no_mc_groups ) ) { - unset( $this->cache[ $key ] ); + function delete($id, $group = 'default') { + $key = $this->key($id, $group); + if ( in_array($group, $this->no_mc_groups) ) { + unset($this->cache[$key]); return true; } - $mc =& $this->get_mc( $group ); + $mc =& $this->get_mc($group); - $result = $mc->delete( $key ); + $result = $mc->delete($key); - ++$this->stats['delete']; + @ ++$this->stats['delete']; + $this->group_ops[$group][] = "delete $id"; - $this->group_ops[ $group ][] = "delete $id"; - - if ( false !== $result ) { - unset( $this->cache[ $key ] ); - } + if ( false !== $result ) + unset($this->cache[$key]); return $result; } @@ -245,55 +197,44 @@ function flush() { // Instead, rotate the key prefix for the current site. // Global keys are rotated when flushing on the main site. $this->cache = array(); - $this->rotate_site_keys(); - - if ( is_main_site() ) { + if ( is_main_site() ) $this->rotate_global_keys(); - } } function rotate_site_keys() { - $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache' ); - + $this->add( 'flush_number', intval(microtime(true) * 1e6), 'WP_Object_Cache' ); $this->flush_number[ $this->blog_prefix ] = $this->incr( 'flush_number', 1, 'WP_Object_Cache' ); } function rotate_global_keys() { - $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache_global' ); - + $this->add( 'flush_number', intval(microtime(true) * 1e6), 'WP_Object_Cache_global' ); $this->global_flush_number = $this->incr( 'flush_number', 1, 'WP_Object_Cache_global' ); } - function get( $id, $group = 'default', $force = false ) { - $key = $this->key( $id, $group ); - $mc =& $this->get_mc( $group ); - - if ( isset( $this->cache[ $key ] ) && ( ! $force || in_array( $group, $this->no_mc_groups ) ) ) { - if ( is_object( $this->cache[ $key ] ) ) { - $value = clone $this->cache[ $key ]; - } else { - $value = $this->cache[ $key ]; - } - } else if ( in_array( $group, $this->no_mc_groups ) ) { - $this->cache[ $key ] = $value = false; + function get($id, $group = 'default', $force = false) { + $key = $this->key($id, $group); + $mc =& $this->get_mc($group); + + if ( isset($this->cache[$key]) && ( !$force || in_array($group, $this->no_mc_groups) ) ) { + if ( is_object( $this->cache[$key] ) ) + $value = clone $this->cache[$key]; + else + $value = $this->cache[$key]; + } else if ( in_array($group, $this->no_mc_groups) ) { + $this->cache[$key] = $value = false; } else { - $value = $mc->get( $key ); - - if ( null === $value ) { - $value = false; - } - - $this->cache[ $key ] = $value; + $value = $mc->get($key); + if ( NULL === $value ) + $value = false; + $this->cache[$key] = $value; } - ++$this->stats['get']; - - $this->group_ops[ $group ][] = "get $id"; + @ ++$this->stats['get']; + $this->group_ops[$group][] = "get $id"; if ( 'checkthedatabaseplease' === $value ) { - unset( $this->cache[ $key ] ); - + unset( $this->cache[$key] ); $value = false; } @@ -305,291 +246,208 @@ function get_multi( $groups ) { format: $get['group-name'] = array( 'key1', 'key2' ); */ $return = array(); - foreach ( $groups as $group => $ids ) { - $mc =& $this->get_mc( $group ); - + $mc =& $this->get_mc($group); foreach ( $ids as $id ) { - $key = $this->key( $id, $group ); - - if ( isset( $this->cache[ $key ] ) ) { - if ( is_object( $this->cache[ $key ] ) ) { - $return[ $key ] = clone $this->cache[ $key ]; - } else { - $return[ $key ] = $this->cache[ $key ]; - } - + $key = $this->key($id, $group); + if ( isset($this->cache[$key]) ) { + if ( is_object( $this->cache[$key] ) ) + $return[$key] = clone $this->cache[$key]; + else + $return[$key] = $this->cache[$key]; continue; - } else if ( in_array( $group, $this->no_mc_groups ) ) { - $return[ $key ] = false; - + } else if ( in_array($group, $this->no_mc_groups) ) { + $return[$key] = false; continue; } else { - $return[ $key ] = $mc->get( $key ); + $return[$key] = $mc->get($key); } } - if ( $to_get ) { $vals = $mc->get_multi( $to_get ); - $return = array_merge( $return, $vals ); } } - - ++$this->stats['get_multi']; - - $this->group_ops[ $group ][] = "get_multi $id"; - + @ ++$this->stats['get_multi']; + $this->group_ops[$group][] = "get_multi $id"; $this->cache = array_merge( $this->cache, $return ); - return $return; } function flush_prefix( $group ) { - if ( 'WP_Object_Cache' === $group || 'WP_Object_Cache_global' === $group ) { + if ( $group === 'WP_Object_Cache' || $group === 'WP_Object_Cache_global' ) { // Never flush the flush numbers. $number = '_'; - } elseif ( false !== array_search( $group, $this->global_groups ) ) { - if ( ! isset( $this->global_flush_number ) ) { - $this->global_flush_number = intval( $this->get( 'flush_number', 'WP_Object_Cache_global' ) ); - } - - if ( 0 === $this->global_flush_number ) { + } elseif ( false !== array_search($group, $this->global_groups) ) { + if ( ! isset( $this->global_flush_number ) ) + $this->global_flush_number = intval( $this->get('flush_number', 'WP_Object_Cache_global') ); + if ( $this->global_flush_number === 0 ) $this->rotate_global_keys(); - } - $number = $this->global_flush_number; } else { - if ( ! isset( $this->flush_number[ $this->blog_prefix ] ) ) { - $this->flush_number[ $this->blog_prefix ] = intval( $this->get( 'flush_number', 'WP_Object_Cache' ) ); - } - - if ( 0 === $this->flush_number[ $this->blog_prefix ] ) { + if ( ! isset( $this->flush_number[ $this->blog_prefix ] ) ) + $this->flush_number[ $this->blog_prefix ] = intval( $this->get('flush_number', 'WP_Object_Cache') ); + if ( $this->flush_number[ $this->blog_prefix ] === 0 ) $this->rotate_site_keys(); - } - $number = $this->flush_number[ $this->blog_prefix ]; } - return $number . ':'; } - function key( $key, $group ) { - if ( empty( $group ) ) { + function key($key, $group) { + if ( empty($group) ) $group = 'default'; - } $prefix = $this->key_salt; $prefix .= $this->flush_prefix( $group ); - if ( false !== array_search( $group, $this->global_groups ) ) { + if ( false !== array_search($group, $this->global_groups) ) $prefix .= $this->global_prefix; - } else { + else $prefix .= $this->blog_prefix; - } - return preg_replace( '/\s+/', '', "$prefix:$group:$key" ); + return preg_replace('/\s+/', '', "$prefix:$group:$key"); } - function replace( $id, $data, $group = 'default', $expire = 0 ) { - $key = $this->key( $id, $group ); + function replace($id, $data, $group = 'default', $expire = 0) { + $key = $this->key($id, $group); + $expire = ($expire == 0) ? $this->default_expiration : $expire; + $mc =& $this->get_mc($group); - $expire = intval( $expire ); - if ( 0 === $expire || $expire > $this->max_expiration ) { - $expire = $this->default_expiration; - } - - $mc =& $this->get_mc( $group ); - - if ( is_object( $data ) ) { + if ( is_object( $data ) ) $data = clone $data; - } - - $result = $mc->replace( $key, $data, false, $expire ); - - if ( false !== $result ) { - $this->cache[ $key ] = $data; - } + $result = $mc->replace($key, $data, false, $expire); + if ( false !== $result ) + $this->cache[$key] = $data; return $result; } - function set( $id, $data, $group = 'default', $expire = 0 ) { - $key = $this->key( $id, $group ); - - if ( isset( $this->cache[ $key ] ) && ( 'checkthedatabaseplease' === $this->cache[ $key ] ) ) { + function set($id, $data, $group = 'default', $expire = 0) { + $key = $this->key($id, $group); + if ( isset($this->cache[$key]) && ('checkthedatabaseplease' === $this->cache[$key]) ) return false; - } - if ( is_object( $data ) ) { + if ( is_object($data) ) $data = clone $data; - } - $this->cache[ $key ] = $data; + $this->cache[$key] = $data; - if ( in_array( $group, $this->no_mc_groups ) ) { + if ( in_array($group, $this->no_mc_groups) ) return true; - } - - $expire = intval( $expire ); - if ( 0 === $expire || $expire > $this->max_expiration ) { - $expire = $this->default_expiration; - } - $mc =& $this->get_mc( $group ); - $result = $mc->set( $key, $data, false, $expire ); - - ++$this->stats[ 'set' ]; - $this->group_ops[$group][] = "set $id"; + $expire = ($expire == 0) ? $this->default_expiration : $expire; + $mc =& $this->get_mc($group); + $result = $mc->set($key, $data, false, $expire); return $result; } function switch_to_blog( $blog_id ) { global $table_prefix; - $blog_id = (int) $blog_id; - $this->blog_prefix = ( is_multisite() ? $blog_id : $table_prefix ); } - function colorize_debug_line( $line ) { + function colorize_debug_line($line) { $colors = array( 'get' => 'green', 'set' => 'purple', 'add' => 'blue', - 'delete' => 'red', - ); + 'delete' => 'red'); - $cmd = substr( $line, 0, strpos( $line, ' ' ) ); + $cmd = substr($line, 0, strpos($line, ' ')); $cmd2 = "$cmd"; - return $cmd2 . substr( $line, strlen( $cmd ) ) . "\n"; + return $cmd2 . substr($line, strlen($cmd)) . "\n"; } function stats() { - if ( $this->stats_callback && is_callable( $this->stats_callback ) ) { - return call_user_func( $this->stats_callback ); - } - echo "

    \n"; - foreach ( $this->stats as $stat => $n ) { echo "$stat $n"; echo "
    \n"; } - echo "

    \n"; - echo '

    Memcached:

    '; - + echo "

    Memcached:

    "; foreach ( $this->group_ops as $group => $ops ) { - if ( ! isset( $_GET['debug_queries'] ) && 500 < count( $ops ) ) { + if ( !isset($_GET['debug_queries']) && 500 < count($ops) ) { $ops = array_slice( $ops, 0, 500 ); echo "Too many to show! Show them anyway.\n"; } - echo "

    $group commands

    "; echo "
    \n";
    -
     			$lines = array();
    -
     			foreach ( $ops as $op ) {
    -				$lines[] = $this->colorize_debug_line( $op );
    +				$lines[] = $this->colorize_debug_line($op);
     			}
    -
    -			print_r( $lines );
    -
    +			print_r($lines);
     			echo "
    \n"; } } - function &get_mc( $group ) { - if ( isset( $this->mc[ $group ] ) ) { - return $this->mc[ $group ]; - } - + function &get_mc($group) { + if ( isset($this->mc[$group]) ) + return $this->mc[$group]; return $this->mc['default']; } - function failure_callback( $host, $port ) { - $this->connection_errors[] = array( - 'host' => $host, - 'port' => $port, - ); + function failure_callback($host, $port) { + //error_log("Connection failure for $host:$port\n", 3, '/tmp/memcached.txt'); } function salt_keys( $key_salt ) { - if ( strlen( $key_salt ) ) { + if ( strlen( $key_salt ) ) $this->key_salt = $key_salt . ':'; - } else { + else $this->key_salt = ''; - } } function __construct() { - $this->stats = array( - 'get' => 0, - 'get_multi' => 0, - 'add' => 0, - 'set' => 0, - 'delete' => 0, - ); - global $memcached_servers; - if ( isset( $memcached_servers ) ) { + if ( isset($memcached_servers) ) $buckets = $memcached_servers; - } else { - $buckets = array( '127.0.0.1:11211' ); - } - - reset( $buckets ); - - if ( is_int( key( $buckets ) ) ) { - $buckets = array( 'default' => $buckets ); - } + else + $buckets = array('127.0.0.1:11211'); - foreach ( $buckets as $bucket => $servers ) { - $this->mc[ $bucket ] = new Memcache(); + reset($buckets); + if ( is_int( key($buckets) ) ) + $buckets = array('default' => $buckets); + foreach ( $buckets as $bucket => $servers) { + $this->mc[$bucket] = new Memcache(); foreach ( $servers as $server ) { if ( 'unix://' == substr( $server, 0, 7 ) ) { $node = $server; $port = 0; } else { - list ( $node, $port ) = explode( ':', $server ); - - if ( ! $port ) { - $port = ini_get( 'memcache.default_port' ); - } - - $port = intval( $port ); - - if ( ! $port ) { + list ( $node, $port ) = explode(':', $server); + if ( !$port ) + $port = ini_get('memcache.default_port'); + $port = intval($port); + if ( !$port ) $port = 11211; - } } - - $this->mc[ $bucket ]->addServer( $node, $port, true, 1, 1, 15, true, array( $this, 'failure_callback' ) ); - $this->mc[ $bucket ]->setCompressThreshold( 20000, 0.2 ); + $this->mc[$bucket]->addServer($node, $port, true, 1, 1, 15, true, array($this, 'failure_callback')); + $this->mc[$bucket]->setCompressThreshold(20000, 0.2); } } global $blog_id, $table_prefix; - $this->global_prefix = ''; - $this->blog_prefix = ''; - + $this->blog_prefix = ''; if ( function_exists( 'is_multisite' ) ) { - $this->global_prefix = ( is_multisite() || defined( 'CUSTOM_USER_TABLE' ) && defined( 'CUSTOM_USER_META_TABLE' ) ) ? '' : $table_prefix; - $this->blog_prefix = ( is_multisite() ? $blog_id : $table_prefix ); + $this->global_prefix = ( is_multisite() || defined('CUSTOM_USER_TABLE') && defined('CUSTOM_USER_META_TABLE') ) ? '' : $table_prefix; + $this->blog_prefix = ( is_multisite() ? $blog_id : $table_prefix ); } $this->salt_keys( WP_CACHE_KEY_SALT ); - $this->cache_hits =& $this->stats['get']; + $this->cache_hits =& $this->stats['get']; $this->cache_misses =& $this->stats['add']; } } +?> From d868f7ff3a58423b539922f5ea31ff278b67df64 Mon Sep 17 00:00:00 2001 From: Tazo Todua Date: Thu, 7 Feb 2019 01:11:35 +0400 Subject: [PATCH 3/6] Update readme.txt --- readme.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/readme.txt b/readme.txt index f70f3ae..4dacc01 100644 --- a/readme.txt +++ b/readme.txt @@ -13,9 +13,8 @@ Memcached Object Cache provides a persistent backend for the WordPress object ca == Installation == 1. Install [memcached](http://danga.com/memcached) on at least one server. Note the connection info. The default is `127.0.0.1:11211`. -1. Install the [PECL memcache extension](http://pecl.php.net/package/memcache) +2. Install the [PECL memcache extension](http://pecl.php.net/package/memcache) -1. Copy object-cache.php to wp-content == Frequently Asked Questions == From e6ed47de3375bcb7de2f59eeb7b6757694b13d7b Mon Sep 17 00:00:00 2001 From: Tazo Todua Date: Thu, 7 Feb 2019 01:20:39 +0400 Subject: [PATCH 4/6] Update object-cache.php --- object-cache.php | 484 +++++++++++++++++++++++------------------------ 1 file changed, 233 insertions(+), 251 deletions(-) diff --git a/object-cache.php b/object-cache.php index 40741e4..491dd48 100644 --- a/object-cache.php +++ b/object-cache.php @@ -1,195 +1,174 @@ add($key, $data, $group, $expire); + return $wp_object_cache->add( $key, $data, $group, $expire ); } - -function wp_cache_incr($key, $n = 1, $group = '') { +function wp_cache_incr( $key, $n = 1, $group = '' ) { global $wp_object_cache; - - return $wp_object_cache->incr($key, $n, $group); + return $wp_object_cache->incr( $key, $n, $group ); } - -function wp_cache_decr($key, $n = 1, $group = '') { +function wp_cache_decr( $key, $n = 1, $group = '' ) { global $wp_object_cache; - - return $wp_object_cache->decr($key, $n, $group); + return $wp_object_cache->decr( $key, $n, $group ); } - function wp_cache_close() { global $wp_object_cache; - return $wp_object_cache->close(); } - -function wp_cache_delete($key, $group = '') { +function wp_cache_delete( $key, $group = '' ) { global $wp_object_cache; - - return $wp_object_cache->delete($key, $group); + return $wp_object_cache->delete( $key, $group ); } - function wp_cache_flush() { global $wp_object_cache; - return $wp_object_cache->flush(); } - -function wp_cache_get($key, $group = '', $force = false) { +function wp_cache_get( $key, $group = '', $force = false ) { global $wp_object_cache; - - return $wp_object_cache->get($key, $group, $force); + return $wp_object_cache->get( $key, $group, $force ); +} +/** + * Retrieve multiple cache entries + * + * @param array $groups Array of arrays, of groups and keys to retrieve + * @return mixed + */ +function wp_cache_get_multi( $groups ) { + global $wp_object_cache; + return $wp_object_cache->get_multi( $groups ); } - function wp_cache_init() { global $wp_object_cache; - $wp_object_cache = new WP_Object_Cache(); } - -function wp_cache_replace($key, $data, $group = '', $expire = 0) { +function wp_cache_replace( $key, $data, $group = '', $expire = 0 ) { global $wp_object_cache; - - return $wp_object_cache->replace($key, $data, $group, $expire); + return $wp_object_cache->replace( $key, $data, $group, $expire ); } - -function wp_cache_set($key, $data, $group = '', $expire = 0) { +function wp_cache_set( $key, $data, $group = '', $expire = 0 ) { global $wp_object_cache; - - if ( defined('WP_INSTALLING') == false ) - return $wp_object_cache->set($key, $data, $group, $expire); - else - return $wp_object_cache->delete($key, $group); + if ( defined( 'WP_INSTALLING' ) == false ) { + return $wp_object_cache->set( $key, $data, $group, $expire ); + } else { + return $wp_object_cache->delete( $key, $group ); + } } - function wp_cache_switch_to_blog( $blog_id ) { global $wp_object_cache; - return $wp_object_cache->switch_to_blog( $blog_id ); } - function wp_cache_add_global_groups( $groups ) { global $wp_object_cache; - - $wp_object_cache->add_global_groups($groups); + $wp_object_cache->add_global_groups( $groups ); } - function wp_cache_add_non_persistent_groups( $groups ) { global $wp_object_cache; - - $wp_object_cache->add_non_persistent_groups($groups); + $wp_object_cache->add_non_persistent_groups( $groups ); } - class WP_Object_Cache { var $global_groups = array( 'WP_Object_Cache_global' ); - var $no_mc_groups = array(); - - var $cache = array(); - var $mc = array(); - var $stats = array(); + var $cache = array(); + var $mc = array(); + var $stats = array(); var $group_ops = array(); - var $flush_number = array(); + var $flush_number = array(); var $global_flush_number = null; - - var $cache_enabled = true; + var $cache_enabled = true; var $default_expiration = 0; - - function add($id, $data, $group = 'default', $expire = 0) { - $key = $this->key($id, $group); - - if ( is_object( $data ) ) + var $max_expiration = 2592000; // 30 days + var $stats_callback = null; + var $connection_errors = array(); + function add( $id, $data, $group = 'default', $expire = 0 ) { + $key = $this->key( $id, $group ); + if ( is_object( $data ) ) { $data = clone $data; - - if ( in_array($group, $this->no_mc_groups) ) { - $this->cache[$key] = $data; + } + if ( in_array( $group, $this->no_mc_groups ) ) { + $this->cache[ $key ] = $data; return true; - } elseif ( isset($this->cache[$key]) && $this->cache[$key] !== false ) { + } elseif ( isset( $this->cache[ $key ] ) && false !== $this->cache[ $key ] ) { return false; } - - $mc =& $this->get_mc($group); - $expire = ($expire == 0) ? $this->default_expiration : $expire; - $result = $mc->add($key, $data, false, $expire); - + $mc =& $this->get_mc( $group ); + $expire = intval( $expire ); + if ( 0 === $expire || $expire > $this->max_expiration ) { + $expire = $this->default_expiration; + } + $result = $mc->add( $key, $data, false, $expire ); if ( false !== $result ) { - @ ++$this->stats['add']; - $this->group_ops[$group][] = "add $id"; - $this->cache[$key] = $data; + ++$this->stats['add']; + $this->group_ops[ $group ][] = "add $id"; + $this->cache[ $key ] = $data; + } else if ( false === $result && true === isset( $this->cache[$key] ) && false === $this->cache[$key] ) { + /* + * Here we unset local cache if remote add failed and local cache value is equal to `false` in order + * to update the local cache anytime we get a new information from remote server. This way, the next + * cache get will go to remote server and will fetch recent data. + */ + unset( $this->cache[$key] ); } - return $result; } - - function add_global_groups($groups) { - if ( ! is_array($groups) ) + function add_global_groups( $groups ) { + if ( ! is_array( $groups ) ) { $groups = (array) $groups; - - $this->global_groups = array_merge($this->global_groups, $groups); - $this->global_groups = array_unique($this->global_groups); + } + $this->global_groups = array_merge( $this->global_groups, $groups ); + $this->global_groups = array_unique( $this->global_groups ); } - - function add_non_persistent_groups($groups) { - if ( ! is_array($groups) ) + function add_non_persistent_groups( $groups ) { + if ( ! is_array( $groups ) ) { $groups = (array) $groups; - - $this->no_mc_groups = array_merge($this->no_mc_groups, $groups); - $this->no_mc_groups = array_unique($this->no_mc_groups); + } + $this->no_mc_groups = array_merge( $this->no_mc_groups, $groups ); + $this->no_mc_groups = array_unique( $this->no_mc_groups ); } - - function incr($id, $n = 1, $group = 'default' ) { - $key = $this->key($id, $group); - $mc =& $this->get_mc($group); + function incr( $id, $n = 1, $group = 'default' ) { + $key = $this->key( $id, $group ); + $mc =& $this->get_mc( $group ); $this->cache[ $key ] = $mc->increment( $key, $n ); return $this->cache[ $key ]; } - - function decr($id, $n = 1, $group = 'default' ) { - $key = $this->key($id, $group); - $mc =& $this->get_mc($group); + function decr( $id, $n = 1, $group = 'default' ) { + $key = $this->key( $id, $group ); + $mc =& $this->get_mc( $group ); $this->cache[ $key ] = $mc->decrement( $key, $n ); return $this->cache[ $key ]; } - function close() { - - foreach ( $this->mc as $bucket => $mc ) + foreach ( $this->mc as $bucket => $mc ) { $mc->close(); + } } - - function delete($id, $group = 'default') { - $key = $this->key($id, $group); - - if ( in_array($group, $this->no_mc_groups) ) { - unset($this->cache[$key]); + function delete( $id, $group = 'default' ) { + $key = $this->key( $id, $group ); + if ( in_array( $group, $this->no_mc_groups ) ) { + unset( $this->cache[ $key ] ); return true; } - - $mc =& $this->get_mc($group); - - $result = $mc->delete($key); - - @ ++$this->stats['delete']; - $this->group_ops[$group][] = "delete $id"; - - if ( false !== $result ) - unset($this->cache[$key]); - + $mc =& $this->get_mc( $group ); + $result = $mc->delete( $key ); + ++$this->stats['delete']; + $this->group_ops[ $group ][] = "delete $id"; + if ( false !== $result ) { + unset( $this->cache[ $key ] ); + } return $result; } - function flush() { // Do not use the memcached flush method. It acts on an // entire memcached server, affecting all sites. @@ -198,69 +177,65 @@ function flush() { // Global keys are rotated when flushing on the main site. $this->cache = array(); $this->rotate_site_keys(); - if ( is_main_site() ) + if ( is_main_site() ) { $this->rotate_global_keys(); + } } - function rotate_site_keys() { - $this->add( 'flush_number', intval(microtime(true) * 1e6), 'WP_Object_Cache' ); + $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache' ); $this->flush_number[ $this->blog_prefix ] = $this->incr( 'flush_number', 1, 'WP_Object_Cache' ); } - function rotate_global_keys() { - $this->add( 'flush_number', intval(microtime(true) * 1e6), 'WP_Object_Cache_global' ); + $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache_global' ); $this->global_flush_number = $this->incr( 'flush_number', 1, 'WP_Object_Cache_global' ); } - - function get($id, $group = 'default', $force = false) { - $key = $this->key($id, $group); - $mc =& $this->get_mc($group); - - if ( isset($this->cache[$key]) && ( !$force || in_array($group, $this->no_mc_groups) ) ) { - if ( is_object( $this->cache[$key] ) ) - $value = clone $this->cache[$key]; - else - $value = $this->cache[$key]; - } else if ( in_array($group, $this->no_mc_groups) ) { - $this->cache[$key] = $value = false; + function get( $id, $group = 'default', $force = false ) { + $key = $this->key( $id, $group ); + $mc =& $this->get_mc( $group ); + if ( isset( $this->cache[ $key ] ) && ( ! $force || in_array( $group, $this->no_mc_groups ) ) ) { + if ( is_object( $this->cache[ $key ] ) ) { + $value = clone $this->cache[ $key ]; + } else { + $value = $this->cache[ $key ]; + } + } else if ( in_array( $group, $this->no_mc_groups ) ) { + $this->cache[ $key ] = $value = false; } else { - $value = $mc->get($key); - if ( NULL === $value ) - $value = false; - $this->cache[$key] = $value; + $value = $mc->get( $key ); + if ( null === $value ) { + $value = false; + } + $this->cache[ $key ] = $value; } - - @ ++$this->stats['get']; - $this->group_ops[$group][] = "get $id"; - + ++$this->stats['get']; + $this->group_ops[ $group ][] = "get $id"; if ( 'checkthedatabaseplease' === $value ) { - unset( $this->cache[$key] ); + unset( $this->cache[ $key ] ); $value = false; } - return $value; } - function get_multi( $groups ) { /* format: $get['group-name'] = array( 'key1', 'key2' ); */ $return = array(); foreach ( $groups as $group => $ids ) { - $mc =& $this->get_mc($group); + $mc =& $this->get_mc( $group ); foreach ( $ids as $id ) { - $key = $this->key($id, $group); - if ( isset($this->cache[$key]) ) { - if ( is_object( $this->cache[$key] ) ) - $return[$key] = clone $this->cache[$key]; - else - $return[$key] = $this->cache[$key]; + $key = $this->key( $id, $group ); + if ( isset( $this->cache[ $key ] ) ) { + if ( is_object( $this->cache[ $key ] ) ) { + $return[ $key ] = clone $this->cache[ $key ]; + } else { + $return[ $key ] = $this->cache[ $key ]; + } continue; - } else if ( in_array($group, $this->no_mc_groups) ) { - $return[$key] = false; + } else if ( in_array( $group, $this->no_mc_groups ) ) { + $return[ $key ] = false; continue; } else { - $return[$key] = $mc->get($key); + $return[ $key ] = $mc->get( $key ); } } if ( $to_get ) { @@ -268,112 +243,114 @@ function get_multi( $groups ) { $return = array_merge( $return, $vals ); } } - @ ++$this->stats['get_multi']; - $this->group_ops[$group][] = "get_multi $id"; + ++$this->stats['get_multi']; + $this->group_ops[ $group ][] = "get_multi $id"; $this->cache = array_merge( $this->cache, $return ); return $return; } - function flush_prefix( $group ) { - if ( $group === 'WP_Object_Cache' || $group === 'WP_Object_Cache_global' ) { + if ( 'WP_Object_Cache' === $group || 'WP_Object_Cache_global' === $group ) { // Never flush the flush numbers. $number = '_'; - } elseif ( false !== array_search($group, $this->global_groups) ) { - if ( ! isset( $this->global_flush_number ) ) - $this->global_flush_number = intval( $this->get('flush_number', 'WP_Object_Cache_global') ); - if ( $this->global_flush_number === 0 ) + } elseif ( false !== array_search( $group, $this->global_groups ) ) { + if ( ! isset( $this->global_flush_number ) ) { + $this->global_flush_number = intval( $this->get( 'flush_number', 'WP_Object_Cache_global' ) ); + } + if ( 0 === $this->global_flush_number ) { $this->rotate_global_keys(); + } $number = $this->global_flush_number; } else { - if ( ! isset( $this->flush_number[ $this->blog_prefix ] ) ) - $this->flush_number[ $this->blog_prefix ] = intval( $this->get('flush_number', 'WP_Object_Cache') ); - if ( $this->flush_number[ $this->blog_prefix ] === 0 ) + if ( ! isset( $this->flush_number[ $this->blog_prefix ] ) ) { + $this->flush_number[ $this->blog_prefix ] = intval( $this->get( 'flush_number', 'WP_Object_Cache' ) ); + } + if ( 0 === $this->flush_number[ $this->blog_prefix ] ) { $this->rotate_site_keys(); + } $number = $this->flush_number[ $this->blog_prefix ]; } return $number . ':'; } - - function key($key, $group) { - if ( empty($group) ) + function key( $key, $group ) { + if ( empty( $group ) ) { $group = 'default'; - + } $prefix = $this->key_salt; - $prefix .= $this->flush_prefix( $group ); - - if ( false !== array_search($group, $this->global_groups) ) + if ( false !== array_search( $group, $this->global_groups ) ) { $prefix .= $this->global_prefix; - else + } else { $prefix .= $this->blog_prefix; - - return preg_replace('/\s+/', '', "$prefix:$group:$key"); + } + return preg_replace( '/\s+/', '', "$prefix:$group:$key" ); } - - function replace($id, $data, $group = 'default', $expire = 0) { - $key = $this->key($id, $group); - $expire = ($expire == 0) ? $this->default_expiration : $expire; - $mc =& $this->get_mc($group); - - if ( is_object( $data ) ) + function replace( $id, $data, $group = 'default', $expire = 0 ) { + $key = $this->key( $id, $group ); + $expire = intval( $expire ); + if ( 0 === $expire || $expire > $this->max_expiration ) { + $expire = $this->default_expiration; + } + $mc =& $this->get_mc( $group ); + if ( is_object( $data ) ) { $data = clone $data; - - $result = $mc->replace($key, $data, false, $expire); - if ( false !== $result ) - $this->cache[$key] = $data; + } + $result = $mc->replace( $key, $data, false, $expire ); + if ( false !== $result ) { + $this->cache[ $key ] = $data; + } return $result; } - - function set($id, $data, $group = 'default', $expire = 0) { - $key = $this->key($id, $group); - if ( isset($this->cache[$key]) && ('checkthedatabaseplease' === $this->cache[$key]) ) + function set( $id, $data, $group = 'default', $expire = 0 ) { + $key = $this->key( $id, $group ); + if ( isset( $this->cache[ $key ] ) && ( 'checkthedatabaseplease' === $this->cache[ $key ] ) ) { return false; - - if ( is_object($data) ) + } + if ( is_object( $data ) ) { $data = clone $data; - - $this->cache[$key] = $data; - - if ( in_array($group, $this->no_mc_groups) ) + } + $this->cache[ $key ] = $data; + if ( in_array( $group, $this->no_mc_groups ) ) { return true; - - $expire = ($expire == 0) ? $this->default_expiration : $expire; - $mc =& $this->get_mc($group); - $result = $mc->set($key, $data, false, $expire); - + } + $expire = intval( $expire ); + if ( 0 === $expire || $expire > $this->max_expiration ) { + $expire = $this->default_expiration; + } + $mc =& $this->get_mc( $group ); + $result = $mc->set( $key, $data, false, $expire ); + ++$this->stats[ 'set' ]; + $this->group_ops[$group][] = "set $id"; return $result; } - function switch_to_blog( $blog_id ) { global $table_prefix; $blog_id = (int) $blog_id; $this->blog_prefix = ( is_multisite() ? $blog_id : $table_prefix ); } - - function colorize_debug_line($line) { + function colorize_debug_line( $line ) { $colors = array( 'get' => 'green', 'set' => 'purple', 'add' => 'blue', - 'delete' => 'red'); - - $cmd = substr($line, 0, strpos($line, ' ')); - + 'delete' => 'red', + ); + $cmd = substr( $line, 0, strpos( $line, ' ' ) ); $cmd2 = "$cmd"; - - return $cmd2 . substr($line, strlen($cmd)) . "\n"; + return $cmd2 . substr( $line, strlen( $cmd ) ) . "\n"; } - function stats() { + if ( $this->stats_callback && is_callable( $this->stats_callback ) ) { + return call_user_func( $this->stats_callback ); + } echo "

    \n"; foreach ( $this->stats as $stat => $n ) { echo "$stat $n"; echo "
    \n"; } echo "

    \n"; - echo "

    Memcached:

    "; + echo '

    Memcached:

    '; foreach ( $this->group_ops as $group => $ops ) { - if ( !isset($_GET['debug_queries']) && 500 < count($ops) ) { + if ( ! isset( $_GET['debug_queries'] ) && 500 < count( $ops ) ) { $ops = array_slice( $ops, 0, 500 ); echo "Too many to show! Show them anyway.\n"; } @@ -381,73 +358,78 @@ function stats() { echo "
    \n";
     			$lines = array();
     			foreach ( $ops as $op ) {
    -				$lines[] = $this->colorize_debug_line($op);
    +				$lines[] = $this->colorize_debug_line( $op );
     			}
    -			print_r($lines);
    +			print_r( $lines );
     			echo "
    \n"; } } - - function &get_mc($group) { - if ( isset($this->mc[$group]) ) - return $this->mc[$group]; + function &get_mc( $group ) { + if ( isset( $this->mc[ $group ] ) ) { + return $this->mc[ $group ]; + } return $this->mc['default']; } - - function failure_callback($host, $port) { - //error_log("Connection failure for $host:$port\n", 3, '/tmp/memcached.txt'); + function failure_callback( $host, $port ) { + $this->connection_errors[] = array( + 'host' => $host, + 'port' => $port, + ); } - function salt_keys( $key_salt ) { - if ( strlen( $key_salt ) ) + if ( strlen( $key_salt ) ) { $this->key_salt = $key_salt . ':'; - else + } else { $this->key_salt = ''; + } } - function __construct() { + $this->stats = array( + 'get' => 0, + 'get_multi' => 0, + 'add' => 0, + 'set' => 0, + 'delete' => 0, + ); global $memcached_servers; - - if ( isset($memcached_servers) ) + if ( isset( $memcached_servers ) ) { $buckets = $memcached_servers; - else - $buckets = array('127.0.0.1:11211'); - - reset($buckets); - if ( is_int( key($buckets) ) ) - $buckets = array('default' => $buckets); - - foreach ( $buckets as $bucket => $servers) { - $this->mc[$bucket] = new Memcache(); + } else { + $buckets = array( '127.0.0.1:11211' ); + } + reset( $buckets ); + if ( is_int( key( $buckets ) ) ) { + $buckets = array( 'default' => $buckets ); + } + foreach ( $buckets as $bucket => $servers ) { + $this->mc[ $bucket ] = new Memcache(); foreach ( $servers as $server ) { if ( 'unix://' == substr( $server, 0, 7 ) ) { $node = $server; $port = 0; } else { - list ( $node, $port ) = explode(':', $server); - if ( !$port ) - $port = ini_get('memcache.default_port'); - $port = intval($port); - if ( !$port ) + list ( $node, $port ) = explode( ':', $server ); + if ( ! $port ) { + $port = ini_get( 'memcache.default_port' ); + } + $port = intval( $port ); + if ( ! $port ) { $port = 11211; + } } - $this->mc[$bucket]->addServer($node, $port, true, 1, 1, 15, true, array($this, 'failure_callback')); - $this->mc[$bucket]->setCompressThreshold(20000, 0.2); + $this->mc[ $bucket ]->addServer( $node, $port, true, 1, 1, 15, true, array( $this, 'failure_callback' ) ); + $this->mc[ $bucket ]->setCompressThreshold( 20000, 0.2 ); } } - global $blog_id, $table_prefix; $this->global_prefix = ''; - $this->blog_prefix = ''; + $this->blog_prefix = ''; if ( function_exists( 'is_multisite' ) ) { - $this->global_prefix = ( is_multisite() || defined('CUSTOM_USER_TABLE') && defined('CUSTOM_USER_META_TABLE') ) ? '' : $table_prefix; - $this->blog_prefix = ( is_multisite() ? $blog_id : $table_prefix ); + $this->global_prefix = ( is_multisite() || defined( 'CUSTOM_USER_TABLE' ) && defined( 'CUSTOM_USER_META_TABLE' ) ) ? '' : $table_prefix; + $this->blog_prefix = ( is_multisite() ? $blog_id : $table_prefix ); } - $this->salt_keys( WP_CACHE_KEY_SALT ); - - $this->cache_hits =& $this->stats['get']; + $this->cache_hits =& $this->stats['get']; $this->cache_misses =& $this->stats['add']; } } -?> From 99d0a5a9875a447d168715a5a9a5b19903ba0cfa Mon Sep 17 00:00:00 2001 From: Tazo Todua Date: Thu, 7 Feb 2019 01:24:05 +0400 Subject: [PATCH 5/6] Update object-cache.php --- object-cache.php | 159 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 157 insertions(+), 2 deletions(-) diff --git a/object-cache.php b/object-cache.php index 491dd48..e32f276 100644 --- a/object-cache.php +++ b/object-cache.php @@ -5,41 +5,54 @@ if ( !defined( 'WP_MEMCHACED_PLUGIN_USED' ) ) define( 'WP_MEMCHACED_PLUGIN_USED', true ); - - // Users with setups where multiple installs share a common wp-config.php or $table_prefix // can use this to guarantee uniqueness for the keys generated by this object cache if ( ! defined( 'WP_CACHE_KEY_SALT' ) ) { define( 'WP_CACHE_KEY_SALT', '' ); } + function wp_cache_add( $key, $data, $group = '', $expire = 0 ) { global $wp_object_cache; + return $wp_object_cache->add( $key, $data, $group, $expire ); } + function wp_cache_incr( $key, $n = 1, $group = '' ) { global $wp_object_cache; + return $wp_object_cache->incr( $key, $n, $group ); } + function wp_cache_decr( $key, $n = 1, $group = '' ) { global $wp_object_cache; + return $wp_object_cache->decr( $key, $n, $group ); } + function wp_cache_close() { global $wp_object_cache; + return $wp_object_cache->close(); } + function wp_cache_delete( $key, $group = '' ) { global $wp_object_cache; + return $wp_object_cache->delete( $key, $group ); } + function wp_cache_flush() { global $wp_object_cache; + return $wp_object_cache->flush(); } + function wp_cache_get( $key, $group = '', $force = false ) { global $wp_object_cache; + return $wp_object_cache->get( $key, $group, $force ); } + /** * Retrieve multiple cache entries * @@ -48,69 +61,98 @@ function wp_cache_get( $key, $group = '', $force = false ) { */ function wp_cache_get_multi( $groups ) { global $wp_object_cache; + return $wp_object_cache->get_multi( $groups ); } + function wp_cache_init() { global $wp_object_cache; + $wp_object_cache = new WP_Object_Cache(); } + function wp_cache_replace( $key, $data, $group = '', $expire = 0 ) { global $wp_object_cache; + return $wp_object_cache->replace( $key, $data, $group, $expire ); } + function wp_cache_set( $key, $data, $group = '', $expire = 0 ) { global $wp_object_cache; + if ( defined( 'WP_INSTALLING' ) == false ) { return $wp_object_cache->set( $key, $data, $group, $expire ); } else { return $wp_object_cache->delete( $key, $group ); } } + function wp_cache_switch_to_blog( $blog_id ) { global $wp_object_cache; + return $wp_object_cache->switch_to_blog( $blog_id ); } + function wp_cache_add_global_groups( $groups ) { global $wp_object_cache; + $wp_object_cache->add_global_groups( $groups ); } + function wp_cache_add_non_persistent_groups( $groups ) { global $wp_object_cache; + $wp_object_cache->add_non_persistent_groups( $groups ); } + class WP_Object_Cache { var $global_groups = array( 'WP_Object_Cache_global' ); + var $no_mc_groups = array(); + var $cache = array(); var $mc = array(); var $stats = array(); var $group_ops = array(); + var $flush_number = array(); var $global_flush_number = null; + var $cache_enabled = true; var $default_expiration = 0; var $max_expiration = 2592000; // 30 days + var $stats_callback = null; + var $connection_errors = array(); + function add( $id, $data, $group = 'default', $expire = 0 ) { $key = $this->key( $id, $group ); + if ( is_object( $data ) ) { $data = clone $data; } + if ( in_array( $group, $this->no_mc_groups ) ) { $this->cache[ $key ] = $data; + return true; } elseif ( isset( $this->cache[ $key ] ) && false !== $this->cache[ $key ] ) { return false; } + $mc =& $this->get_mc( $group ); + $expire = intval( $expire ); if ( 0 === $expire || $expire > $this->max_expiration ) { $expire = $this->default_expiration; } + $result = $mc->add( $key, $data, false, $expire ); + if ( false !== $result ) { ++$this->stats['add']; + $this->group_ops[ $group ][] = "add $id"; $this->cache[ $key ] = $data; } else if ( false === $result && true === isset( $this->cache[$key] ) && false === $this->cache[$key] ) { @@ -121,54 +163,76 @@ function add( $id, $data, $group = 'default', $expire = 0 ) { */ unset( $this->cache[$key] ); } + return $result; } + function add_global_groups( $groups ) { if ( ! is_array( $groups ) ) { $groups = (array) $groups; } + $this->global_groups = array_merge( $this->global_groups, $groups ); $this->global_groups = array_unique( $this->global_groups ); } + function add_non_persistent_groups( $groups ) { if ( ! is_array( $groups ) ) { $groups = (array) $groups; } + $this->no_mc_groups = array_merge( $this->no_mc_groups, $groups ); $this->no_mc_groups = array_unique( $this->no_mc_groups ); } + function incr( $id, $n = 1, $group = 'default' ) { $key = $this->key( $id, $group ); $mc =& $this->get_mc( $group ); + $this->cache[ $key ] = $mc->increment( $key, $n ); + return $this->cache[ $key ]; } + function decr( $id, $n = 1, $group = 'default' ) { $key = $this->key( $id, $group ); $mc =& $this->get_mc( $group ); + $this->cache[ $key ] = $mc->decrement( $key, $n ); + return $this->cache[ $key ]; } + function close() { foreach ( $this->mc as $bucket => $mc ) { $mc->close(); } } + function delete( $id, $group = 'default' ) { $key = $this->key( $id, $group ); + if ( in_array( $group, $this->no_mc_groups ) ) { unset( $this->cache[ $key ] ); + return true; } + $mc =& $this->get_mc( $group ); + $result = $mc->delete( $key ); + ++$this->stats['delete']; + $this->group_ops[ $group ][] = "delete $id"; + if ( false !== $result ) { unset( $this->cache[ $key ] ); } + return $result; } + function flush() { // Do not use the memcached flush method. It acts on an // entire memcached server, affecting all sites. @@ -176,22 +240,30 @@ function flush() { // Instead, rotate the key prefix for the current site. // Global keys are rotated when flushing on the main site. $this->cache = array(); + $this->rotate_site_keys(); + if ( is_main_site() ) { $this->rotate_global_keys(); } } + function rotate_site_keys() { $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache' ); + $this->flush_number[ $this->blog_prefix ] = $this->incr( 'flush_number', 1, 'WP_Object_Cache' ); } + function rotate_global_keys() { $this->add( 'flush_number', intval( microtime( true ) * 1e6 ), 'WP_Object_Cache_global' ); + $this->global_flush_number = $this->incr( 'flush_number', 1, 'WP_Object_Cache_global' ); } + function get( $id, $group = 'default', $force = false ) { $key = $this->key( $id, $group ); $mc =& $this->get_mc( $group ); + if ( isset( $this->cache[ $key ] ) && ( ! $force || in_array( $group, $this->no_mc_groups ) ) ) { if ( is_object( $this->cache[ $key ] ) ) { $value = clone $this->cache[ $key ]; @@ -202,52 +274,72 @@ function get( $id, $group = 'default', $force = false ) { $this->cache[ $key ] = $value = false; } else { $value = $mc->get( $key ); + if ( null === $value ) { $value = false; } + $this->cache[ $key ] = $value; } + ++$this->stats['get']; + $this->group_ops[ $group ][] = "get $id"; + if ( 'checkthedatabaseplease' === $value ) { unset( $this->cache[ $key ] ); + $value = false; } + return $value; } + function get_multi( $groups ) { /* format: $get['group-name'] = array( 'key1', 'key2' ); */ $return = array(); + foreach ( $groups as $group => $ids ) { $mc =& $this->get_mc( $group ); + foreach ( $ids as $id ) { $key = $this->key( $id, $group ); + if ( isset( $this->cache[ $key ] ) ) { if ( is_object( $this->cache[ $key ] ) ) { $return[ $key ] = clone $this->cache[ $key ]; } else { $return[ $key ] = $this->cache[ $key ]; } + continue; } else if ( in_array( $group, $this->no_mc_groups ) ) { $return[ $key ] = false; + continue; } else { $return[ $key ] = $mc->get( $key ); } } + if ( $to_get ) { $vals = $mc->get_multi( $to_get ); + $return = array_merge( $return, $vals ); } } + ++$this->stats['get_multi']; + $this->group_ops[ $group ][] = "get_multi $id"; + $this->cache = array_merge( $this->cache, $return ); + return $return; } + function flush_prefix( $group ) { if ( 'WP_Object_Cache' === $group || 'WP_Object_Cache_global' === $group ) { // Never flush the flush numbers. @@ -256,77 +348,107 @@ function flush_prefix( $group ) { if ( ! isset( $this->global_flush_number ) ) { $this->global_flush_number = intval( $this->get( 'flush_number', 'WP_Object_Cache_global' ) ); } + if ( 0 === $this->global_flush_number ) { $this->rotate_global_keys(); } + $number = $this->global_flush_number; } else { if ( ! isset( $this->flush_number[ $this->blog_prefix ] ) ) { $this->flush_number[ $this->blog_prefix ] = intval( $this->get( 'flush_number', 'WP_Object_Cache' ) ); } + if ( 0 === $this->flush_number[ $this->blog_prefix ] ) { $this->rotate_site_keys(); } + $number = $this->flush_number[ $this->blog_prefix ]; } + return $number . ':'; } + function key( $key, $group ) { if ( empty( $group ) ) { $group = 'default'; } + $prefix = $this->key_salt; + $prefix .= $this->flush_prefix( $group ); + if ( false !== array_search( $group, $this->global_groups ) ) { $prefix .= $this->global_prefix; } else { $prefix .= $this->blog_prefix; } + return preg_replace( '/\s+/', '', "$prefix:$group:$key" ); } + function replace( $id, $data, $group = 'default', $expire = 0 ) { $key = $this->key( $id, $group ); + $expire = intval( $expire ); if ( 0 === $expire || $expire > $this->max_expiration ) { $expire = $this->default_expiration; } + $mc =& $this->get_mc( $group ); + if ( is_object( $data ) ) { $data = clone $data; } + $result = $mc->replace( $key, $data, false, $expire ); + if ( false !== $result ) { $this->cache[ $key ] = $data; } + return $result; } + function set( $id, $data, $group = 'default', $expire = 0 ) { $key = $this->key( $id, $group ); + if ( isset( $this->cache[ $key ] ) && ( 'checkthedatabaseplease' === $this->cache[ $key ] ) ) { return false; } + if ( is_object( $data ) ) { $data = clone $data; } + $this->cache[ $key ] = $data; + if ( in_array( $group, $this->no_mc_groups ) ) { return true; } + $expire = intval( $expire ); if ( 0 === $expire || $expire > $this->max_expiration ) { $expire = $this->default_expiration; } + $mc =& $this->get_mc( $group ); $result = $mc->set( $key, $data, false, $expire ); + ++$this->stats[ 'set' ]; $this->group_ops[$group][] = "set $id"; + return $result; } + function switch_to_blog( $blog_id ) { global $table_prefix; + $blog_id = (int) $blog_id; + $this->blog_prefix = ( is_multisite() ? $blog_id : $table_prefix ); } + function colorize_debug_line( $line ) { $colors = array( 'get' => 'green', @@ -334,48 +456,65 @@ function colorize_debug_line( $line ) { 'add' => 'blue', 'delete' => 'red', ); + $cmd = substr( $line, 0, strpos( $line, ' ' ) ); + $cmd2 = "$cmd"; + return $cmd2 . substr( $line, strlen( $cmd ) ) . "\n"; } + function stats() { if ( $this->stats_callback && is_callable( $this->stats_callback ) ) { return call_user_func( $this->stats_callback ); } + echo "

    \n"; + foreach ( $this->stats as $stat => $n ) { echo "$stat $n"; echo "
    \n"; } + echo "

    \n"; echo '

    Memcached:

    '; + foreach ( $this->group_ops as $group => $ops ) { if ( ! isset( $_GET['debug_queries'] ) && 500 < count( $ops ) ) { $ops = array_slice( $ops, 0, 500 ); echo "Too many to show! Show them anyway.\n"; } + echo "

    $group commands

    "; echo "
    \n";
    +
     			$lines = array();
    +
     			foreach ( $ops as $op ) {
     				$lines[] = $this->colorize_debug_line( $op );
     			}
    +
     			print_r( $lines );
    +
     			echo "
    \n"; } } + function &get_mc( $group ) { if ( isset( $this->mc[ $group ] ) ) { return $this->mc[ $group ]; } + return $this->mc['default']; } + function failure_callback( $host, $port ) { $this->connection_errors[] = array( 'host' => $host, 'port' => $port, ); } + function salt_keys( $key_salt ) { if ( strlen( $key_salt ) ) { $this->key_salt = $key_salt . ':'; @@ -383,6 +522,7 @@ function salt_keys( $key_salt ) { $this->key_salt = ''; } } + function __construct() { $this->stats = array( 'get' => 0, @@ -391,44 +531,59 @@ function __construct() { 'set' => 0, 'delete' => 0, ); + global $memcached_servers; + if ( isset( $memcached_servers ) ) { $buckets = $memcached_servers; } else { $buckets = array( '127.0.0.1:11211' ); } + reset( $buckets ); + if ( is_int( key( $buckets ) ) ) { $buckets = array( 'default' => $buckets ); } + foreach ( $buckets as $bucket => $servers ) { $this->mc[ $bucket ] = new Memcache(); + foreach ( $servers as $server ) { if ( 'unix://' == substr( $server, 0, 7 ) ) { $node = $server; $port = 0; } else { list ( $node, $port ) = explode( ':', $server ); + if ( ! $port ) { $port = ini_get( 'memcache.default_port' ); } + $port = intval( $port ); + if ( ! $port ) { $port = 11211; } } + $this->mc[ $bucket ]->addServer( $node, $port, true, 1, 1, 15, true, array( $this, 'failure_callback' ) ); $this->mc[ $bucket ]->setCompressThreshold( 20000, 0.2 ); } } + global $blog_id, $table_prefix; + $this->global_prefix = ''; $this->blog_prefix = ''; + if ( function_exists( 'is_multisite' ) ) { $this->global_prefix = ( is_multisite() || defined( 'CUSTOM_USER_TABLE' ) && defined( 'CUSTOM_USER_META_TABLE' ) ) ? '' : $table_prefix; $this->blog_prefix = ( is_multisite() ? $blog_id : $table_prefix ); } + $this->salt_keys( WP_CACHE_KEY_SALT ); + $this->cache_hits =& $this->stats['get']; $this->cache_misses =& $this->stats['add']; } From 4ac3695f742921be2a8cf9373f1b9278b67392a8 Mon Sep 17 00:00:00 2001 From: Tazo Todua Date: Thu, 7 Feb 2019 01:25:43 +0400 Subject: [PATCH 6/6] Update object-cache.php --- object-cache.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/object-cache.php b/object-cache.php index e32f276..648c942 100644 --- a/object-cache.php +++ b/object-cache.php @@ -1,5 +1,5 @@