[ Index ]
 

Code source de PHP PEAR 1.4.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/Cache/Container/ -> shm.php (source)

   1  <?php
   2  // +----------------------------------------------------------------------+
   3  // | PEAR :: Cache                                                        |
   4  // +----------------------------------------------------------------------+
   5  // | Copyright (c) 1997-2003 The PHP Group                                |
   6  // +----------------------------------------------------------------------+
   7  // | This source file is subject to version 2.0 of the PHP license,       |
   8  // | that is bundled with this package in the file LICENSE, and is        |
   9  // | available at through the world-wide-web at                           |
  10  // | http://www.php.net/license/2_02.txt.                                 |
  11  // | If you did not receive a copy of the PHP license and are unable to   |
  12  // | obtain it through the world-wide-web, please send a note to          |
  13  // | license@php.net so we can mail you a copy immediately.               |
  14  // +----------------------------------------------------------------------+
  15  // | Authors: Ulf Wendel <ulf.wendel@phpdoc.de>                           |
  16  // |          Sebastian Bergmann <sb@sebastian-bergmann.de>               |
  17  // +----------------------------------------------------------------------+
  18  //
  19  // $Id: shm.php,v 1.3 2003/01/04 11:54:46 mj Exp $
  20  
  21  require_once  'Cache/Container.php';
  22  
  23  /**
  24  * Stores cache data into shared memory.
  25  *
  26  * Well, this is not a very efficient implementation. Indeed it's much 
  27  * slower than the file container as far as my tests showed. Files are 
  28  * cached by most operating systems and it will be hard to write a faster 
  29  * caching algorithm using PHP.
  30  *
  31  * @author   Ulf Wendel <ulf.wendel@phpdoc.de>
  32  * @version  $Id: shm.php,v 1.3 2003/01/04 11:54:46 mj Exp $
  33  * @package  Cache
  34  */
  35  class Cache_Container_shm extends Cache_Container {
  36      /**
  37      * Key of the semaphore used to sync the SHM access
  38      * 
  39      * @var  int
  40      */
  41      var $sem_key = NULL;
  42  
  43      /**
  44      * Permissions of the semaphore used to sync the SHM access
  45      * 
  46      * @var  int
  47      */
  48      var $sem_perm = 0644;
  49  
  50      /**
  51      * Semaphore handler
  52      * 
  53      * @var  resource
  54      */
  55      var $sem_id = NULL;
  56  
  57      /**
  58      * Key of the shared memory block used to store cache data
  59      *
  60      * @var  int
  61      */
  62      var $shm_key = NULL;
  63  
  64      /**
  65      * Size of the shared memory block used
  66      * 
  67      * Note: the container does only use _one_ shm block no more!
  68      * 
  69      * @var  int
  70      */        
  71      var $shm_size = 131072;
  72  
  73      /**
  74      * Permissions of the shared memory block
  75      * 
  76      * @var  int
  77      */
  78      var $shm_perm = 0644;
  79  
  80      /**
  81      * Shared memory handler
  82      * 
  83      * @var resource
  84      */
  85      var $shm_id = NULL;
  86  
  87      /**
  88      * Hash of cache entries
  89      * 
  90      * Used by the garbage collection to find old entries.
  91      *
  92      * @var  array
  93      */
  94      var $entries = array();
  95  
  96      /**
  97      * Number of bytes consumed by the cache
  98      * 
  99      * @var  int
 100      */
 101      var $total_size = 0;
 102  
 103      /**
 104      * Creates a shared memory container
 105      *
 106      * @param array    shm_key, sem_key, shm_size, sem_perm, shm_perm
 107      */    
 108      function Cache_Container_shm($options = '') {
 109          if (is_array($options))
 110              $this->setOptions($options, array_merge($this->allowed_options, 
 111                                                      array('shm_key',  'sem_key', 
 112                                                            'shm_size', 'sem_perm',
 113                                                            'shm_perm'
 114                                                           )
 115                                          )
 116                                 );
 117  
 118          // Cache::Container high- and lowwater defaults should be overridden if
 119          // not already done by the user
 120          if (!isset($options['highwater'])) 
 121              $this->highwater = round(0.75 * 131072);
 122          if (!isset($options['lowwater']))
 123              $this->lowwater = round(0.5 * 131072);
 124  
 125          if (!isset($options['shm_size']))
 126              $this->shm_size = 131072;
 127  
 128          //get SHM and Semaphore handles
 129          if (!($this->shm_id = shmop_open($this->shm_key, 'c', $this->shm_perm, $this->shm_size)))
 130              new Cache_Error("Can't open SHM segment '{$this->shm_key}', size '{$this->shm_size}'.",
 131                              __FILE__,
 132                              __LINE__
 133                             );
 134  
 135          if (!($this->sem_id = sem_get($this->sem_key, 1, $this->sem_perm)))
 136              new Cache_Error("Can't get semaphore '{$this->sem_key}' using perms '{$this->sem_perm}'.",
 137                              __FILE__,
 138                              __LINE__
 139                             );
 140  
 141      } // end constructor
 142  
 143      function fetch($id, $group) {
 144          sem_acquire($this->sem_id);
 145  
 146          $cachedata = shmop_read($this->shm_id, 0, $this->shm_size);
 147  
 148          sem_release($this->sem_id);
 149  
 150          $cachedata = $this->decode($cachedata);
 151  
 152          if (!isset($cachedata[$group][$id]))
 153              return array(NULL, NULL, NULL);
 154          else 
 155              $cachedata = $cachedata[$group][$id];
 156  
 157          return array($cachedata['expire'],
 158                       $cachedata['cachedata'],
 159                       $cachedata['userdata']
 160                      );
 161      } // end func fetch
 162  
 163      function save($id, $data, $expire, $group, $userdata) {
 164          $this->flushPreload($id, $group);
 165  
 166          sem_acquire($this->sem_id);
 167  
 168          $cachedata = $this->decode(shmop_read($this->shm_id, 0, $this->shm_size));
 169          $cachedata[$group][$id] = array('expire'    => $this->getExpiresAbsolute($expire),
 170                                          'cachedata' => $data,
 171                                          'userdata'  => $userdata,
 172                                          'changed'   => time()
 173                                         );
 174  
 175          if (strlen($newdata = $this->encode($cachedata)) > $this->shm_size)
 176              $cachedata = $this->garbageCollection(time(), $cachedata);
 177  
 178          shmop_write($this->shm_id, $newdata, 0);
 179  
 180          sem_release($this->sem_id);
 181  
 182          return true;
 183      } // end func save
 184  
 185      function remove($id, $group) {
 186          $this->flushPreload($id, $group);
 187  
 188          sem_acquire($this->sem_id);
 189  
 190          $cachedata = $this->decode(shmop_read($this->shm_id, 0, $this->shm_size));
 191          unset($cachedata[$group][$id]);
 192          shmop_write($this->shm_id, $this->encode($cachedata), 0);
 193  
 194          sem_release($this->sem_id);
 195      } // end func remove
 196  
 197      function flush($group = '') {
 198          $this->flushPreload();
 199  
 200          sem_acquire($this->sem_id);
 201  
 202          shmop_write($this->shm_id, $this->encode(array()), 0);
 203  
 204          sem_release($this->sem_id);
 205      } // end func flush
 206  
 207      function idExists($id, $group) {
 208          sem_acquire($this->sem_id);
 209  
 210          $cachedata = shm_read($this->shm_id, 0, $this->shm_size);
 211  
 212          sem_release($this->sem_id);
 213  
 214          $cachedata = $this->decode($cachedata);
 215  
 216          return isset($cachedata[$group][$id]);
 217      } // end func isExists
 218  
 219      function garbageCollection($maxlifetime, $cachedata = array()) {
 220          if ($lock = empty($cachedata)) {
 221              sem_acquire($this->sem_id);
 222              $cachedata = $this->decode(shmop_read($this->shm_id, 0, $this->shm_size));
 223          }
 224  
 225          $this->doGarbageCollection($maxlifetime, &$cachedata);
 226          if ($this->total_size > $this->highwater) {
 227              krsort($this->entries);
 228              reset($this->entries);
 229  
 230              while ($this->total_size > $this->lowwater && list($size, $entries) = each($this->entries)) {
 231                  reset($entries);
 232  
 233                  while (list($k, $entry) = each($entries)) {
 234                      unset($cachedata[$entry['group']][$entry['id']]);
 235                      $this->total_size -= $size;
 236                  }
 237              }
 238          }
 239  
 240          if ($lock)
 241              sem_release($this->sem_id);
 242  
 243          $this->entries = array();
 244          $this->total_size = 0;
 245  
 246          return $cachedata;           
 247      } // end func garbageCollection
 248  
 249      function doGarbageCollection($maxlifetime, &$cachedata) {
 250          $changed = time() - $maxlifetime;
 251          $removed = 0;
 252  
 253          reset($cachedata);
 254  
 255          while (list($group, $groupdata) = each($cachedata)) {
 256              reset($groupdata);
 257  
 258              while (list($id, $data) = each($groupdata)) {
 259                  if ($data['expire'] < time() || $data['changed'] < $changed) {
 260                      unset($cachedata[$group][$id]);
 261                  }
 262              }
 263  
 264              // ugly but simple to implement :/
 265              $size = strlen($this->encode($data));
 266              $this->entries[$size][] = array('group' => $group,
 267                                              'id'    => $id
 268                                             );
 269  
 270              $this->total_size += $size;
 271          }
 272  
 273          return $removed;
 274      }  // end func doGarbageCollection
 275  } // end class Cache_Container_shm
 276  ?>


Généré le : Sun Feb 25 14:08:00 2007 par Balluche grâce à PHPXref 0.7