Кеширование на файлах часть 2

Главные вкладки

Аватар пользователя Ильич Рамирес Санчес Ильич Рамирес Санчес 20 января 2008 в 19:28

Сделал функцию чистки кеша. С учетом специфики может быть ее будет достаточно.
Завтра поставлю на наш дистриб друпала его + devel забью случайные данные и поиграю с производительностью.

На моих ресурсах кеш работает в режиме бетатестирования Smile
Вроде все.

<?php
/*
*
* Filecache by Ilya V. Azarov, brainstorm.name
*
*
*/
class cache_cc{
var $data, $created, $expire, $headers;
function cache_cc($c){
$this->data = $c['data'];
$this->created = $c['created'];
$this->expire = $c['expire'];
$this->headers = $c['headers'];
}
}
function filecache_md5($key){
static $cache_arr;
if(isset($cache_arr[$key] ) ) return $cache_arr[$key];
$md = md5($key);
$cache_arr[$key] = $md;
return $md;
}
function filecache_tablepath($table, $key){
return variable_get('filecache_path', 'files/cache') . '/'. $table;
}

function filecache_md5path($table, $key){
static $cache_arr;
if(isset($cache_arr[$table . $key] ) ) return $cache_arr[$table . $key];
$md = filecache_md5($key);
$path = array($md{0}, $md{1}, $md{2}/*, $md{3}, $md{5}*/ );
$path = filecache_tablepath($table, $key) . '/' . implode('/', $path);
$cache_arr[$key] = $path;
return $path;
}
function filecache_fname($table, $key){
return urlencode($key);
}
function filecache_name($table, $key){
return filecache_md5path($table, $key) . '/' . filecache_fname($table, $key);
}
function filecache_pmkdir($dir){
// FOR PHP 5 ONLY. PHP 4 SUCKS A COCK
if(is_dir($dir) ) return true;
return mkdir($dir, 0755, true);
}
// checks file exists and create path to them if not Smile
function filecache_lockpath($table, $key){
if(!is_dir(filecache_md5path($table, $key) ) ){
filecache_pmkdir(filecache_md5path($table, $key) );
}
return filecache_md5path($table, $key) . '/' . 'lock';
}
function filecache_safefile_get_contents($table, $key){
$lck = filecache_lockpath($table, $key);
$src = filecache_name($table, $key);
$f = fopen($lck, 'w+');
if(flock($f, LOCK_SH) ){
$cnt = file_get_contents($src);
flock($f, LOCK_UN);
fclose($f);
return $cnt;
}
fclose($f);
return false;
}
function filecache_safefile_put_contents($table, $key, $cache){
$lck = filecache_lockpath($table, $key);
$f = fopen($lck, 'w+');
$src = filecache_name($table, $key);
if(flock($f, LOCK_EX) ){
$cnt = @file_put_contents($src, $cache);
flock($f, LOCK_UN);
fclose($f);
return $cnt;
}
fclose($f);
return false;
}

function cache_get($cid, $table = 'cache') {
global $user;
$key = $cid;

if (!file_exists(filecache_name($table, $key) ) ) {
return 0;
}
$cache = unserialize(filecache_safefile_get_contents($table, $key) );

if (isset($cache->data)) {
// If the data is permanent or we're not enforcing a minimum cache lifetime
// always return the cached data.
if ($cache['expire'] == CACHE_PERMANENT || !variable_get('cache_lifetime', 0)) {
$cache['data'] = db_decode_blob($cache['data']);
}
// If enforcing a minimum cache lifetime, validate that the data is
// currently valid for this user before we return it by making sure the
// cache entry was created before the timestamp in the current session's
// cache timer. The cache variable is loaded into the $user object by
// sess_read() in session.inc.
else {
if ($user->cache > $cache->created) {
// This cache data is too old and thus not valid for us, ignore it.
return 0;
}
else {
$cache->data = db_decode_blob($cache->data);
}
}
return new cache_cc($cache);
}
return 0;
}

function cache_set($cid, $table = 'cache', $data, $expire = CACHE_PERMANENT, $headers = NULL) {
$cache = array(
'data' => $data,
'created' => time(),
'expire' => $expire,
'headers' => $headers,
);
$cache = serialize($cache);
$key = $cid;
filecache_safefile_put_contents($table, $key, $cache);
}
/*
* Removes all files from given cache directory
*
*
*/
function filecache_clear_directory_clear($dir){
if($dh = opendir($dir) ){
$dirs = array();
$files = array();
while($f = readdir($dh) ) if($f != '..' && $f != '.') {
$f1 = $dir . '/' . $f;
if(is_dir($f1) ) array_push($dirs, $f1);
elseif(strcmp($f, 'lock') != 0) array_push($files, $f1);
}
closedir($dh);
while($f1 = array_pop($files) ) unlink($f1);
while($f1 = array_pop($dirs) ) filecache_clear_directory_clear($f1);
return true;
}else{
return false;
}
}

function cache_clear_all($cid = NULL, $table = NULL, $wildcard = FALSE) {
global $user;
if (!isset($cid) && !isset($table)) {
cache_clear_all(NULL, 'cache_page');
return;
}
if (empty($cid)){
filecache_clear_directory_clear(filecache_tablepath($table, $cid) );
}else{
if ($wildcard) {
filecache_clear_directory_clear(filecache_tablepath($table, $cid) );
}else{
unlink(filecache_name($table, $cid) );
}
}
}

?>

Комментарии

Аватар пользователя Ильич Рамирес Санчес Ильич Рамирес Санчес 21 января 2008 в 12:55

Этот вариант кеширования решает проблемы с прожорливостью модуля path?

для анонимусов прожорливость решается стандартным кешем. для неанонимумов - надо тестировать advcache