Commit 1a7a15a3 by Alexander Makarov

Implemented mset, madd for cache. Added tests.

parent 6a4ed5a1
...@@ -72,6 +72,17 @@ class ApcCache extends Cache ...@@ -72,6 +72,17 @@ class ApcCache extends Cache
} }
/** /**
* Stores multiple key-value pairs in cache.
* @param array $data array where key corresponds to cache key while value
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys
*/
protected function setValues($data, $expire)
{
return array_keys(apc_store($data, null, $expire));
}
/**
* Stores a value identified by a key into cache if the cache does not contain this key. * Stores a value identified by a key into cache if the cache does not contain this key.
* This is the implementation of the method declared in the parent class. * This is the implementation of the method declared in the parent class.
* @param string $key the key identifying the value to be cached * @param string $key the key identifying the value to be cached
...@@ -85,6 +96,17 @@ class ApcCache extends Cache ...@@ -85,6 +96,17 @@ class ApcCache extends Cache
} }
/** /**
* Adds multiple key-value pairs to cache.
* @param array $data array where key corresponds to cache key while value is the value stored
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys
*/
protected function addValues($data, $expire)
{
return array_keys(apc_add($data, null, $expire));
}
/**
* Deletes a value with the specified key from cache * Deletes a value with the specified key from cache
* This is the implementation of the method declared in the parent class. * This is the implementation of the method declared in the parent class.
* @param string $key the key of the value to be deleted * @param string $key the key of the value to be deleted
......
...@@ -220,14 +220,62 @@ abstract class Cache extends Component implements \ArrayAccess ...@@ -220,14 +220,62 @@ abstract class Cache extends Component implements \ArrayAccess
* If the cache already contains such a key, the existing value and * If the cache already contains such a key, the existing value and
* expiration time will be replaced with the new ones, respectively. * expiration time will be replaced with the new ones, respectively.
* *
* @param array $items the items to be cached, as key-value pairs. Each key can be a simple string or * @param array $items the items to be cached, as key-value pairs.
* a complex data structure consisting of factors representing the key. * @param integer $expire default number of seconds in which the cached values will expire. 0 means never expire.
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire. * @param Dependency $dependency dependency of the cached items. If the dependency changes,
* the corresponding values in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is false.
* @return boolean whether the items are successfully stored into cache * @return boolean whether the items are successfully stored into cache
*/ */
public function mset($items, $expire = 0) public function mset($items, $expire = 0, $dependency = null)
{ {
return false; if ($dependency !== null && $this->serializer !== false) {
$dependency->evaluateDependency($this);
}
$data = [];
foreach ($items as $key => $value) {
$itemKey = $this->buildKey($key);
if ($this->serializer === null) {
$itemValue = serialize([$value, $dependency]);
} elseif ($this->serializer !== false) {
$itemValue = call_user_func($this->serializer[0], [$value, $dependency]);
}
$data[$itemKey] = $itemValue;
}
return $this->setValues($data, $expire);
}
/**
* Stores multiple items in cache. Each item contains a value identified by a key.
* If the cache already contains such a key, the existing value and expiration time will be preserved.
*
* @param array $items the items to be cached, as key-value pairs.
* @param integer $expire default number of seconds in which the cached values will expire. 0 means never expire.
* @param Dependency $dependency dependency of the cached items. If the dependency changes,
* the corresponding values in the cache will be invalidated when it is fetched via [[get()]].
* This parameter is ignored if [[serializer]] is false.
* @return boolean whether the items are successfully stored into cache
*/
public function madd($items, $expire = 0, $dependency = null)
{
if ($dependency !== null && $this->serializer !== false) {
$dependency->evaluateDependency($this);
}
$data = [];
foreach ($items as $key => $value) {
$itemKey = $this->buildKey($key);
if ($this->serializer === null) {
$itemValue = serialize([$value, $dependency]);
} elseif ($this->serializer !== false) {
$itemValue = call_user_func($this->serializer[0], [$value, $dependency]);
}
$data[$itemKey] = $itemValue;
}
return $this->addValues($data, $expire);
} }
/** /**
...@@ -342,6 +390,46 @@ abstract class Cache extends Component implements \ArrayAccess ...@@ -342,6 +390,46 @@ abstract class Cache extends Component implements \ArrayAccess
} }
/** /**
* Stores multiple key-value pairs in cache.
* The default implementation calls [[setValue()]] multiple times store values one by one. If the underlying cache
* storage supports multiset, this method should be overridden to exploit that feature.
* @param array $data array where key corresponds to cache key while value is the value stored
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys
*/
protected function setValues($data, $expire)
{
$failedKeys = [];
foreach ($data as $key => $value)
{
if ($this->setValue($key, $value, $expire) === false) {
$failedKeys[] = $key;
}
}
return $failedKeys;
}
/**
* Adds multiple key-value pairs to cache.
* The default implementation calls [[addValue()]] multiple times add values one by one. If the underlying cache
* storage supports multiadd, this method should be overridden to exploit that feature.
* @param array $data array where key corresponds to cache key while value is the value stored
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys
*/
protected function addValues($data, $expire)
{
$failedKeys = [];
foreach ($data as $key => $value)
{
if ($this->addValue($key, $value, $expire) === false) {
$failedKeys[] = $key;
}
}
return $failedKeys;
}
/**
* Returns whether there is a cache entry with a specified key. * Returns whether there is a cache entry with a specified key.
* This method is required by the interface ArrayAccess. * This method is required by the interface ArrayAccess.
* @param string $key a key identifying the cached value * @param string $key a key identifying the cached value
......
...@@ -202,6 +202,27 @@ class MemCache extends Cache ...@@ -202,6 +202,27 @@ class MemCache extends Cache
} }
/** /**
* Stores multiple key-value pairs in cache.
* @param array $data array where key corresponds to cache key while value is the value stored
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys. Always empty in case of using memcached.
*/
protected function setValues($data, $expire)
{
if ($this->useMemcached) {
if ($expire > 0) {
$expire += time();
} else {
$expire = 0;
}
$this->_cache->setMulti($data, $expire);
return [];
} else {
return parent::setValues($data, $expire);
}
}
/**
* Stores a value identified by a key into cache if the cache does not contain this key. * Stores a value identified by a key into cache if the cache does not contain this key.
* This is the implementation of the method declared in the parent class. * This is the implementation of the method declared in the parent class.
* *
......
...@@ -72,6 +72,17 @@ class WinCache extends Cache ...@@ -72,6 +72,17 @@ class WinCache extends Cache
} }
/** /**
* Stores multiple key-value pairs in cache.
* @param array $data array where key corresponds to cache key while value is the value stored
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys
*/
protected function setValues($data, $expire)
{
return wincache_ucache_set($data, null, $expire);
}
/**
* Stores a value identified by a key into cache if the cache does not contain this key. * Stores a value identified by a key into cache if the cache does not contain this key.
* This is the implementation of the method declared in the parent class. * This is the implementation of the method declared in the parent class.
* *
...@@ -86,6 +97,19 @@ class WinCache extends Cache ...@@ -86,6 +97,19 @@ class WinCache extends Cache
} }
/** /**
* Adds multiple key-value pairs to cache.
* The default implementation calls [[addValue()]] multiple times add values one by one. If the underlying cache
* storage supports multiadd, this method should be overridden to exploit that feature.
* @param array $data array where key corresponds to cache key while value is the value stored
* @param integer $expire the number of seconds in which the cached values will expire. 0 means never expire.
* @return array array of failed keys
*/
protected function addValues($data, $expire)
{
return wincache_ucache_add($data, null, $expire);
}
/**
* Deletes a value with the specified key from cache * Deletes a value with the specified key from cache
* This is the implementation of the method declared in the parent class. * This is the implementation of the method declared in the parent class.
* @param string $key the key of the value to be deleted * @param string $key the key of the value to be deleted
......
...@@ -93,15 +93,14 @@ abstract class CacheTestCase extends TestCase ...@@ -93,15 +93,14 @@ abstract class CacheTestCase extends TestCase
public function testMset() public function testMset()
{ {
$this->markTestIncomplete('Work in progress');
$cache = $this->getCacheInstance(); $cache = $this->getCacheInstance();
$cache->flush(); $cache->flush();
$this->assertTrue($cache->mset(['string_test' => 'string_test', $cache->mset([
'string_test' => 'string_test',
'number_test' => 42, 'number_test' => 42,
'array_test' => ['array_test' => 'array_test'], 'array_test' => ['array_test' => 'array_test'],
])); ]);
$this->assertEquals('string_test', $cache->get('string_test')); $this->assertEquals('string_test', $cache->get('string_test'));
...@@ -185,6 +184,21 @@ abstract class CacheTestCase extends TestCase ...@@ -185,6 +184,21 @@ abstract class CacheTestCase extends TestCase
$this->assertEquals(13, $cache->get('add_test')); $this->assertEquals(13, $cache->get('add_test'));
} }
public function testMadd()
{
$cache = $this->prepare();
$this->assertFalse($cache->get('add_test'));
$cache->madd([
'number_test' => 13,
'add_test' => 13,
]);
$this->assertEquals(42, $cache->get('number_test'));
$this->assertEquals(13, $cache->get('add_test'));
}
public function testDelete() public function testDelete()
{ {
$cache = $this->prepare(); $cache = $this->prepare();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment