Permalink
Browse files

introducing new features

git-svn-id: http://svn.php.net/repository/pear/packages/Cache_Lite/trunk@173392 c90b9560-bf6c-de11-be94-00142212c4b1
  • Loading branch information...
1 parent 16ad045 commit eb9ca9fa93a048f1e04197f90b411b70c5e620a4 Fabien MARTY committed Nov 23, 2004
Showing with 184 additions and 231 deletions.
  1. +165 −58 Lite.php
  2. +0 −166 TODO
  3. +19 −7 package.xml
View
223 Lite.php
@@ -80,6 +80,13 @@ class Cache_Lite
* @var string $_file
*/
var $_file;
+
+ /**
+ * File name (without path)
+ *
+ * @var string $_fileName
+ */
+ var $_fileName;
/**
* Enable / disable write control (the cache is read just after writing to detect corrupt entries)
@@ -197,6 +204,27 @@ class Cache_Lite
*/
var $_automaticSerialization = false;
+ /**
+ * Disable / Tune the automatic cleaning process
+ *
+ * The automatic cleaning process destroy too old (for the given life time)
+ * cache files when a new cache file is written.
+ * 0 => no automatic cache cleaning
+ * 1 => systematic cache cleaning
+ * x (integer) > 1 => automatic cleaning randomly 1 times on x cache write
+ *
+ * @var int $_automaticCleaning
+ */
+ var $_automaticCleaningFactor = 0;
+
+ /**
+ * Nested directory level
+ *
+ *
+ * @var int $_hashedDirectoryLevel
+ */
+ var $_hashedDirectoryLevel = 0;
+
// --- Public methods ---
/**
@@ -217,14 +245,16 @@ class Cache_Lite
* 'memoryCachingLimit' => max nbr of records to store into memory caching (int),
* 'fileNameProtection' => enable / disable automatic file name protection (boolean),
* 'automaticSerialization' => enable / disable automatic serialization (boolean)
+ * 'automaticCleaningFactor' => distable / tune automatic cleaning process (int)
+ * 'hashedDirectoryLevel' => level of the hashed directory system (int)
* );
*
* @param array $options options
* @access public
*/
function Cache_Lite($options = array(NULL))
{
- $availableOptions = array('automaticSerialization', 'fileNameProtection', 'memoryCaching', 'onlyMemoryCaching', 'memoryCachingLimit', 'cacheDir', 'caching', 'lifeTime', 'fileLocking', 'writeControl', 'readControl', 'readControlType', 'pearErrorMode');
+ $availableOptions = array('hashedDirectoryLevel', 'automaticCleaningFactor', 'automaticSerialization', 'fileNameProtection', 'memoryCaching', 'onlyMemoryCaching', 'memoryCachingLimit', 'cacheDir', 'caching', 'lifeTime', 'fileLocking', 'writeControl', 'readControl', 'readControlType', 'pearErrorMode');
foreach($options as $key => $value) {
if(in_array($key, $availableOptions)) {
$property = '_'.$key;
@@ -307,6 +337,12 @@ function save($data, $id = NULL, $group = 'default')
return true;
}
}
+ if ($this->_automaticCleaningFactor>0) {
+ $rand = rand(1, $this->_automaticCleaningFactor);
+ if ($rand==1) {
+ $this->clean(false, 'old');
+ }
+ }
if ($this->_writeControl) {
if (!$this->_writeAndControl($data)) {
@touch($this->_file, time() - 2*abs($this->_lifeTime));
@@ -315,8 +351,8 @@ function save($data, $id = NULL, $group = 'default')
return true;
}
} else {
- return $this->_write($data);
- }
+ return $this->_write($data);
+ }
}
return false;
}
@@ -341,11 +377,7 @@ function remove($id, $group = 'default')
return true;
}
}
- if (!@unlink($this->_file)) {
- $this->raiseError('Cache_Lite : Unable to remove cache !', -3);
- return false;
- }
- return true;
+ return $this->_unlink($this->_file);
}
/**
@@ -355,47 +387,15 @@ function remove($id, $group = 'default')
* else only cache files of the specified group will be destroyed
*
* @param string $group name of the cache group
+ * @param string $mode flush cache mode : 'old', 'ingroup', 'notingroup'
* @return boolean true if no problem
* @access public
*/
- function clean($group = false)
+ function clean($group = false, $mode = 'ingroup')
{
- if ($this->_fileNameProtection) {
- $motif = ($group) ? 'cache_'.md5($group).'_' : 'cache_';
- } else {
- $motif = ($group) ? 'cache_'.$group.'_' : 'cache_';
- }
- if ($this->_memoryCaching) {
- while (list($key, $value) = each($this->_memoryCachingArray)) {
- if (strpos($key, $motif, 0)) {
- unset($this->_memoryCachingArray[$key]);
- $this->_memoryCachingCounter = $this->_memoryCachingCounter - 1;
- }
- }
- if ($this->_onlyMemoryCaching) {
- return true;
- }
- }
- if (!($dh = opendir($this->_cacheDir))) {
- $this->raiseError('Cache_Lite : Unable to open cache directory !', -4);
- return false;
- }
- while ($file = readdir($dh)) {
- if (($file != '.') && ($file != '..')) {
- $file = $this->_cacheDir . $file;
- if (is_file($file)) {
- if (strpos($file, $motif, 0)) {
- if (!@unlink($file)) {
- $this->raiseError('Cache_Lite : Unable to remove cache !', -3);
- return false;
- }
- }
- }
- }
- }
- return true;
+ $this->_cleanDir($this->_cacheDir, $group, $mode);
}
-
+
/**
* Set to debug mode
*
@@ -479,11 +479,93 @@ function raiseError($msg, $code)
include_once('PEAR.php');
PEAR::raiseError($msg, $code, $this->_pearErrorMode);
}
-
+
// --- Private methods ---
/**
+ * Remove a file
+ *
+ * @param string $file complete file path and name
+ * @return boolean true if no problem
+ * @access private
+ */
+ function _unlink($file)
+ {
+ if (!@unlink($file)) {
+ $this->raiseError('Cache_Lite : Unable to remove cache !', -3);
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ *
+ * @return boolean true if no problem
+ * @access private
+ */
+ function _cleanDir($dir, $group = false, $mode = 'ingroup')
+ {
+ if ($this->_fileNameProtection) {
+ $motif = ($group) ? 'cache_'.md5($group).'_' : 'cache_';
+ } else {
+ $motif = ($group) ? 'cache_'.$group.'_' : 'cache_';
+ }
+ if ($this->_memoryCaching) {
+ while (list($key, $value) = each($this->_memoryCachingArray)) {
+ if (strpos($key, $motif, 0)) {
+ unset($this->_memoryCachingArray[$key]);
+ $this->_memoryCachingCounter = $this->_memoryCachingCounter - 1;
+ }
+ }
+ if ($this->_onlyMemoryCaching) {
+ return true;
+ }
+ }
+ if (!($dh = opendir($dir))) {
+ $this->raiseError('Cache_Lite : Unable to open cache directory !', -4);
+ return false;
+ }
+ $result = true;
+ while ($file = readdir($dh)) {
+ if (($file != '.') && ($file != '..')) {
+ if (substr($file, 0, 6)=='cache_') {
+ $file2 = $dir . $file;
+ if (is_file($file2)) {
+ switch ($mode) {
+ case 'old':
+ // files older than lifeTime get deleted from cache
+ if ((mktime() - filemtime($file2)) > $this->_lifeTime) {
+ $result = ($result and ($this->_unlink($file2)));
+ }
+ break;
+ case 'notingroup':
+ if (!strpos($file2, $motif, 0)) {
+ $result = ($result and ($this->_unlink($file2)));
+ }
+ break;
+ case 'ingroup':
+ default:
+ if (strpos($file2, $motif, 0)) {
+ $result = ($result and ($this->_unlink($file2)));
+ }
+ break;
+ }
+ }
+ if ((is_dir($file2)) and ($this->_hashedDirectoryLevel>0)) {
+ $result = ($result and ($this->_cleanDir($file2 . '/', $group, $mode)));
+ }
+ }
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Add some date in the memory caching array
*
+ * @param string $id cache id
+ * @param string $data data to cache
* @access private
*/
function _memoryCacheAdd($id, $data)
@@ -506,11 +588,21 @@ function _memoryCacheAdd($id, $data)
*/
function _setFileName($id, $group)
{
+
if ($this->_fileNameProtection) {
- $this->_file = ($this->_cacheDir.'cache_'.md5($group).'_'.md5($id));
+ $suffix = 'cache_'.md5($group).'_'.md5($id);
} else {
- $this->_file = $this->_cacheDir.'cache_'.$group.'_'.$id;
+ $suffix = 'cache_'.$group.'_'.$id;
+ }
+ $root = $this->_cacheDir;
+ if ($this->_hashedDirectoryLevel>0) {
+ $hash = md5($suffix);
+ for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) {
+ $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
+ }
}
+ $this->_fileName = $suffix;
+ $this->_file = $root.$suffix;
}
/**
@@ -558,19 +650,34 @@ function _read()
*/
function _write($data)
{
- $fp = @fopen($this->_file, "wb");
- if ($fp) {
- if ($this->_fileLocking) @flock($fp, LOCK_EX);
- if ($this->_readControl) {
- @fwrite($fp, $this->_hash($data, $this->_readControlType), 32);
+ $try = 1;
+ while ($try<=2) {
+ $fp = @fopen($this->_file, "wb");
+ if ($fp) {
+ if ($this->_fileLocking) @flock($fp, LOCK_EX);
+ if ($this->_readControl) {
+ @fwrite($fp, $this->_hash($data, $this->_readControlType), 32);
+ }
+ $len = strlen($data);
+ @fwrite($fp, $data, $len);
+ if ($this->_fileLocking) @flock($fp, LOCK_UN);
+ @fclose($fp);
+ return true;
+ } else {
+ if (($try==1) and ($this->_hashedDirectoryLevel>0)) {
+ $hash = md5($this->_fileName);
+ $root = $this->_cacheDir;
+ for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) {
+ $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
+ @mkdir($root, 0700);
+ }
+ $try = 2;
+ } else {
+ $try = 999;
+ }
}
- $len = strlen($data);
- @fwrite($fp, $data, $len);
- if ($this->_fileLocking) @flock($fp, LOCK_UN);
- @fclose($fp);
- return true;
}
- $this->raiseError('Cache_Lite : Unable to write cache !', -1);
+ $this->raiseError('Cache_Lite : Unable to write cache file : '.$this->_file, -1);
return false;
}
Oops, something went wrong.

0 comments on commit eb9ca9f

Please sign in to comment.