2015-10-08 11:40:12 -07:00
< ? php
namespace Doctrine\Common\Cache ;
2018-11-23 12:29:20 +00:00
use function array_values ;
use function count ;
use function iterator_to_array ;
2015-10-08 11:40:12 -07:00
/**
* Cache provider that allows to easily chain multiple cache providers
*/
class ChainCache extends CacheProvider
{
2018-11-23 12:29:20 +00:00
/** @var CacheProvider[] */
private $cacheProviders = [];
2015-10-08 11:40:12 -07:00
/**
* @ param CacheProvider [] $cacheProviders
*/
2018-11-23 12:29:20 +00:00
public function __construct ( $cacheProviders = [])
2015-10-08 11:40:12 -07:00
{
2018-11-23 12:29:20 +00:00
$this -> cacheProviders = $cacheProviders instanceof \Traversable
? iterator_to_array ( $cacheProviders , false )
: array_values ( $cacheProviders );
2015-10-08 11:40:12 -07:00
}
/**
* { @ inheritDoc }
*/
public function setNamespace ( $namespace )
{
parent :: setNamespace ( $namespace );
foreach ( $this -> cacheProviders as $cacheProvider ) {
$cacheProvider -> setNamespace ( $namespace );
}
}
/**
* { @ inheritDoc }
*/
protected function doFetch ( $id )
{
foreach ( $this -> cacheProviders as $key => $cacheProvider ) {
if ( $cacheProvider -> doContains ( $id )) {
$value = $cacheProvider -> doFetch ( $id );
// We populate all the previous cache layers (that are assumed to be faster)
2018-11-23 12:29:20 +00:00
for ( $subKey = $key - 1 ; $subKey >= 0 ; $subKey -- ) {
2015-10-08 11:40:12 -07:00
$this -> cacheProviders [ $subKey ] -> doSave ( $id , $value );
}
return $value ;
}
}
return false ;
}
2018-11-23 12:29:20 +00:00
/**
* { @ inheritdoc }
*/
protected function doFetchMultiple ( array $keys )
{
/** @var CacheProvider[] $traversedProviders */
$traversedProviders = [];
$keysCount = count ( $keys );
$fetchedValues = [];
foreach ( $this -> cacheProviders as $key => $cacheProvider ) {
$fetchedValues = $cacheProvider -> doFetchMultiple ( $keys );
// We populate all the previous cache layers (that are assumed to be faster)
if ( count ( $fetchedValues ) === $keysCount ) {
foreach ( $traversedProviders as $previousCacheProvider ) {
$previousCacheProvider -> doSaveMultiple ( $fetchedValues );
}
return $fetchedValues ;
}
$traversedProviders [] = $cacheProvider ;
}
return $fetchedValues ;
}
2015-10-08 11:40:12 -07:00
/**
* { @ inheritDoc }
*/
protected function doContains ( $id )
{
foreach ( $this -> cacheProviders as $cacheProvider ) {
if ( $cacheProvider -> doContains ( $id )) {
return true ;
}
}
return false ;
}
/**
* { @ inheritDoc }
*/
protected function doSave ( $id , $data , $lifeTime = 0 )
{
$stored = true ;
foreach ( $this -> cacheProviders as $cacheProvider ) {
$stored = $cacheProvider -> doSave ( $id , $data , $lifeTime ) && $stored ;
}
return $stored ;
}
2018-11-23 12:29:20 +00:00
/**
* { @ inheritdoc }
*/
protected function doSaveMultiple ( array $keysAndValues , $lifetime = 0 )
{
$stored = true ;
foreach ( $this -> cacheProviders as $cacheProvider ) {
$stored = $cacheProvider -> doSaveMultiple ( $keysAndValues , $lifetime ) && $stored ;
}
return $stored ;
}
2015-10-08 11:40:12 -07:00
/**
* { @ inheritDoc }
*/
protected function doDelete ( $id )
{
$deleted = true ;
foreach ( $this -> cacheProviders as $cacheProvider ) {
$deleted = $cacheProvider -> doDelete ( $id ) && $deleted ;
}
return $deleted ;
}
2018-11-23 12:29:20 +00:00
/**
* { @ inheritdoc }
*/
protected function doDeleteMultiple ( array $keys )
{
$deleted = true ;
foreach ( $this -> cacheProviders as $cacheProvider ) {
$deleted = $cacheProvider -> doDeleteMultiple ( $keys ) && $deleted ;
}
return $deleted ;
}
2015-10-08 11:40:12 -07:00
/**
* { @ inheritDoc }
*/
protected function doFlush ()
{
$flushed = true ;
foreach ( $this -> cacheProviders as $cacheProvider ) {
$flushed = $cacheProvider -> doFlush () && $flushed ;
}
return $flushed ;
}
/**
* { @ inheritDoc }
*/
protected function doGetStats ()
{
// We return all the stats from all adapters
2018-11-23 12:29:20 +00:00
$stats = [];
2015-10-08 11:40:12 -07:00
foreach ( $this -> cacheProviders as $cacheProvider ) {
$stats [] = $cacheProvider -> doGetStats ();
}
return $stats ;
}
}