[Cache] fix optimizing Psr6Cache for AdapterInterface pools

This commit is contained in:
Nicolas Grekas 2018-11-16 21:57:33 +01:00
parent 236565c87e
commit b8100a9df0

View File

@ -15,7 +15,7 @@ use Psr\Cache\CacheException as Psr6CacheException;
use Psr\Cache\CacheItemPoolInterface;
use Psr\SimpleCache\CacheException as SimpleCacheException;
use Psr\SimpleCache\CacheInterface;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Exception\InvalidArgumentException;
use Symfony\Component\Cache\PruneableInterface;
@ -30,27 +30,36 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa
use ProxyTrait;
private $createCacheItem;
private $cacheItemPrototype;
public function __construct(CacheItemPoolInterface $pool)
{
$this->pool = $pool;
if ($pool instanceof AbstractAdapter) {
$this->createCacheItem = \Closure::bind(
function ($key, $value, $allowInt = false) {
if ($allowInt && \is_int($key)) {
$key = (string) $key;
} else {
CacheItem::validateKey($key);
}
$f = $this->createCacheItem;
return $f($key, $value, false);
},
$pool,
AbstractAdapter::class
);
if (!$pool instanceof AdapterInterface) {
return;
}
$cacheItemPrototype = &$this->cacheItemPrototype;
$createCacheItem = \Closure::bind(
function ($key, $value, $allowInt = false) use (&$cacheItemPrototype) {
$item = clone $cacheItemPrototype;
$item->key = $allowInt && \is_int($key) ? (string) $key : CacheItem::validateKey($key);
$item->value = $value;
$item->isHit = false;
return $item;
},
null,
CacheItem::class
);
$this->createCacheItem = function ($key, $value, $allowInt = false) use ($createCacheItem) {
if (null === $this->cacheItemPrototype) {
$this->get($allowInt && \is_int($key) ? (string) $key : $key);
}
$this->createCacheItem = $createCacheItem;
return $createCacheItem($key, $value, $allowInt);
};
}
/**
@ -65,6 +74,10 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa
} catch (Psr6CacheException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
if (null === $this->cacheItemPrototype) {
$this->cacheItemPrototype = clone $item;
$this->cacheItemPrototype->set(null);
}
return $item->isHit() ? $item->get() : $default;
}