Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F772831
in-portal
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Feb 1, 7:05 PM
Size
14 KB
Mime Type
text/x-diff
Expires
Mon, Feb 3, 7:05 PM (1 d, 10 h)
Engine
blob
Format
Raw Data
Handle
554555
Attached To
rINP In-Portal
in-portal
View Options
Index: branches/5.1.x/core/kernel/utility/cache.php
===================================================================
--- branches/5.1.x/core/kernel/utility/cache.php (revision 13990)
+++ branches/5.1.x/core/kernel/utility/cache.php (revision 13991)
@@ -1,599 +1,607 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
/**
* Manager of all implemented caching handlers
*
*/
class kCache extends kBase {
/**
* Object of cache handler
*
* @var FakeCacheHandler
*/
var $_handler = null;
/**
* Part of what we retrieve will be stored locally (per script run) not to bother memcache a lot
*
* @var Array
*/
var $_localStorage = Array ();
/**
* What type of caching is being used
*
* @var int
*/
var $cachingType = CACHING_TYPE_NONE;
/**
* Cache usage statistics (per script run)
*
* @var Array
*/
var $statistics = Array ();
/**
* Debug cache usage
*
* @var bool
*/
var $debugCache = false;
/**
* Displays cache usage statistics
*
* @var bool
*/
var $displayCacheStatistics = false;
/**
* Site key name
* Prepended to each cached key name
*
* @var string
*/
var $siteKeyName = '';
/**
* Site key value
* Prepended to each cached key name
*
* @var string
*/
var $siteKeyValue = null;
function kCache()
{
parent::kBase();
$this->siteKeyName = 'site_serial:' . crc32(SQL_TYPE . '://' . SQL_USER . ':' . SQL_PASS . '@' . SQL_SERVER . ':' . TABLE_PREFIX);
// get cache handler class to use
if (array_key_exists('CacheHandler', $GLOBALS['vars']) && $GLOBALS['vars']['CacheHandler']) {
// for advanced users, who want to save one SQL on each page load
$handler_class = $GLOBALS['vars']['CacheHandler'] . 'CacheHandler';
}
else {
$handler_class = $this->Application->ConfigValue('CacheHandler') . 'CacheHandler';
}
// defined cache handler doen't exist -> use default
if (!class_exists($handler_class)) {
$handler_class = 'FakeCacheHandler';
}
$handler = new $handler_class();
if (!$handler->isWorking()) {
// defined cache handler is not working -> use default
trigger_error('Failed to initialize "<strong>' . $handler_class . '</strong>" caching handler.', E_USER_WARNING);
$handler = new FakeCacheHandler();
}
elseif ($this->Application->isDebugMode() && ($handler->cachingType == CACHING_TYPE_MEMORY)) {
$this->Application->Debugger->appendHTML('Memory Caching: "<strong>' . $handler_class . '</strong>"');
}
$this->_handler =& $handler;
$this->cachingType = $handler->cachingType;
$this->debugCache = $handler->cachingType == CACHING_TYPE_MEMORY && $this->Application->isDebugMode();
$this->displayCacheStatistics = defined('DBG_CACHE') && DBG_CACHE && $this->Application->isDebugMode();
}
/**
* Returns caching type of current storage engine
*
* @return int
*/
function getCachingType()
{
return $this->cachingType;
}
/**
* Stores value to cache
*
* @param string $name
* @param mixed $value
* @param int $expires cache record expiration time in seconds
*/
function setCache($name, $value, $expiration)
{
$name = $this->prepareKeyName($name);
$this->_localStorage[$name] = $value;
return $this->_handler->set($name, $value, $expiration);
}
/**
* Returns value from cache
*
* @param string $name
* @param bool $store_locally store data locally after retrieved
* @param bool $replace_serials
* @return mixed
*/
function getCache($name, $store_locally = true, $replace_serials = true)
{
$name = $this->prepareKeyName($name, $replace_serials);
if ($store_locally) {
if (array_key_exists($name, $this->_localStorage)) {
if ($this->displayCacheStatistics) {
$this->setStatistics($name, $this->_localStorage[$name]);
}
return $this->_localStorage[$name];
}
}
$res = $this->_handler->get($name);
if ($replace_serials && $this->debugCache) {
// don't display subsequent serial cache retrievals (ones, that are part of keys)
if (is_array($res)) {
$this->Application->Debugger->appendHTML('Restoring key "' . $name . '". Type: ' . gettype($res) . '.');
}
else {
$res_display = strip_tags($res);
if (strlen($res_display) > 200) {
$res_display = substr($res_display, 0, 50) . ' ...';
}
$this->Application->Debugger->appendHTML('Restoring key "' . $name . '" resulted [' . $res_display . ']');
}
}
if ($store_locally && ($res !== false)) {
$this->_localStorage[$name] = $res;
if ($this->displayCacheStatistics) {
$this->setStatistics($name, $res);
}
}
return $res;
}
/**
* Deletes value from cache
*
* @param string $name
* @return mixed
*/
function delete($name)
{
$name = $this->prepareKeyName($name);
unset($this->_localStorage[$name]);
return $this->_handler->delete($name);
}
/**
* Reset's all memory cache at once
*/
function reset()
{
// don't check for enabled, because we maybe need to reset cache anyway
if ($this->cachingType == CACHING_TYPE_TEMPORARY) {
return ;
}
$site_key = $this->_cachePrefix(true);
$this->_handler->set($site_key, $this->_handler->get($site_key) + 1);
}
/**
* Replaces serials and adds unique site prefix to cache variable name
*
* @param string $name
* @param bool $replace_serials
* @return string
*/
function prepareKeyName($name, $replace_serials = true)
{
// replace serials in key name
if ($replace_serials && preg_match_all('/\[%(.*?)%\]/', $name, $regs)) {
// [%LangSerial%] - prefix-wide serial in case of any change in "lang" prefix
// [%LangIDSerial:5%] - one id-wide serial in case of data, associated with given id was changed
// [%CiIDSerial:ItemResourceId:5%] - foreign key-based serial in case of data, associated with given foreign key was changed
foreach ($regs[1] as $serial_name) {
$name = str_replace('[%' . $serial_name . '%]', '[' . $serial_name . '=' . $this->getCache($serial_name, true, false) . ']', $name);
}
}
if ($this->cachingType == CACHING_TYPE_TEMPORARY) {
return $name;
}
// add site-wide prefix to key
return $this->_cachePrefix() . $name;
}
/**
* Returns site-wide caching prefix
*
* @param bool $only_site_key_name
* @return string
*/
function _cachePrefix($only_site_key_name = false)
{
if ($only_site_key_name) {
return $this->siteKeyName;
}
if ( !isset($this->siteKeyValue) ) {
$this->siteKeyValue = $this->_handler->get($this->siteKeyName);
if (!$this->siteKeyValue) {
$this->siteKeyValue = 1;
$this->_handler->set($this->siteKeyName, $this->siteKeyValue);
}
}
return "{$this->siteKeyName}:{$this->siteKeyValue}:";
}
function setStatistics($name, $found)
{
if (strpos($name, ']:') !== false) {
list ($cache_name, $name) = explode(']:', $name, 2);
}
else {
$cache_name = '-';
}
if (!array_key_exists($cache_name, $this->statistics)) {
$this->statistics[$cache_name] = Array ();
}
if (!array_key_exists($name, $this->statistics[$cache_name])) {
$this->statistics[$cache_name][$name] = Array ();
}
$status_key = $found ? 'found' : 'not_found';
if (!isset($this->statistics[$cache_name][$name][$status_key])) {
$this->statistics[$cache_name][$name][$status_key] = 0;
}
$this->statistics[$cache_name][$name][$status_key]++;
}
/**
* Returns storage size in bytes
*
* @return int
*/
function getStorageSize()
{
return strlen( serialize($this->_localStorage) );
}
function printStatistics()
{
$cache_size = $this->getStorageSize();
$this->Application->Debugger->appendHTML('<strong>Cache Size:</strong> ' . formatSize($cache_size) . ' (' . $cache_size . ')');
foreach ($this->statistics as $cache_name => $cache_data) {
foreach ($cache_data as $key => $value) {
if (!array_key_exists('found', $value) || $value['found'] == 1) {
// remove cached records, that were used only 1 or 2 times
unset($this->statistics[$cache_name][$key]);
}
}
}
print_pre($this->statistics, 'Cache Statistics:');
}
}
class FakeCacheHandler {
var $cachingType = CACHING_TYPE_TEMPORARY;
function FakeCacheHandler()
{
}
/**
* Retrieves value from cache
*
* @param string $name
* @return mixed
*/
function get($name)
{
return false;
}
/**
* Stores value in cache
*
* @param string $name
* @param mixed $value
* @param int $expiration
* @return bool
*/
function set($name, $value, $expiration = 0)
{
return true;
}
/**
* Deletes key from cach
*
* @param string $name
* @return bool
*/
function delete($name)
{
return true;
}
/**
* Determines, that cache storage is working fine
*
* @return bool
*/
function isWorking()
{
return true;
}
}
class MemcacheCacheHandler {
var $_enabled = false;
/**
* Memcache connection
*
* @var Memcache
*/
var $_handler = null;
var $cachingType = CACHING_TYPE_MEMORY;
function MemcacheCacheHandler()
{
if (array_key_exists('MemcacheServers', $GLOBALS['vars'])) {
// for advanced users, who want to save one SQL on each page load
$memcached_servers = $GLOBALS['vars']['MemcacheServers'];
}
else {
$application =& kApplication::Instance();
$memcached_servers = $application->ConfigValue('MemcacheServers');
}
if ($memcached_servers && class_exists('Memcache')) {
$this->_enabled = true;
$this->_handler = new Memcache();
$servers = explode(';', $memcached_servers);
foreach ($servers as $server) {
- list ($server, $port) = strpos($server, ':') !== false ? explode(':', $server, 2) : Array ($server, 11211);
+ if ( preg_match('/(.*):([\d]+)$/', $server, $regs) ) {
+ // "hostname:port" OR "unix:///path/to/socket:0"
+ $server = $regs[1];
+ $port = $regs[2];
+ }
+ else {
+ $port = 11211;
+ }
+
$this->_handler->addServer($server, $port);
}
// verify, that memcache server is working
if (!$this->_handler->set('test', 1)) {
$this->_enabled = false;
}
}
}
/**
* Retrieves value from cache
*
* @param string $name
* @return mixed
*/
function get($name)
{
return $this->_handler->get($name);
}
/**
* Stores value in cache
*
* @param string $name
* @param mixed $value
* @param int $expiration
* @return bool
*/
function set($name, $value, $expiration = 0)
{
// 0 - don't use compression
return $this->_handler->set($name, $value, 0, $expiration);
}
/**
* Deletes key from cache
*
* @param string $name
* @return bool
*/
function delete($name)
{
- return $this->_handler->delete($name);
+ return $this->_handler->delete($name, 0);
}
/**
* Determines, that cache storage is working fine
*
* @return bool
*/
function isWorking()
{
return $this->_enabled;
}
}
class ApcCacheHandler {
var $_enabled = false;
var $cachingType = CACHING_TYPE_MEMORY;
function ApcCacheHandler()
{
$this->_enabled = function_exists('apc_fetch');
// verify, that apc is working
if ($this->_enabled && !$this->set('test', 1)) {
$this->_enabled = false;
}
}
/**
* Retrieves value from cache
*
* @param string $name
* @return mixed
*/
function get($name)
{
return apc_fetch($name);
}
/**
* Stores value in cache
*
* @param string $name
* @param mixed $value
* @param int $expiration
* @return bool
*/
function set($name, $value, $expiration = 0)
{
return apc_store($name, $value, $expiration);
}
/**
* Deletes key from cache
*
* @param string $name
* @return bool
*/
function delete($name)
{
return apc_delete($name);
}
/**
* Determines, that cache storage is working fine
*
* @return bool
*/
function isWorking()
{
return $this->_enabled;
}
}
class XCacheCacheHandler {
var $_enabled = false;
var $cachingType = CACHING_TYPE_MEMORY;
function XCacheCacheHandler()
{
$this->_enabled = function_exists('xcache_get');
// verify, that xcache is working
if ($this->_enabled && !$this->set('test', 1)) {
$this->_enabled = false;
}
}
/**
* Retrieves value from cache
*
* @param string $name
* @return mixed
*/
function get($name)
{
return xcache_isset($name) ? xcache_get($name) : false;
}
/**
* Stores value in cache
*
* @param string $name
* @param mixed $value
* @param int $expiration
* @return bool
*/
function set($name, $value, $expiration = 0)
{
return xcache_set($name, $value, $expiration);
}
/**
* Deletes key from cache
*
* @param string $name
* @return bool
*/
function delete($name)
{
return xcache_unset($name);
}
/**
* Determines, that cache storage is working fine
*
* @return bool
*/
function isWorking()
{
return $this->_enabled;
}
}
\ No newline at end of file
Event Timeline
Log In to Comment