Permalink
Browse files

Adding Wincache support. Wincache is a fast shared memory

cache that performs very well on windows platforms.
  • Loading branch information...
1 parent 97e51f1 commit 9e4c367688d1aa54aeb18098ed2c09bb1cc4c61e @markstory markstory committed Jun 21, 2011
Showing with 322 additions and 0 deletions.
  1. +124 −0 lib/Cake/Cache/Engine/WincacheEngine.php
  2. +198 −0 lib/Cake/Test/Case/Cache/Engine/WincacheEngineTest.php
View
124 lib/Cake/Cache/Engine/WincacheEngine.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Wincache storage engine for cache.
+ *
+ * Supports wincache 1.1.0 and higher.
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://cakephp.org CakePHP(tm) Project
+ * @package cake.libs.cache
+ * @since CakePHP(tm) v 1.2.0.4933
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Wincache storage engine for cache
+ *
+ * @package cake.libs.cache
+ */
+class WincacheEngine extends CacheEngine {
+
+/**
+ * Initialize the Cache Engine
+ *
+ * Called automatically by the cache frontend
+ * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
+ *
+ * @param array $settings array of setting for the engine
+ * @return boolean True if the engine has been successfully initialized, false if not
+ * @see CacheEngine::__defaults
+ */
+ public function init($settings = array()) {
+ parent::init(array_merge(array(
+ 'engine' => 'Wincache',
+ 'prefix' => Inflector::slug(APP_DIR) . '_'),
+ $settings));
+ return function_exists('wincache_ucache_info');
+ }
+
+/**
+ * Write data for key into cache
+ *
+ * @param string $key Identifier for the data
+ * @param mixed $value Data to be cached
+ * @param integer $duration How long to cache the data, in seconds
+ * @return boolean True if the data was successfully cached, false on failure
+ */
+ public function write($key, $value, $duration) {
+ $expires = time() + $duration;
+
+ $data = array(
+ $key . '_expires' => $expires,
+ $key => $value
+ );
+ $result = wincache_ucache_set($data, null, $duration);
+ return empty($result);
+ }
+
+/**
+ * Read a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return mixed The cached data, or false if the data doesn't exist, has expired, or if
+ * there was an error fetching it
+ */
+ public function read($key) {
+ $time = time();
+ $cachetime = intval(wincache_ucache_get($key . '_expires'));
+ if ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime) {
+ return false;
+ }
+ return wincache_ucache_get($key);
+ }
+
+/**
+ * Increments the value of an integer cached key
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to increment
+ * @return New incremented value, false otherwise
+ */
+ public function increment($key, $offset = 1) {
+ return wincache_ucache_inc($key, $offset);
+ }
+
+/**
+ * Decrements the value of an integer cached key
+ *
+ * @param string $key Identifier for the data
+ * @param integer $offset How much to subtract
+ * @return New decremented value, false otherwise
+ */
+ public function decrement($key, $offset = 1) {
+ return wincache_ucache_dec($key, $offset);
+ }
+
+/**
+ * Delete a key from the cache
+ *
+ * @param string $key Identifier for the data
+ * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
+ */
+ public function delete($key) {
+ return wincache_ucache_delete($key);
+ }
+
+/**
+ * Delete all keys from the cache. This will clear every cache value stored
+ * in wincache.
+ *
+ * @return boolean True if the cache was successfully cleared, false otherwise
+ */
+ public function clear($check) {
+ return wincache_ucache_clear();
+ }
+
+}
View
198 lib/Cake/Test/Case/Cache/Engine/WincacheEngineTest.php
@@ -0,0 +1,198 @@
+<?php
+/**
+ * WincacheEngineTest file
+ *
+ * PHP 5
+ *
+ * CakePHP(tm) Tests <http://book.cakephp.org/view/1196/Testing>
+ * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link http://book.cakephp.org/view/1196/Testing CakePHP(tm) Tests
+ * @package cake.tests.cases.libs.cache
+ * @since CakePHP(tm) v 1.2.0.5434
+ * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+App::uses('Cache', 'Cache');
+
+/**
+ * WincacheEngineTest class
+ *
+ * @package cake.tests.cases.libs.cache
+ */
+class WincacheEngineTest extends CakeTestCase {
+
+/**
+ * setUp method
+ *
+ * @access public
+ * @return void
+ */
+ public function setUp() {
+ $this->skipIf(!function_exists('wincache_ucache_set'), 'Wincache is not installed or configured properly.');
+ $this->_cacheDisable = Configure::read('Cache.disable');
+ Configure::write('Cache.disable', false);
+ Cache::config('wincache', array('engine' => 'Wincache', 'prefix' => 'cake_'));
+ }
+
+/**
+ * tearDown method
+ *
+ * @access public
+ * @return void
+ */
+ public function tearDown() {
+ Configure::write('Cache.disable', $this->_cacheDisable);
+ Cache::drop('wincache');
+ Cache::config('default');
+ }
+
+/**
+ * testReadAndWriteCache method
+ *
+ * @access public
+ * @return void
+ */
+ public function testReadAndWriteCache() {
+ Cache::set(array('duration' => 1), 'wincache');
+
+ $result = Cache::read('test', 'wincache');
+ $expecting = '';
+ $this->assertEqual($result, $expecting);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('test', $data, 'wincache');
+ var_dump(wincache_ucache_get('cake_test'));
+ $this->assertTrue($result);
+
+ $result = Cache::read('test', 'wincache');
+ $expecting = $data;
+ $this->assertEqual($result, $expecting);
+
+ Cache::delete('test', 'wincache');
+ }
+
+/**
+ * testExpiry method
+ *
+ * @access public
+ * @return void
+ */
+ public function testExpiry() {
+ Cache::set(array('duration' => 1), 'wincache');
+
+ $result = Cache::read('test', 'wincache');
+ $this->assertFalse($result);
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data, 'wincache');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'wincache');
+ $this->assertFalse($result);
+
+ Cache::set(array('duration' => 1), 'wincache');
+
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('other_test', $data, 'wincache');
+ $this->assertTrue($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'wincache');
+ $this->assertFalse($result);
+
+ sleep(2);
+ $result = Cache::read('other_test', 'wincache');
+ $this->assertFalse($result);
+ }
+
+/**
+ * testDeleteCache method
+ *
+ * @access public
+ * @return void
+ */
+ public function testDeleteCache() {
+ $data = 'this is a test of the emergency broadcasting system';
+ $result = Cache::write('delete_test', $data, 'wincache');
+ $this->assertTrue($result);
+
+ $result = Cache::delete('delete_test', 'wincache');
+ $this->assertTrue($result);
+ }
+
+/**
+ * testDecrement method
+ *
+ * @access public
+ * @return void
+ */
+ public function testDecrement() {
+ $this->skipIf(
+ !function_exists('wincache_ucache_dec'),
+ 'No wincache_ucache_dec() function, cannot test decrement().'
+ );
+
+ $result = Cache::write('test_decrement', 5, 'wincache');
+ $this->assertTrue($result);
+
+ $result = Cache::decrement('test_decrement', 1, 'wincache');
+ $this->assertEqual(4, $result);
+
+ $result = Cache::read('test_decrement', 'wincache');
+ $this->assertEqual(4, $result);
+
+ $result = Cache::decrement('test_decrement', 2, 'wincache');
+ $this->assertEqual(2, $result);
+
+ $result = Cache::read('test_decrement', 'wincache');
+ $this->assertEqual(2, $result);
+
+ }
+
+/**
+ * testIncrement method
+ *
+ * @access public
+ * @return void
+ */
+ public function testIncrement() {
+ $this->skipIf(
+ !function_exists('wincache_ucache_inc'),
+ 'No wincache_inc() function, cannot test increment().'
+ );
+
+ $result = Cache::write('test_increment', 5, 'wincache');
+ $this->assertTrue($result);
+
+ $result = Cache::increment('test_increment', 1, 'wincache');
+ $this->assertEqual(6, $result);
+
+ $result = Cache::read('test_increment', 'wincache');
+ $this->assertEqual(6, $result);
+
+ $result = Cache::increment('test_increment', 2, 'wincache');
+ $this->assertEqual(8, $result);
+
+ $result = Cache::read('test_increment', 'wincache');
+ $this->assertEqual(8, $result);
+ }
+
+/**
+ * test the clearing of cache keys
+ *
+ * @return void
+ */
+ public function testClear() {
+ Cache::write('some_value', 'value', 'wincache');
+
+ $result = Cache::clear(false, 'wincache');
+ $this->assertTrue($result);
+ $this->assertFalse(Cache::read('some_value', 'wincache'));
+ }
+}

0 comments on commit 9e4c367

Please sign in to comment.