| [ Index ] |
|
Code source de PHP PEAR 1.4.5 |
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 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 14:08:00 2007 | par Balluche grâce à PHPXref 0.7 |