spip_nursit/plugins-dist/dist/nursit/memoization/memo/filecache.inc
2023-06-01 17:30:12 +02:00

179 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;
}
}