| 1 | <?php |
|---|
| 2 | require_once(IA_ROOT_DIR . "common/string.php"); |
|---|
| 3 | |
|---|
| 4 | // Check if there is something in the cache newer that date. |
|---|
| 5 | // If date is null age doesn't matter. |
|---|
| 6 | // Date must be unix timestamp. |
|---|
| 7 | // Old stuff is deleted. |
|---|
| 8 | // |
|---|
| 9 | // Only returns true/false. |
|---|
| 10 | |
|---|
| 11 | // Used internally to determine file path from cache_id |
|---|
| 12 | function _disk_cache_path($cache_id) { |
|---|
| 13 | return IA_ROOT_DIR . "cache/" . $cache_id; |
|---|
| 14 | } |
|---|
| 15 | |
|---|
| 16 | // Recursively delete directories |
|---|
| 17 | function _recursive_delete($path) { |
|---|
| 18 | $path = realpath($path); |
|---|
| 19 | log_assert($path != IA_ROOT_DIR . "cache/" && |
|---|
| 20 | starts_with($path, IA_ROOT_DIR . "cache/")); |
|---|
| 21 | foreach (glob($path . "/*") as $file_name) { |
|---|
| 22 | if (is_dir($file_name)) { |
|---|
| 23 | _recursive_delete($file_name); |
|---|
| 24 | } else if (is_file($file_name)) { |
|---|
| 25 | unlink($file_name); |
|---|
| 26 | } |
|---|
| 27 | } |
|---|
| 28 | rmdir($path); |
|---|
| 29 | } |
|---|
| 30 | |
|---|
| 31 | function disk_cache_has($cache_id, $date = null) { |
|---|
| 32 | $file_name = _disk_cache_path($cache_id); |
|---|
| 33 | |
|---|
| 34 | if (!@is_readable($file_name)) { |
|---|
| 35 | return false; |
|---|
| 36 | } else { |
|---|
| 37 | if (is_null($date) || $date === false) { |
|---|
| 38 | return true; |
|---|
| 39 | } |
|---|
| 40 | |
|---|
| 41 | // Check mtime |
|---|
| 42 | $mtime = @filemtime($file_name); |
|---|
| 43 | |
|---|
| 44 | // Delete old stuff. |
|---|
| 45 | if ($mtime === false || $mtime < $date) { |
|---|
| 46 | @unlink($fname); |
|---|
| 47 | return false; |
|---|
| 48 | } else { |
|---|
| 49 | return true; |
|---|
| 50 | } |
|---|
| 51 | } |
|---|
| 52 | } |
|---|
| 53 | |
|---|
| 54 | // Get an object from the cache, or FALSE if nothing is found. |
|---|
| 55 | function disk_cache_get($cache_id) { |
|---|
| 56 | $file_name = _disk_cache_path($cache_id); |
|---|
| 57 | |
|---|
| 58 | if (@is_readable($file_name)) { |
|---|
| 59 | if (IA_LOG_DISK_CACHE) { |
|---|
| 60 | log_print("CACHE: DISK: HIT on $cache_id"); |
|---|
| 61 | } |
|---|
| 62 | return file_get_contents($file_name); |
|---|
| 63 | } else { |
|---|
| 64 | if (IA_LOG_DISK_CACHE) { |
|---|
| 65 | log_print("CACHE: DISK: MISS on $cache_id"); |
|---|
| 66 | } |
|---|
| 67 | return false; |
|---|
| 68 | } |
|---|
| 69 | } |
|---|
| 70 | |
|---|
| 71 | // If $cache_id is in cache, then pass it to the client. |
|---|
| 72 | // Fails if not found. |
|---|
| 73 | function disk_cache_serve($cache_id, $http_file_name, $mime_type = null) { |
|---|
| 74 | require_once(IA_ROOT_DIR . 'www/utilities.php'); |
|---|
| 75 | $file_name = _disk_cache_path($cache_id); |
|---|
| 76 | |
|---|
| 77 | if (IA_LOG_DISK_CACHE) { |
|---|
| 78 | log_print("CACHE: DISK: SERVE $cache_id"); |
|---|
| 79 | } |
|---|
| 80 | http_serve($file_name, $http_file_name, $mime_type); |
|---|
| 81 | } |
|---|
| 82 | |
|---|
| 83 | // Place an object in the cache. |
|---|
| 84 | // Object should expire after $ttl, but it's only a hint. |
|---|
| 85 | // Always returns $buffer. |
|---|
| 86 | function disk_cache_set($cache_id, $buffer, $ttl = 0) { |
|---|
| 87 | $file_name = _disk_cache_path($cache_id); |
|---|
| 88 | |
|---|
| 89 | if (!is_dir(dirname($file_name))) { |
|---|
| 90 | log_assert(!file_exists(dirname($file_name)), |
|---|
| 91 | "Cache directory contains invalid files"); |
|---|
| 92 | |
|---|
| 93 | $old_umask = umask(0); |
|---|
| 94 | @mkdir(dirname($file_name), 0777, true); |
|---|
| 95 | umask($old_umask); |
|---|
| 96 | } |
|---|
| 97 | $ret = @file_put_contents($file_name, $buffer, LOCK_EX); |
|---|
| 98 | |
|---|
| 99 | if (IA_LOG_DISK_CACHE) { |
|---|
| 100 | if ($ret) { |
|---|
| 101 | log_print("CACHE: DISK: SET $cache_id"); |
|---|
| 102 | } else { |
|---|
| 103 | log_warn("CACHE: DISK: FAIL SET $cache_id"); |
|---|
| 104 | } |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | return $buffer; |
|---|
| 108 | } |
|---|
| 109 | |
|---|
| 110 | // Delete something from the disk cache. |
|---|
| 111 | function disk_cache_delete($cache_id) { |
|---|
| 112 | $file_name = _disk_cache_path($cache_id); |
|---|
| 113 | @unlink($file_name); |
|---|
| 114 | } |
|---|
| 115 | |
|---|
| 116 | // Delete the entire disk cache |
|---|
| 117 | function disk_cache_purge() { |
|---|
| 118 | foreach (glob(IA_ROOT_DIR . "cache/*", GLOB_ONLYDIR) as $dir_name) { |
|---|
| 119 | _recursive_delete($dir_name); |
|---|
| 120 | } |
|---|
| 121 | |
|---|
| 122 | foreach (glob(IA_ROOT_DIR . "cache/*") as $file_name) { |
|---|
| 123 | unlink($file_name); |
|---|
| 124 | } |
|---|
| 125 | } |
|---|
| 126 | |
|---|
| 127 | // |
|---|
| 128 | // Memory caching implementation depends on IA_MEM_CACHE_METHOD. |
|---|
| 129 | // There are only four functions, which should be enough for just about everything. |
|---|
| 130 | // |
|---|
| 131 | // You can store arrays, ints, string, null but not booleans because they're |
|---|
| 132 | // used by the mem_cache_get function. You could store booleans as 0/1 however. |
|---|
| 133 | // |
|---|
| 134 | // FUNCTIONS: |
|---|
| 135 | // mem_cache_get gets an object from the cache, or FALSE if not found. |
|---|
| 136 | // A null result means it a null value was stored. |
|---|
| 137 | // |
|---|
| 138 | // mem_cache_set places an object in the cache with a certain ttl and |
|---|
| 139 | // returns the untouched object. Booleans can't be stored. |
|---|
| 140 | // |
|---|
| 141 | // mem_cache_delete removes something from the cache, use this when the |
|---|
| 142 | // object is no longer valid. |
|---|
| 143 | // |
|---|
| 144 | // mem_cache_purge deletes everything from the cache. Try to avoid calling it. |
|---|
| 145 | // |
|---|
| 146 | if (IA_MEM_CACHE_METHOD == 'none') { |
|---|
| 147 | |
|---|
| 148 | // Fake cache implementation/ |
|---|
| 149 | |
|---|
| 150 | function mem_cache_get($cache_id) { |
|---|
| 151 | return false; |
|---|
| 152 | } |
|---|
| 153 | |
|---|
| 154 | function mem_cache_set($cache_id, $object, $ttl = IA_MEM_CACHE_EXPIRATION) { |
|---|
| 155 | return $object; |
|---|
| 156 | } |
|---|
| 157 | |
|---|
| 158 | function mem_cache_delete($cache_id) { |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | function mem_cache_purge() { |
|---|
| 162 | } |
|---|
| 163 | |
|---|
| 164 | } else if (IA_MEM_CACHE_METHOD == 'eaccelerator') { |
|---|
| 165 | |
|---|
| 166 | // eAccelerator SHM memory cache |
|---|
| 167 | |
|---|
| 168 | function mem_cache_get($cache_id) { |
|---|
| 169 | $res = eaccelerator_get($cache_id); |
|---|
| 170 | if ($res === null) { |
|---|
| 171 | if (IA_LOG_MEM_CACHE) { |
|---|
| 172 | log_print("MEM CACHE: miss on $cache_id"); |
|---|
| 173 | } |
|---|
| 174 | return false; |
|---|
| 175 | } else { |
|---|
| 176 | if (IA_LOG_MEM_CACHE) { |
|---|
| 177 | log_print("MEM CACHE: hit on $cache_id"); |
|---|
| 178 | } |
|---|
| 179 | return unserialize($res); |
|---|
| 180 | } |
|---|
| 181 | } |
|---|
| 182 | |
|---|
| 183 | function mem_cache_set($cache_id, $object, $ttl = IA_MEM_CACHE_EXPIRATION) { |
|---|
| 184 | log_assert($object !== 'false', "Can't cache false values"); |
|---|
| 185 | eaccelerator_put($cache_id, serialize($object), $ttl); |
|---|
| 186 | |
|---|
| 187 | if (IA_LOG_MEM_CACHE) { |
|---|
| 188 | log_print("MEM CACHE: store $cache_id"); |
|---|
| 189 | } |
|---|
| 190 | |
|---|
| 191 | return $object; |
|---|
| 192 | } |
|---|
| 193 | |
|---|
| 194 | function mem_cache_delete($cache_id) { |
|---|
| 195 | eaccelerator_rm($cache_id); |
|---|
| 196 | if (IA_LOG_MEM_CACHE) { |
|---|
| 197 | log_print("MEM CACHE: delete $cache_id"); |
|---|
| 198 | } |
|---|
| 199 | } |
|---|
| 200 | |
|---|
| 201 | // Purge the entire SHM cache. |
|---|
| 202 | // FIXME: This does not work |
|---|
| 203 | function mem_cache_purge() { |
|---|
| 204 | if (IA_LOG_MEM_CACHE) { |
|---|
| 205 | log_print("MEM CACHE: purge"); |
|---|
| 206 | } |
|---|
| 207 | eaccelerator_gc(); |
|---|
| 208 | } |
|---|
| 209 | |
|---|
| 210 | } else if (IA_MEM_CACHE_METHOD == 'memcached') { |
|---|
| 211 | |
|---|
| 212 | // memcached cache implementation. |
|---|
| 213 | |
|---|
| 214 | $_memcache = memcache_pconnect('localhost'); |
|---|
| 215 | |
|---|
| 216 | function mem_cache_get($cache_id) { |
|---|
| 217 | global $_memcache; |
|---|
| 218 | $res = memcache_get($_memcache, $cache_id); |
|---|
| 219 | if ($res === false) { |
|---|
| 220 | if (IA_LOG_MEM_CACHE) { |
|---|
| 221 | log_print("MEM CACHE: miss on $cache_id"); |
|---|
| 222 | } |
|---|
| 223 | return false; |
|---|
| 224 | } else { |
|---|
| 225 | if (IA_LOG_MEM_CACHE) { |
|---|
| 226 | log_print("MEM CACHE: hit on $cache_id"); |
|---|
| 227 | } |
|---|
| 228 | return unserialize($res); |
|---|
| 229 | } |
|---|
| 230 | } |
|---|
| 231 | |
|---|
| 232 | function mem_cache_set($cache_id, $object, $ttl = IA_MEM_CACHE_EXPIRATION) { |
|---|
| 233 | global $_memcache; |
|---|
| 234 | log_assert($object !== 'false', "Can't cache false values"); |
|---|
| 235 | memcache_set($_memcache, $cache_id, serialize($object), 0, $ttl); |
|---|
| 236 | |
|---|
| 237 | if (IA_LOG_MEM_CACHE) { |
|---|
| 238 | log_print("MEM CACHE: store $cache_id"); |
|---|
| 239 | } |
|---|
| 240 | return $object; |
|---|
| 241 | } |
|---|
| 242 | |
|---|
| 243 | function mem_cache_delete($cache_id) { |
|---|
| 244 | global $_memcache; |
|---|
| 245 | memcache_delete($_memcache, $cache_id); |
|---|
| 246 | |
|---|
| 247 | if (IA_LOG_MEM_CACHE) { |
|---|
| 248 | log_print("MEM CACHE: delete $cache_id"); |
|---|
| 249 | } |
|---|
| 250 | } |
|---|
| 251 | |
|---|
| 252 | function mem_cache_purge() { |
|---|
| 253 | global $_memcache; |
|---|
| 254 | memcache_flush($_memcache); |
|---|
| 255 | |
|---|
| 256 | if (IA_LOG_MEM_CACHE) { |
|---|
| 257 | log_print("MEM CACHE: purge"); |
|---|
| 258 | } |
|---|
| 259 | } |
|---|
| 260 | |
|---|
| 261 | } else if (IA_MEM_CACHE_METHOD == 'apc') { |
|---|
| 262 | // APC cache implementation |
|---|
| 263 | function mem_cache_get($cache_id) { |
|---|
| 264 | $res = apc_fetch($cache_id); |
|---|
| 265 | if ($res === false) { |
|---|
| 266 | if (IA_LOG_MEM_CACHE) { |
|---|
| 267 | log_print("MEM CACHE: miss on $cache_id"); |
|---|
| 268 | } |
|---|
| 269 | return false; |
|---|
| 270 | } else { |
|---|
| 271 | if (IA_LOG_MEM_CACHE) { |
|---|
| 272 | log_print("MEM CACHE: hit on $cache_id"); |
|---|
| 273 | } |
|---|
| 274 | return unserialize($res); |
|---|
| 275 | } |
|---|
| 276 | } |
|---|
| 277 | |
|---|
| 278 | function mem_cache_set($cache_id, $object, $ttl = IA_MEM_CACHE_EXPIRATION) { |
|---|
| 279 | log_assert($object !== 'false', "Can't cache false values"); |
|---|
| 280 | apc_store($cache_id, serialize($object), $ttl); |
|---|
| 281 | |
|---|
| 282 | if (IA_LOG_MEM_CACHE) { |
|---|
| 283 | log_print("MEM CACHE: store $cache_id"); |
|---|
| 284 | } |
|---|
| 285 | return $object; |
|---|
| 286 | } |
|---|
| 287 | |
|---|
| 288 | function mem_cache_delete($cache_id) { |
|---|
| 289 | apc_delete($cache_id); |
|---|
| 290 | if (IA_LOG_MEM_CACHE) { |
|---|
| 291 | log_print("MEM CACHE: delete $cache_id"); |
|---|
| 292 | } |
|---|
| 293 | } |
|---|
| 294 | |
|---|
| 295 | function mem_cache_purge() { |
|---|
| 296 | if (IA_LOG_MEM_CACHE) { |
|---|
| 297 | log_print("MEM CACHE: purge"); |
|---|
| 298 | } |
|---|
| 299 | apc_clear_cache(); |
|---|
| 300 | } |
|---|
| 301 | } |
|---|
| 302 | |
|---|
| 303 | ?> |
|---|