180 lines
3.7 KiB
PHP
180 lines
3.7 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Implementation methode Memoization
|
||
|
*
|
||
|
* @package SPIP\memoization\Memo
|
||
|
**/
|
||
|
|
||
|
// Sécurité
|
||
|
if (!defined('_ECRIRE_INC_VERSION')){
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!defined('_DIR_TMP')){
|
||
|
define('_DIR_TMP', 'tmp/');
|
||
|
}
|
||
|
if (!defined('_DIR_CACHE_FILECACHE')){
|
||
|
if (defined('_DIR_FILECACHE')){
|
||
|
define('_DIR_CACHE_FILECACHE', _DIR_TMP . _DIR_FILECACHE);
|
||
|
} // compat
|
||
|
elseif (defined('_DIR_CACHE')) {
|
||
|
define('_DIR_CACHE_FILECACHE', _DIR_CACHE);
|
||
|
} else {
|
||
|
define('_DIR_CACHE_FILECACHE', _DIR_TMP . 'cache/');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class MCacheBackend_filecache implements MCacheBackend {
|
||
|
|
||
|
// file named tmp/cache/ab/cd
|
||
|
// that's a maximum of 16^4 files in 256 directories
|
||
|
private function filename($u){
|
||
|
$u = md5($u);
|
||
|
$d = substr($u, 0, 2);
|
||
|
$u = substr($u, 2, 2);
|
||
|
|
||
|
# SPIP
|
||
|
if (function_exists('sous_repertoire')){
|
||
|
$rep = _DIR_CACHE_FILECACHE;
|
||
|
if (!@file_exists(_DIR_CACHE_FILECACHE)){
|
||
|
$rep = sous_repertoire(_DIR_CACHE_FILECACHE, '');
|
||
|
}
|
||
|
return sous_repertoire($rep, $d) . $u;
|
||
|
}
|
||
|
|
||
|
# Normal PHP
|
||
|
if (!is_dir(_DIR_CACHE_FILECACHE)){
|
||
|
@mkdir(_DIR_CACHE_FILECACHE);
|
||
|
}
|
||
|
if (!is_dir($sub = _DIR_CACHE_FILECACHE . $d)){
|
||
|
@mkdir($sub);
|
||
|
}
|
||
|
return $sub . '/' . $u;
|
||
|
}
|
||
|
|
||
|
/* Interface */
|
||
|
|
||
|
public function init($params = null){
|
||
|
|
||
|
}
|
||
|
|
||
|
public function get($key){
|
||
|
if ($c = @file_get_contents($this->filename($key))
|
||
|
and $r = unserialize($c)
|
||
|
and $r[1]===$key
|
||
|
and $r[2]>=time()){
|
||
|
return $r[0];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function set($key, $value, $ttl = null){
|
||
|
$r = array($value);
|
||
|
$r[1] = $key;
|
||
|
$r[2] = isset($ttl)
|
||
|
? time()+intval($ttl)
|
||
|
: time()+365*24*3600;
|
||
|
|
||
|
return (
|
||
|
$f = $this->filename($key)
|
||
|
and $n = @tempnam(dirname($f), 'xc')
|
||
|
and $h = @fopen($n, 'w')
|
||
|
and @fwrite($h, serialize($r))
|
||
|
and @fclose($h)
|
||
|
and @rename($n, $f)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
public function exists($key){
|
||
|
if ($c = @file_get_contents($this->filename($key))
|
||
|
and $r = @unserialize($c)
|
||
|
and $r[1]==$key
|
||
|
and $r[2]>=time()){
|
||
|
return true;
|
||
|
} else {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function del($key){
|
||
|
return (
|
||
|
$c = @file_get_contents($f = $this->filename($key))
|
||
|
and $s = supprimer_fichier($f)
|
||
|
and $r = @unserialize($c)
|
||
|
and $r[1]==$key
|
||
|
and $r[2]>=time()
|
||
|
);
|
||
|
}
|
||
|
|
||
|
public function inc($key, $value = null, $ttl = null){
|
||
|
$this->lock($key);
|
||
|
$value = (isset($value) ? intval($value) : 1)+intval($this->get($key));
|
||
|
$this->set($key, $value);
|
||
|
$this->unlock($key);
|
||
|
return $value;
|
||
|
}
|
||
|
|
||
|
public function dec($key, $value = null, $ttl = null){
|
||
|
$value = isset($value) ? intval($value) : 1;
|
||
|
return $this->inc($key, -$value, $ttl);
|
||
|
}
|
||
|
|
||
|
public function lock($key, /* private */ $unlock = false){
|
||
|
static $locks = array();
|
||
|
$f = $this->filename($key);
|
||
|
|
||
|
/* unlock */
|
||
|
if ($unlock){
|
||
|
if (isset($locks[$f])
|
||
|
and is_resource($locks[$f])){
|
||
|
@flock($locks[$f], LOCK_UN);
|
||
|
@fclose($locks[$f]);
|
||
|
unset($locks[$f]);
|
||
|
}
|
||
|
} /* lock */
|
||
|
else {
|
||
|
if (!isset($locks[$f])){
|
||
|
$locks[$f] = @fopen($f, 'a');
|
||
|
@flock($locks[$f], LOCK_EX);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function unlock($key){
|
||
|
$this->lock($key, true);
|
||
|
}
|
||
|
|
||
|
public function size(){
|
||
|
# check dirs until we reach > 500 files
|
||
|
$t = 0;
|
||
|
$n = 0;
|
||
|
$time = (isset($GLOBALS['meta']['cache_mark']) ? $GLOBALS['meta']['cache_mark'] : 0);
|
||
|
for ($i = 0; $i<256; $i++){
|
||
|
$dir = _DIR_CACHE . sprintf('%02s', dechex($i));
|
||
|
if (@is_dir($dir) and is_readable($dir) and $d = @opendir($dir)){
|
||
|
while (($f = readdir($d))!==false){
|
||
|
if (preg_match(',^[0-9a-f][0-9a-f]$,S', $f)
|
||
|
and $a = stat("$dir/$f")){
|
||
|
$n++;
|
||
|
if ($a['mtime']>=$time){
|
||
|
if ($a['blocks']>0){
|
||
|
$t += 512*$a['blocks'];
|
||
|
} else {
|
||
|
$t += $a['size'];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if ($n>500){
|
||
|
return intval(256*$t/(1+$i));
|
||
|
}
|
||
|
}
|
||
|
return $t;
|
||
|
}
|
||
|
|
||
|
public function purge(){
|
||
|
return false;
|
||
|
}
|
||
|
}
|