Adding Wincache support. Wincache is a fast shared memory

cache that performs very well on windows platforms.
This commit is contained in:
Mark Story 2011-06-21 16:01:47 -07:00
parent 97e51f1d94
commit 9e4c367688
2 changed files with 322 additions and 0 deletions

View file

@ -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 file

@ -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'));
}
}