Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
cache_storage_memcache.inc
1 <?php
25 require_once SQ_CORE_PACKAGE_PATH.'/system/cache_storage/cache_storage/cache_storage.inc';
26 
27 define('SQ_CACHE_MEMCACHE_PREFIX', 'sq_cache|');
28 define('SQ_CACHE_MEMCACHE_ASSET_INDEX_PREFIX', 'sq_cache_asset_index|');
29 define('SQ_CACHE_MEMCACHE_URL_INDEX_PREFIX', 'sq_cache_url_index|');
30 
46 {
52  private $_memcache;
53 
54 
61  function __construct($assetid=0)
62  {
63  parent::__construct($assetid);
64 
65  }//end constructor
66 
67 
68  public function initMemcache()
69  {
70  assert_true(extension_loaded('memcache'), 'Cannot use Memcache Cache Storage; it requires the memcache PECL extension installed within PHP, which is not installed');
71  assert_true(is_file(SQ_DATA_PATH.'/private/conf/memcache.inc'), 'Cannot use Memcache Cache Storage; the Memcache configuration file is not set');
72 
73  $memcache_conf = require(SQ_DATA_PATH.'/private/conf/memcache.inc');
74  $hosts =& $memcache_conf['hosts'];
75  $services =& $memcache_conf['services'];
76 
77  assert_true(count($hosts) > 0, 'Cannot use Memcache Cache Storage; no hosts are defined in the Memcache configuration file');
78  assert_true(array_key_exists('cache_manager', $services) === TRUE, 'Cannot use Memcache Cache Storage; no Memcache hosts are assigned to cache manager');
79  assert_true(count($services['cache_manager']) > 0, 'Cannot use Memcache Cache Storage; no Memcache hosts are assigned to cache manager');
80 
81  // If PHP has the memcache module installed, instantiate it and try to load some config.
82  $this->_memcache = new Memcache;
83 
84  foreach ($services['cache_manager'] as $host_key => $weight) {
85  assert_true(array_key_exists($host_key, $hosts) === TRUE, 'Cannot use Memcache Cache Storage; host key "'.$host_key.'" assigned for use for cache manager but not defined as a host');
86  $host = $hosts[$host_key];
87  $this->_memcache->addServer($host['host'], $host['port'], $host['persistent'], $weight, $host['timeout'], $host['retry_interval'], $host['status'], Array($this, 'failureCallback'));
88  }
89 
90  $this->_memcache->setCompressThreshold($memcache_conf['compression_threshold'], $memcache_conf['compression_min_saving']);
91 
92  }//end initMemcache()
93 
94 
102  public static function isAvailable()
103  {
104  if (extension_loaded('memcache') === TRUE) {
105  if (is_file(SQ_DATA_PATH.'/private/conf/memcache.inc')) {
106  return TRUE;
107  } else {
108  return FALSE;
109  }
110  } else {
111  return FALSE;
112  }
113 
114  }//end isAvailable()
115 
116 
149  function store($cache_key, $perm_key, $url, $assetid, $data, $expiry)
150  {
151  if (!$this->_memcache) $this->initMemcache();
152 
153  if ($this->_memcache) {
154  // 0 is handled as infinite rather than 0 seconds in memcache. If we have 0,
155  // don't set in cache, so that we're compatible with the standard cache storage.
156  $expiry_length = $expiry - time();
157  if ($expiry_length === 0) return FALSE;
158 
159  // For the indexes, we want just the base URL, no query string or trailing slash.
160  $index_url = md5(trim(preg_replace('/\?.*/', '', $url), '/'));
161 
162  $url = md5($url);
163  $mcache_key = SQ_CACHE_MEMCACHE_PREFIX."$cache_key|$perm_key|$url|$assetid";
164 
165  // Get both the indexes at once (faster).
166  $indexes = $this->_memcache->get(Array(SQ_CACHE_MEMCACHE_ASSET_INDEX_PREFIX.$assetid, SQ_CACHE_MEMCACHE_URL_INDEX_PREFIX.$index_url));
167 
168  // Update the assetid index if necessary.
169  $assetid_hits = isset($indexes[SQ_CACHE_MEMCACHE_ASSET_INDEX_PREFIX.$assetid]) ? $indexes[SQ_CACHE_MEMCACHE_ASSET_INDEX_PREFIX.$assetid] : Array();
170  if (!in_array($mcache_key, $assetid_hits)) {
171  array_push($assetid_hits, $mcache_key);
172  $this->_memcache->set(SQ_CACHE_MEMCACHE_ASSET_INDEX_PREFIX.$assetid, $assetid_hits);
173  }
174 
175  // Update the url index if necessary.
176  $url_hits = isset($indexes[SQ_CACHE_MEMCACHE_URL_INDEX_PREFIX.$index_url]) ? $indexes[SQ_CACHE_MEMCACHE_URL_INDEX_PREFIX.$index_url] : Array();
177  if (!in_array($mcache_key, $url_hits)) {
178  array_push($url_hits, $mcache_key);
179  $this->_memcache->set(SQ_CACHE_MEMCACHE_URL_INDEX_PREFIX.$index_url, $url_hits);
180  }
181 
182  // Save the actual cache entry
183  $ok = $this->_memcache->set($mcache_key, $data, FALSE, $expiry_length);
184  return $ok;
185  } else {
186  return FALSE;
187  }
188 
189  }//end store()
190 
191 
212  function read($cache_key, $perm_key, $url, $assetid)
213  {
214  if (!$this->_memcache) $this->initMemcache();
215 
216  if ($this->_memcache) {
217  $url = md5($url);
218  return $this->_memcache->get(SQ_CACHE_MEMCACHE_PREFIX."$cache_key|$perm_key|$url|$assetid", FALSE);
219  } else {
220  return FALSE;
221  }
222 
223  }//end read()
224 
225 
232  function clearAll()
233  {
234  if (!$this->_memcache) $this->initMemcache();
235 
236  if ($this->_memcache) {
237  return $this->_memcache->flush();
238  } else {
239  return FALSE;
240  }
241 
242  }//end clearAll()
243 
244 
254  {
255  return TRUE;
256 
257  }//end cleanExpiredEntries()
258 
259 
266  function canClearByAssetid()
267  {
268  return TRUE;
269 
270  }//end canClearByAssetid()
271 
272 
281  function clear($assetids)
282  {
283  if (!$this->_memcache) $this->initMemcache();
284 
285  // For each assetid, fetch the asset index and delete everything we find. Including the index.
286  foreach ($assetids as $assetid) {
287  $assetid_hits = $this->_memcache->get(SQ_CACHE_MEMCACHE_ASSET_INDEX_PREFIX.$assetid, FALSE);
288  if ($assetid_hits) {
289  foreach ($assetid_hits as $key) {
290  $this->_memcache->delete($key);
291  }
292  $this->_memcache->delete(SQ_CACHE_MEMCACHE_ASSET_INDEX_PREFIX.$assetid);
293  }
294  }
295 
296 
297  }//end clear()
298 
299 
310  function clearCachedAssetsByUrl($url)
311  {
312  if (!$this->_memcache) $this->initMemcache();
313 
314  // Fetch the URL index and delete anything we find. Including the index.
315  $index_key = SQ_CACHE_MEMCACHE_URL_INDEX_PREFIX.md5($url);
316  $url_hits = $this->_memcache->get($index_key);
317 
318  if ($url_hits) {
319  foreach ($url_hits as $key) {
320  $this->_memcache->delete($key);
321  }
322  $this->_memcache->delete($index_key);
323  }
324 
325  }//end clearCachedAssetsByUrl
326 
327 
339  function getFilePaths($assetids)
340  {
341  return Array();
342 
343  }//end getFilePaths()
344 
345 
357  function getAllFilePaths($option='')
358  {
359  return Array();
360 
361  }//end getAllFilePaths()
362 
363 
373  function failureCallback($hostname, $port)
374  {
375  log_error(get_class()." failure communicating with $hostname:$port", E_USER_WARNING);
376 
377  }//end failureCallback()
378 
379 
380 }//end class
381 
382 ?>