• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List

E:/E/GEAMP/www/openbiz/openbiz/others/Zend/Cache/Backend/TwoLevels.php

00001 <?php
00027 require_once 'Zend/Cache/Backend/ExtendedInterface.php';
00028 
00032 require_once 'Zend/Cache/Backend.php';
00033 
00034 
00042 class Zend_Cache_Backend_TwoLevels extends Zend_Cache_Backend implements Zend_Cache_Backend_ExtendedInterface
00043 {
00080     protected $_options = array(
00081         'slow_backend' => 'File',
00082         'fast_backend' => 'Apc',
00083         'slow_backend_options' => array(),
00084         'fast_backend_options' => array(),
00085         'stats_update_factor' => 10,
00086         'slow_backend_custom_naming' => false,
00087         'fast_backend_custom_naming' => false,
00088         'slow_backend_autoload' => false,
00089         'fast_backend_autoload' => false,
00090         'auto_refresh_fast_cache' => true
00091     );
00092 
00098     protected $_slowBackend;
00099 
00105     protected $_fastBackend;
00106 
00112     protected $_fastBackendFillingPercentage = null;
00113 
00121     public function __construct(array $options = array())
00122     {
00123         parent::__construct($options);
00124         if ($this->_options['slow_backend'] === null) {
00125             Zend_Cache::throwException('slow_backend option has to set');
00126         }
00127         if ($this->_options['fast_backend'] === null) {
00128             Zend_Cache::throwException('fast_backend option has to set');
00129         }
00130         $this->_slowBackend = Zend_Cache::_makeBackend($this->_options['slow_backend'], $this->_options['slow_backend_options'], $this->_options['slow_backend_custom_naming'], $this->_options['slow_backend_autoload']);
00131         $this->_fastBackend = Zend_Cache::_makeBackend($this->_options['fast_backend'], $this->_options['fast_backend_options'], $this->_options['fast_backend_custom_naming'], $this->_options['fast_backend_autoload']);
00132         if (!in_array('Zend_Cache_Backend_ExtendedInterface', class_implements($this->_slowBackend))) {
00133             Zend_Cache::throwException('slow_backend must implement the Zend_Cache_Backend_ExtendedInterface interface');
00134         }
00135         if (!in_array('Zend_Cache_Backend_ExtendedInterface', class_implements($this->_fastBackend))) {
00136             Zend_Cache::throwException('fast_backend must implement the Zend_Cache_Backend_ExtendedInterface interface');
00137         }
00138         $this->_slowBackend->setDirectives($this->_directives);
00139         $this->_fastBackend->setDirectives($this->_directives);
00140     }
00141 
00148     public function test($id)
00149     {
00150         $fastTest = $this->_fastBackend->test($id);
00151         if ($fastTest) {
00152             return $fastTest;
00153         } else {
00154             return $this->_slowBackend->test($id);
00155         }
00156     }
00157 
00171     public function save($data, $id, $tags = array(), $specificLifetime = false, $priority = 8)
00172     {
00173         $usage = $this->_getFastFillingPercentage('saving');
00174         $boolFast = true;
00175         $lifetime = $this->getLifetime($specificLifetime);
00176         $preparedData = $this->_prepareData($data, $lifetime, $priority);
00177         if (($priority > 0) && (10 * $priority >= $usage)) {
00178             $fastLifetime = $this->_getFastLifetime($lifetime, $priority);
00179             $boolFast = $this->_fastBackend->save($preparedData, $id, array(), $fastLifetime);
00180         }
00181         $boolSlow = $this->_slowBackend->save($preparedData, $id, $tags, $lifetime);
00182         return ($boolFast && $boolSlow);
00183     }
00184 
00194     public function load($id, $doNotTestCacheValidity = false)
00195     {
00196         $res = $this->_fastBackend->load($id, $doNotTestCacheValidity);
00197         if ($res === false) {
00198             $res = $this->_slowBackend->load($id, $doNotTestCacheValidity);
00199             if ($res === false) {
00200                 // there is no cache at all for this id
00201                 return false;
00202             }
00203         }
00204         $array = unserialize($res);
00205         // maybe, we have to refresh the fast cache ?
00206         if ($this->_options['auto_refresh_fast_cache']) {
00207             if ($array['priority'] == 10) {
00208                 // no need to refresh the fast cache with priority = 10
00209                 return $array['data'];
00210             }
00211             $newFastLifetime = $this->_getFastLifetime($array['lifetime'], $array['priority'], time() - $array['expire']);
00212             // we have the time to refresh the fast cache
00213             $usage = $this->_getFastFillingPercentage('loading');
00214             if (($array['priority'] > 0) && (10 * $array['priority'] >= $usage)) {
00215                 // we can refresh the fast cache
00216                 $preparedData = $this->_prepareData($array['data'], $array['lifetime'], $array['priority']);
00217                 $this->_fastBackend->save($preparedData, $id, array(), $newFastLifetime);
00218             }
00219         }
00220         return $array['data'];
00221     }
00222 
00229     public function remove($id)
00230     {
00231         $boolFast = $this->_fastBackend->remove($id);
00232         $boolSlow = $this->_slowBackend->remove($id);
00233         return $boolFast && $boolSlow;
00234     }
00235 
00254     public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array())
00255     {
00256         switch($mode) {
00257             case Zend_Cache::CLEANING_MODE_ALL:
00258                 $boolFast = $this->_fastBackend->clean(Zend_Cache::CLEANING_MODE_ALL);
00259                 $boolSlow = $this->_slowBackend->clean(Zend_Cache::CLEANING_MODE_ALL);
00260                 return $boolFast && $boolSlow;
00261                 break;
00262             case Zend_Cache::CLEANING_MODE_OLD:
00263                 return $this->_slowBackend->clean(Zend_Cache::CLEANING_MODE_OLD);
00264             case Zend_Cache::CLEANING_MODE_MATCHING_TAG:
00265                 $ids = $this->_slowBackend->getIdsMatchingTags($tags);
00266                 $res = true;
00267                 foreach ($ids as $id) {
00268                     $bool = $this->remove($id);
00269                     $res = $res && $bool;
00270                 }
00271                 return $res;
00272                 break;
00273             case Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG:
00274                 $ids = $this->_slowBackend->getIdsNotMatchingTags($tags);
00275                 $res = true;
00276                 foreach ($ids as $id) {
00277                     $bool = $this->remove($id);
00278                     $res = $res && $bool;
00279                 }
00280                 return $res;
00281                 break;
00282             case Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG:
00283                 $ids = $this->_slowBackend->getIdsMatchingAnyTags($tags);
00284                 $res = true;
00285                 foreach ($ids as $id) {
00286                     $bool = $this->remove($id);
00287                     $res = $res && $bool;
00288                 }
00289                 return $res;
00290                 break;
00291             default:
00292                 Zend_Cache::throwException('Invalid mode for clean() method');
00293                 break;
00294         }
00295     }
00296 
00302     public function getIds()
00303     {
00304         return $this->_slowBackend->getIds();
00305     }
00306 
00312     public function getTags()
00313     {
00314         return $this->_slowBackend->getTags();
00315     }
00316 
00325     public function getIdsMatchingTags($tags = array())
00326     {
00327         return $this->_slowBackend->getIdsMatchingTags($tags);
00328     }
00329 
00338     public function getIdsNotMatchingTags($tags = array())
00339     {
00340         return $this->_slowBackend->getIdsNotMatchingTags($tags);
00341     }
00342 
00351     public function getIdsMatchingAnyTags($tags = array())
00352     {
00353         return $this->_slowBackend->getIdsMatchingAnyTags($tags);
00354     }
00355 
00356 
00362     public function getFillingPercentage()
00363     {
00364         return $this->_slowBackend->getFillingPercentage();
00365     }
00366 
00378     public function getMetadatas($id)
00379     {
00380         return $this->_slowBackend->getMetadatas($id);
00381     }
00382 
00390     public function touch($id, $extraLifetime)
00391     {
00392         return $this->_slowBackend->touch($id, $extraLifetime);
00393     }
00394 
00409     public function getCapabilities()
00410     {
00411         $slowBackendCapabilities = $this->_slowBackend->getCapabilities();
00412         return array(
00413             'automatic_cleaning' => $slowBackendCapabilities['automatic_cleaning'],
00414             'tags' => $slowBackendCapabilities['tags'],
00415             'expired_read' => $slowBackendCapabilities['expired_read'],
00416             'priority' => $slowBackendCapabilities['priority'],
00417             'infinite_lifetime' => $slowBackendCapabilities['infinite_lifetime'],
00418             'get_list' => $slowBackendCapabilities['get_list']
00419         );
00420     }
00421 
00430     private function _prepareData($data, $lifetime, $priority)
00431     {
00432         $lt = $lifetime;
00433         if ($lt === null) {
00434             $lt = 9999999999;
00435         }
00436         return serialize(array(
00437             'data' => $data,
00438             'lifetime' => $lifetime,
00439             'expire' => time() + $lt,
00440             'priority' => $priority
00441         ));
00442     }
00443 
00452     private function _getFastLifetime($lifetime, $priority, $maxLifetime = null)
00453     {
00454         if ($lifetime === null) {
00455             // if lifetime is null, we have an infinite lifetime
00456             // we need to use arbitrary lifetimes
00457             $fastLifetime = (int) (2592000 / (11 - $priority));
00458         } else {
00459             $fastLifetime = (int) ($lifetime / (11 - $priority));
00460         }
00461         if (($maxLifetime !== null) && ($maxLifetime >= 0)) {
00462             if ($fastLifetime > $maxLifetime) {
00463                 return $maxLifetime;
00464             }
00465         }
00466         return $fastLifetime;
00467     }
00468 
00476     public function ___expire($id)
00477     {
00478         $this->_fastBackend->remove($id);
00479         $this->_slowBackend->___expire($id);
00480     }
00481 
00482     private function _getFastFillingPercentage($mode)
00483     {
00484 
00485         if ($mode == 'saving') {
00486             // mode saving
00487             if ($this->_fastBackendFillingPercentage === null) {
00488                 $this->_fastBackendFillingPercentage = $this->_fastBackend->getFillingPercentage();
00489             } else {
00490                 $rand = rand(1, $this->_options['stats_update_factor']);
00491                 if ($rand == 1) {
00492                     // we force a refresh
00493                     $this->_fastBackendFillingPercentage = $this->_fastBackend->getFillingPercentage();
00494                 }
00495             }
00496         } else {
00497             // mode loading
00498             // we compute the percentage only if it's not available in cache
00499             if ($this->_fastBackendFillingPercentage === null) {
00500                 $this->_fastBackendFillingPercentage = $this->_fastBackend->getFillingPercentage();
00501             }
00502         }
00503         return $this->_fastBackendFillingPercentage;
00504     }
00505 
00506 }

Generated on Thu Apr 19 2012 17:01:16 for openbiz by  doxygen 1.7.2