Index: contributions/modules/cacherouter/engines/wincache.php --- contributions/modules/cacherouter/engines/wincache.php No Base Revision +++ contributions/modules/cacherouter/engines/wincache.php Locally New @@ -0,0 +1,242 @@ +fast_cache; + } + + /** + * get() + * Return item from cache if it is available. + * + * @param string $key + * The key to fetch. + * @return mixed object|bool + * Returns either the cache object or FALSE on failure + */ + function get($key) { + $cache = parent::get($this->key($key)); + if (isset($cache)) { + return $cache; + } + + $cache = wincache_ucache_get($this->key($key)); + if (is_object($cache) && $cache->serialized) { + $cache->data = unserialize($cache->data); + } + parent::set($this->key($key), $cache); + return $cache; + } + + /** + * set() + * Add item into cache. + * + * @param string $key + * The key to set. + * @param string $value + * The data to store in the cache. + * @param string $expire + * The time to expire in seconds. + * @param string $headers + * The page headers. + * @return bool + * Returns TRUE on success or FALSE on failure + */ + function set($key, $value, $expire = CACHE_PERMANENT, $headers = NULL) { + // Create new cache object. + $cache = new stdClass; + $cache->cid = $key; + $cache->created = time(); + $cache->expire = $expire; + $cache->headers = $headers; + + if ($expire != CACHE_PERMANENT && $expire != CACHE_TEMPORARY) { + // Check if $expire is a TTL (1 day or less) and not a timestamp + if ($expire <= 86400) { + $ttl = $expire; + } + else { + // Convert Drupal $expire, which is a timestamp, to a TTL + $ttl = $expire - time(); + } + } + else { + $ttl = 0; + } + + if (!is_string($value)) { + $cache->serialized = TRUE; + $cache->data = serialize($value); + } + else { + $cache->serialized = FALSE; + $cache->data = $value; + } + + $return = FALSE; + if (!empty($key) && $this->lock()) { + // Get lookup table to be able to keep track of bins + $lookup = wincache_ucache_get($this->lookup); + + // If the lookup table is empty, initialize table + if (empty($lookup)) { + $lookup = array(); + } + + // Set key to 1 so we can keep track of the bin + $lookup[$this->key($key)] = $expire; + + // Attempt to store full key and value + if (!wincache_ucache_set($this->key($key), $cache, $ttl)) { + unset($lookup[$this->key($key)]); + $return = FALSE; + } + else { + // Update static cache + parent::set($this->key($key), $cache); + $return = TRUE; + } + + // Resave the lookup table (even on failure) + wincache_ucache_set($this->lookup, $lookup); + + // Remove lock. + $this->unlock(); + } + + return $return; + } + + /** + * delete() + * Remove item from cache. + * + * @param string $key + * The key to set. + * @return mixed object|bool + * Returns either the cache object or FALSE on failure + */ + function delete($key) { + // Remove from static array cache. + parent::delete($this->key($key)); + + if (substr($key, strlen($key) - 1, 1) == '*') { + $key = $this->key(substr($key, 0, strlen($key) - 1)); + $lookup = wincache_ucache_get($this->lookup); + if (!empty($lookup)) { + foreach ($lookup as $k => $v) { + if (substr($k, 0, strlen($key)) == $key) { + wincache_ucache_delete($k); + unset($lookup[$k]); + } + } + } + + if ($this->lock()) { + wincache_ucache_set($this->lookup, $lookup); + $this->unlock(); + } + } + else { + if (!empty($key)) { + if (!wincache_ucache_delete($this->key($key))) { + return FALSE; + } else { + return TRUE; + } + } + } + } + + /** + * flush() + * Flush the entire cache. + * + * @param none + * @return mixed bool + * Returns TRUE + */ + function flush() { + parent::flush(); + if ($this->lock()) { + // Get lookup table to be able to keep track of bins + $lookup = wincache_ucache_get($this->lookup); + + // If the lookup table is empty, remove lock and return + if (empty($lookup)) { + $this->unlock(); + return TRUE; + } + + // Cycle through keys and remove each entry from the cache + foreach ($lookup as $k => $expire) { + if ($expire != CACHE_PERMANENT && $expire <= time()) { + wincache_ucache_delete($k); + unset($lookup[$k]); + } + } + + // Resave the lookup table (even on failure) + wincache_ucache_set($this->lookup, $lookup); + + // Remove lock + $this->unlock(); + } + + return TRUE; + } + + /** + * lock() + * lock the cache from other writes. + * + * @param none + * @return string + * Returns TRUE on success, FALSE on failure + */ + function lock() { + return wincache_lock(basename($this->lock)); + } + + /** + * unlock() + * unlock the cache from other writes. + * + * @param none + * @return bool + * Returns TRUE on success, FALSE on failure + */ + function unlock() { + return wincache_unlock(basename($this->lock)); + } + + function stats() { + $wincache_stats = wincache_ucache_info(); + $wincache_memory_stats = wincache_ucache_meminfo(); + $stats = array( + 'uptime' => $wincache_stats['total_cache_uptime'], + 'bytes_used' => $wincache_memory_stats['memory_total'] - $wincache_memory_stats['memory_free'], + 'bytes_total' => $wincache_memory_stats['memory_total'], + 'gets' => $wincache_stats['total_hit_count'], + //'sets' => $wincache_stats[''], + 'hits' => $wincache_stats['total_hit_count'] + $wincache_stats['total_miss_count'], + 'misses' => $wincache_stats['total_miss_count'], + 'req_rate' => (($wincache_stats['total_hit_count'] + $wincache_stats['total_miss_count']) / $wincache_stats['total_cache_uptime']), + 'hit_rate' => ($wincache_stats['total_hit_count'] / $wincache_stats['total_cache_uptime']), + 'miss_rate' => ($wincache_stats['total_miss_count'] / $wincache_stats['total_cache_uptime']), + //'set_rate' => ($wincache_stats['num_inserts'] / $wincache_stats['total_cache_uptime']), + ); + return $stats; + } +} \ No newline at end of file Index: contributions/modules/cacherouter/README.txt --- contributions/modules/cacherouter/README.txt Base (1.1.2.2) +++ contributions/modules/cacherouter/README.txt Locally Modified (Based On 1.1.2.2) @@ -47,8 +47,8 @@ default is for the default caching engine. All valid cache tables or "bins" can be added in addition, but you must have a default if you skip any bins. -For engine, the current available options are: apc, db, file, memcache and -xcache. +For engine, the current available options are: apc, db, file, memcache, +wincache (1.1.0+) and xcache. servers is only used in memcache and should be an array of host:port combinations. (e.g. 'servers' => array('localhost:11211', 'localhost:11212'))