diff options
Diffstat (limited to 'phpBB/includes/acm/acm_apc.php')
-rw-r--r-- | phpBB/includes/acm/acm_apc.php | 174 |
1 files changed, 121 insertions, 53 deletions
diff --git a/phpBB/includes/acm/acm_apc.php b/phpBB/includes/acm/acm_apc.php index e4c4b79de3..e0714b1f0a 100644 --- a/phpBB/includes/acm/acm_apc.php +++ b/phpBB/includes/acm/acm_apc.php @@ -1,10 +1,10 @@ <?php -/** +/** * * @package acm * @version $Id$ -* @copyright (c) 2005 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @copyright (c) 2009 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License * */ @@ -17,32 +17,35 @@ if (!defined('IN_PHPBB')) } /** -* ACM APC Based Caching +* ACM File Based Caching * @package acm */ class acm { - private $vars = array(); - private $is_modified = false; + var $vars = array(); + var $is_modified = false; - public $sql_rowset = array(); - public $cache_dir = ''; + var $sql_rowset = array(); + var $sql_row_pointer = array(); + var $cache_dir = ''; /** * Set cache path */ - function __construct() + function acm() { - $this->cache_dir = PHPBB_ROOT_PATH . 'cache/'; + $this->cache_dir = $phpbb_root_path . 'cache/'; } /** * Load global cache */ - private function load() + function load() { // grab the global cache - if ($this->vars = apc_fetch('global')) + $this->vars = apc_fetch('global'); + + if ($this->vars !== false) { return true; } @@ -53,20 +56,22 @@ class acm /** * Unload cache object */ - public function unload() + function unload() { $this->save(); unset($this->vars); unset($this->sql_rowset); + unset($this->sql_row_pointer); $this->vars = array(); $this->sql_rowset = array(); + $this->sql_row_pointer = array(); } /** * Save modified objects */ - private function save() + function save() { if (!$this->is_modified) { @@ -81,7 +86,7 @@ class acm /** * Tidy cache */ - public function tidy() + function tidy() { // cache has auto GC, no need to have any code here :) @@ -91,28 +96,29 @@ class acm /** * Get saved cache object */ - public function get($var_name) + function get($var_name) { - if ($var_name[0] === '_') + if ($var_name[0] == '_') { + if (!$this->_exists($var_name)) + { + return false; + } + return apc_fetch($var_name); } else { - if (!sizeof($this->vars)) - { - $this->load(); - } - return (isset($this->vars[$var_name])) ? $this->vars[$var_name] : false; + return ($this->_exists($var_name)) ? $this->vars[$var_name] : false; } } /** * Put data into cache */ - public function put($var_name, $var, $ttl = 31536000) + function put($var_name, $var, $ttl = 31536000) { - if ($var_name[0] === '_') + if ($var_name[0] == '_') { apc_store($var_name, $var, $ttl); } @@ -126,7 +132,7 @@ class acm /** * Purge cache data */ - public function purge() + function purge() { // Purge all phpbb cache files $dir = @opendir($this->cache_dir); @@ -143,7 +149,7 @@ class acm continue; } - @unlink($this->cache_dir . $entry); + $this->remove_file($this->cache_dir . $entry); } closedir($dir); @@ -151,10 +157,11 @@ class acm unset($this->vars); unset($this->sql_rowset); + unset($this->sql_row_pointer); $this->vars = array(); - $this->var_expires = array(); $this->sql_rowset = array(); + $this->sql_row_pointer = array(); $this->is_modified = false; } @@ -162,9 +169,9 @@ class acm /** * Destroy cache data */ - public function destroy($var_name, $table = '') + function destroy($var_name, $table = '') { - if ($var_name === 'sql' && !empty($table)) + if ($var_name == 'sql' && !empty($table)) { if (!is_array($table)) { @@ -175,6 +182,7 @@ class acm { // gives us the md5s that we want $temp = apc_fetch('sql_' . $table_name); + if ($temp === false) { continue; @@ -193,7 +201,12 @@ class acm return; } - if ($var_name[0] === '_') + if (!$this->_exists($var_name)) + { + return; + } + + if ($var_name[0] == '_') { apc_delete($var_name); } @@ -208,9 +221,29 @@ class acm } /** + * Check if a given cache entry exist + */ + function _exists($var_name) + { + if ($var_name[0] == '_') + { + return true; + } + else + { + if (!sizeof($this->vars)) + { + $this->load(); + } + + return isset($this->vars[$var_name]); + } + } + + /** * Load cached sql query */ - public function sql_load($query) + function sql_load($query) { // Remove extra spaces and tabs $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); @@ -224,6 +257,7 @@ class acm } $this->sql_rowset[$query_id] = $temp; + $this->sql_row_pointer[$query_id] = 0; return $query_id; } @@ -231,25 +265,15 @@ class acm /** * Save sql query */ - public function sql_save($query, &$query_result, $ttl) + function sql_save($query, &$query_result, $ttl) { - global $db; - // Remove extra spaces and tabs $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); - // determine which tables this query belongs to: - - // grab all the FROM tables, avoid getting a LEFT JOIN - preg_match('/FROM \(?(\w+(?: (?!LEFT JOIN)\w+)?(?:, ?\w+(?: (?!LEFT JOIN)\w+)?)*)\)?/', $query, $regs); + // determine which tables this query belongs to + preg_match('/FROM \\(?(\\w+(?: \\w+)?(?:, ?\\w+(?: \\w+)?)*)\\)?/', $query, $regs); $tables = array_map('trim', explode(',', $regs[1])); - // now get the LEFT JOIN - preg_match_all('/LEFT JOIN\s+(\w+)(?: \w+)?/', $query, $result, PREG_PATTERN_ORDER); - $tables = array_merge($tables, $result[1]); - - $query_hash = md5($query); - foreach ($tables as $table_name) { if (($pos = strpos($table_name, ' ')) !== false) @@ -262,13 +286,14 @@ class acm { $temp = array(); } - $temp[$query_hash] = true; + $temp[md5($query)] = true; apc_store('sql_' . $table_name, $temp, $ttl); } // store them in the right place $query_id = sizeof($this->sql_rowset); $this->sql_rowset[$query_id] = array(); + $this->sql_row_pointer[$query_id] = 0; while ($row = $db->sql_fetchrow($query_result)) { @@ -276,35 +301,63 @@ class acm } $db->sql_freeresult($query_result); - apc_store('sql_' . $query_hash, $this->sql_rowset[$query_id], $ttl); + apc_store('sql_' . md5($query), $this->sql_rowset[$query_id], $ttl); $query_result = $query_id; } /** + * Ceck if a given sql query exist in cache + */ + function sql_exists($query_id) + { + return isset($this->sql_rowset[$query_id]); + } + + /** * Fetch row from cache (database) */ - public function sql_fetchrow($query_id) + function sql_fetchrow($query_id) { - list(, $row) = each($this->sql_rowset[$query_id]); + if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) + { + return $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]++]; + } - return ($row !== NULL) ? $row : false; + return false; } /** * Fetch a field from the current row of a cached database result (database) */ - public function sql_fetchfield($query_id, $field) + function sql_fetchfield($query_id, $field) { - $row = current($this->sql_rowset[$query_id]); + if ($this->sql_row_pointer[$query_id] < sizeof($this->sql_rowset[$query_id])) + { + return (isset($this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field])) ? $this->sql_rowset[$query_id][$this->sql_row_pointer[$query_id]][$field] : false; + } - return ($row !== false && isset($row[$field])) ? $row[$field] : false; + return false; + } + + /** + * Seek a specific row in an a cached database result (database) + */ + function sql_rowseek($rownum, $query_id) + { + if ($rownum >= sizeof($this->sql_rowset[$query_id])) + { + return false; + } + + $this->sql_row_pointer[$query_id] = $rownum; + return true; } /** * Free memory used for a cached database result (database) */ - public function sql_freeresult($query_id) + function sql_freeresult($query_id) { if (!isset($this->sql_rowset[$query_id])) { @@ -312,9 +365,24 @@ class acm } unset($this->sql_rowset[$query_id]); + unset($this->sql_row_pointer[$query_id]); return true; } + + /** + * Removes/unlinks file + */ + function remove_file($filename, $check = false) + { + if ($check && !@is_writable($this->cache_dir)) + { + // E_USER_ERROR - not using language entry - intended. + trigger_error('Unable to remove files within ' . $this->cache_dir . '. Please check directory permissions.', E_USER_ERROR); + } + + return @unlink($filename); + } } ?>
\ No newline at end of file |