<?php
/**
* A SMF based cache engine using Memcache.
* @since 3.0
* @version 3.0
*/
class SmCache
{
/**
* Is memcache enabled?
* @since 3.0
* @version 3.0
*/
private static $disabled = false;
/**
* The memcache object.
* @since 3.0
* @version 3.0
*/
private static $memcache = null;
/**
* The prekey, basically the prefix used on this memcache instance.
* @since 3.0
* @version 3.0
*/
private static $prekey = '';
/**
* Gets data from MemCache.
* @param string $key The unique key.
* @param int $ttl How long the key should exist.
* @return mixed The data which was stored is now returned.
* @since 3.0
* @version 3.0
*/
public static function get($key, $ttl)
{
if (self::$disabled)
return;
$st = microtime();
$value = self::$memcache->get(self::$prekey . strtr($key, ':', '-'), $ttl);
// Update our hit counter.
self::__cacheHits('get', strtr($key, ':', '-'), null, $ttl, $st, microtime());
// Return the correct value.
if (empty($value))
return null;
else
return @unserialize($value);
}
/**
* Sets the data into the memcache server.
* @param string $key The unique key.
* @param string $value The data to cache.
* @param int $ttl How long the key should exist.
* @return void Nothing is returned.
* @since 3.0
* @version 3.0
*/
public static function set($key, $value, $ttl)
{
if (self::$disabled)
return;
$st = microtime();
$value = $value === null ? null : serialize($value);
// Note: due to inconsistencies in pecl, we use 0 as ttl to resolve a bug.
if (is_null($value))
self::$memcache->delete(self::$prekey . strtr($key, ':', '-'), 0);
else
self::$memcache->set(self::$prekey . strtr($key, ':', '-'), $value, 0, $ttl);
// Update our hit counter.
self::__cacheHits('put', $key, strtr($key, ':', '-'), $ttl, $st, microtime());
}
/**
* This does the hefty startup work. Gets memcache going.
* @param int $level Allows us to call this multiple times to try and start memcache up.
* @return void Nothing is returned.
* @since 3.0
* @version 3.0
*/
public static function __loadMemCache($level = 0)
{
global $modSettings;
// If it is off, let the class know.
if (empty($modSettings['cache_enable']) && !empty($modSettings))
{
return;
}
// Create our new memcache instance.
self::$memcache = new Memcache;
// Basic load balancing.
$servers = explode(',', $modSettings['cache_memcached']);
$server = explode(':', trim($servers[array_rand($servers)]));
// Connect to memcache now.
$connected = $memcache->pconnect($server[0], empty($server[1]) ? 11211 : $server[1]);
// Try a few times to connect.
if (!$connected && $level > 3)
self::__loadMemCache(++$level);
elseif ($level =< 2)
return false;
self::$prekey = md5($boardurl . filemtime(__FILE__)) . '-SmSite-';
}
/**
* Updates SMFs cache counter and debugging info.
* @param string $type Either "get" or "put" based on what type of usage.
* @param string $key The unique key.
* @param string $value The data to cache.
* @param int $ttl How long the key should exist.
* @param int $start Time before trying caching.
* @param int $stop Time after trying caching.
* @return void Nothing is returned.
* @since 3.0
* @version 3.0
*/
public static function __cacheHits($type, $key, $value, $ttl, $start, $stop)
{
global $cache_hits, $cache_count, $db_show_debug;
$cache_count = isset($cache_count) ? $cache_count + 1 : 1;
if (isset($db_show_debug) && $db_show_debug === true)
{
$cache_hits[$cache_count] = array('k' => $key, 'd' => $type, 's' => $value === null ? 0 : strlen(serialize($value)), 't' => array_sum(explode(' ', microtime())) - array_sum(explode(' ', $st)));
$cache_hits[$cache_count]['t'] = array_sum(explode(' ', $stop)) - array_sum(explode(' ', $start));
}
}
}
?>
<?php
/**
* A SMF based cache engine using Memcache.
* @since 3.0
* @version 3.0
*/
class SmCache
{
/**
* Is memcache enabled?
* @since 3.0
* @version 3.0
*/
private static $disabled = false;
/**
* The memcache object.
* @since 3.0
* @version 3.0
*/
private static $memcache = null;
/**
* The prekey, basically the prefix used on this memcache instance.
* @since 3.0
* @version 3.0
*/
private static $prekey = '';
/**
* Gets data from MemCache.
* @param string $key The unique key.
* @param int $ttl How long the key should exist.
* @return mixed The data which was stored is now returned.
* @since 3.0
* @version 3.0
*/
public static function get($key, $ttl)
{
if (self::$disabled)
return;
$st = microtime();
$value = self::$memcache->get(self::$prekey . strtr($key, ':', '-'), $ttl);
// Update our hit counter.
self::__cacheHits('get', strtr($key, ':', '-'), null, $ttl, $st, microtime());
// Return the correct value.
if (empty($value))
return null;
else
return @unserialize($value);
}
/**
* Sets the data into the memcache server.
* @param string $key The unique key.
* @param string $value The data to cache.
* @param int $ttl How long the key should exist.
* @return void Nothing is returned.
* @since 3.0
* @version 3.0
*/
public static function set($key, $value, $ttl)
{
if (self::$disabled)
return;
$st = microtime();
$value = $value === null ? null : serialize($value);
// Note: due to inconsistencies in pecl, we use 0 as ttl to resolve a bug.
if (is_null($value))
self::$memcache->delete(self::$prekey . strtr($key, ':', '-'), 0);
else
self::$memcache->set(self::$prekey . strtr($key, ':', '-'), $value, 0, $ttl);
// Update our hit counter.
self::__cacheHits('put', $key, strtr($key, ':', '-'), $ttl, $st, microtime());
}
/**
* This does the hefty startup work. Gets memcache going.
* @param int $level Allows us to call this multiple times to try and start memcache up.
* @return void Nothing is returned.
* @since 3.0
* @version 3.0
*/
public static function __loadMemCache($level = 0)
{
global $modSettings;
// If it is off, let the class know.
if (empty($modSettings['cache_enable']) && !empty($modSettings))
{
return;
}
// Create our new memcache instance.
self::$memcache = new Memcache;
// Basic load balancing.
$servers = explode(',', $modSettings['cache_memcached']);
$server = explode(':', trim($servers[array_rand($servers)]));
// Connect to memcache now.
$connected = $memcache->pconnect($server[0], empty($server[1]) ? 11211 : $server[1]);
// Try a few times to connect.
if (!$connected && $level > 3)
self::__loadMemCache(++$level);
elseif ($level =< 2)
return false;
self::$prekey = md5(filemtime(__FILE__)) . '-SmSite-';
}
/**
* Updates SMFs cache counter and debugging info.
* @param string $type Either "get" or "put" based on what type of usage.
* @param string $key The unique key.
* @param string $value The data to cache.
* @param int $ttl How long the key should exist.
* @param int $start Time before trying caching.
* @param int $stop Time after trying caching.
* @return void Nothing is returned.
* @since 3.0
* @version 3.0
*/
public static function __cacheHits($type, $key, $value, $ttl, $start, $stop)
{
global $cache_hits, $cache_count, $db_show_debug;
$cache_count = isset($cache_count) ? $cache_count + 1 : 1;
if (isset($db_show_debug) && $db_show_debug === true)
{
$cache_hits[$cache_count] = array('k' => $key, 'd' => $type, 's' => $value === null ? 0 : strlen(serialize($value)), 't' => array_sum(explode(' ', microtime())) - array_sum(explode(' ', $st)));
$cache_hits[$cache_count]['t'] = array_sum(explode(' ', $stop)) - array_sum(explode(' ', $start));
}
}
}
?>