Skip to content

Commit 40ea9fd

Browse files
[Cache] Implement PSR-16 SimpleCache
1 parent 13265ae commit 40ea9fd

File tree

9 files changed

+303
-5
lines changed

9 files changed

+303
-5
lines changed

composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"twig/twig": "~1.28|~2.0",
2222
"psr/cache": "~1.0",
2323
"psr/log": "~1.0",
24+
"psr/simple-cache": "^0.2",
2425
"symfony/polyfill-intl-icu": "~1.0",
2526
"symfony/polyfill-mbstring": "~1.0",
2627
"symfony/polyfill-php56": "~1.0",
@@ -97,7 +98,8 @@
9798
"phpdocumentor/type-resolver": "<0.2.0"
9899
},
99100
"provide": {
100-
"psr/cache-implementation": "1.0"
101+
"psr/cache-implementation": "1.0",
102+
"psr/simple-cache-implementation": "1.0"
101103
},
102104
"autoload": {
103105
"psr-4": {

src/Symfony/Component/Cache/Adapter/AbstractAdapter.php

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515
use Psr\Log\LoggerAwareInterface;
1616
use Psr\Log\LoggerAwareTrait;
1717
use Psr\Log\LoggerInterface;
18+
use Psr\SimpleCache\CounterInterface;
1819
use Symfony\Component\Cache\CacheItem;
1920
use Symfony\Component\Cache\Exception\InvalidArgumentException;
2021

2122
/**
2223
* @author Nicolas Grekas <p@tchwork.com>
2324
*/
24-
abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface
25+
abstract class AbstractAdapter implements AdapterInterface, CounterInterface, LoggerAwareInterface
2526
{
2627
use LoggerAwareTrait;
2728

@@ -372,6 +373,36 @@ public function commit()
372373
return $ok;
373374
}
374375

376+
/**
377+
* {@inheritdoc}
378+
*/
379+
public function increment($key, $step = 1)
380+
{
381+
if (!is_numeric($step)) {
382+
return false;
383+
}
384+
$id = $this->getId($key);
385+
386+
try {
387+
if (false === $result = $this->doIncrement($id, (int) $step)) {
388+
CacheItem::log($this->logger, 'Failed to increment key "{key}"', array('key' => $key));
389+
}
390+
} catch (\Exception $e) {
391+
CacheItem::log($this->logger, 'Failed to increment key "{key}"', array('key' => $key, 'exception' => $e));
392+
$result = false;
393+
}
394+
395+
return $result;
396+
}
397+
398+
/**
399+
* {@inheritdoc}
400+
*/
401+
public function decrement($key, $step = 1)
402+
{
403+
return is_numeric($step) ? $this->increment($key, -$step) : false;
404+
}
405+
375406
public function __destruct()
376407
{
377408
if ($this->deferred) {
@@ -406,6 +437,29 @@ protected static function unserialize($value)
406437
}
407438
}
408439

440+
/**
441+
* Increments a value in the cache by the given step value and returns the new value.
442+
*
443+
* If the key does not exist, it is initialized to the value of $step.
444+
*
445+
* @param string $key The cache item key
446+
* @param int $step The value to increment by
447+
*
448+
* @return int|bool The new value on success and false on failure
449+
*/
450+
protected function doIncrement($id, $step)
451+
{
452+
foreach ($this->doFetch(array($id)) as $value) {
453+
if (is_numeric($value)) {
454+
$step += $value;
455+
}
456+
}
457+
458+
$e = $this->doSave(array($id => $step), 0);
459+
460+
return true === $e || array() === $e ? $step : false;
461+
}
462+
409463
private function getId($key)
410464
{
411465
CacheItem::validateKey($key);

src/Symfony/Component/Cache/Adapter/ApcuAdapter.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,12 @@ protected function doSave(array $values, $lifetime)
104104

105105
throw $e;
106106
}
107+
108+
/**
109+
* {@inheritdoc}
110+
*/
111+
protected function doIncrement($id, $step)
112+
{
113+
return apcu_inc($id, $step);
114+
}
107115
}

src/Symfony/Component/Cache/Adapter/ArrayAdapter.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
use Psr\Cache\CacheItemInterface;
1515
use Psr\Log\LoggerAwareInterface;
1616
use Psr\Log\LoggerAwareTrait;
17+
use Psr\SimpleCache\CounterInterface;
1718
use Symfony\Component\Cache\CacheItem;
1819

1920
/**
2021
* @author Nicolas Grekas <p@tchwork.com>
2122
*/
22-
class ArrayAdapter implements AdapterInterface, LoggerAwareInterface
23+
class ArrayAdapter implements AdapterInterface, CounterInterface, LoggerAwareInterface
2324
{
2425
use LoggerAwareTrait;
2526

@@ -197,6 +198,33 @@ public function commit()
197198
return true;
198199
}
199200

201+
/**
202+
* {@inheritdoc}
203+
*/
204+
public function increment($key, $step = 1)
205+
{
206+
if (!is_numeric($step)) {
207+
return false;
208+
}
209+
210+
if ($this->hasItem($key) && is_numeric($this->values[$key])) {
211+
$this->values[$key] = $value + (int) $step;
212+
} else {
213+
$this->values[$key] = (int) $step;
214+
$this->expiries[$key] = PHP_INT_MAX;
215+
}
216+
217+
return $this->values[$key];
218+
}
219+
220+
/**
221+
* {@inheritdoc}
222+
*/
223+
public function decrement($key, $step = 1)
224+
{
225+
return is_numeric($step) ? $this->increment($key, -$step) : false;
226+
}
227+
200228
private function generateItems(array $keys, $now)
201229
{
202230
$f = $this->createCacheItem;

src/Symfony/Component/Cache/Adapter/FilesystemAdapterTrait.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,25 @@ protected function doDelete(array $ids)
7979
return $ok;
8080
}
8181

82+
/**
83+
* {@inheritdoc}
84+
*/
85+
protected function doIncrement($id, $step)
86+
{
87+
if (!$lock = @fopen($this->getFile($id, true), 'cb')) {
88+
return false;
89+
}
90+
if (!flock($lock, LOCK_EX)) {
91+
return false;
92+
}
93+
$result = parent::doIncrement($id, $step);
94+
95+
flock($lock, LOCK_UN);
96+
fclose($lock);
97+
98+
return $result;
99+
}
100+
82101
private function write($file, $data, $expiresAt = null)
83102
{
84103
if (false === @file_put_contents($this->tmp, $data)) {

src/Symfony/Component/Cache/Adapter/PdoAdapter.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,20 @@ protected function doSave(array $values, $lifetime)
335335
return $failed;
336336
}
337337

338+
/**
339+
* {@inheritdoc}
340+
*/
341+
protected function doIncrement($id, $step)
342+
{
343+
$conn = $this->getConnection();
344+
if (!$conn->beginTransaction()) {
345+
return false;
346+
}
347+
$result = parent::doIncrement($id, $step);
348+
349+
return $conn->commit() ? $result : false;
350+
}
351+
338352
/**
339353
* @return \PDO|Connection
340354
*/

src/Symfony/Component/Cache/Adapter/RedisAdapter.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,14 @@ protected function doSave(array $values, $lifetime)
266266
return $failed;
267267
}
268268

269+
/**
270+
* {@inheritdoc}
271+
*/
272+
protected function doIncrement($id, $step)
273+
{
274+
return $this->redis->incrBy($id, $step);
275+
}
276+
269277
private function execute($command, $id, array $args, $redis = null)
270278
{
271279
array_unshift($args, $id);
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Cache\Adapter;
13+
14+
use Psr\Cache\CacheItemPoolInterface;
15+
use Psr\SimpleCache\CacheInterface;
16+
use Psr\SimpleCache\CounterInterface;
17+
18+
/**
19+
* @author Nicolas Grekas <p@tchwork.com>
20+
*/
21+
class SimpleCacheAdapter implements CacheInterface, CounterInterface
22+
{
23+
private $pool;
24+
private $createCacheItem;
25+
26+
public function __construct(CacheItemPoolInterface $pool)
27+
{
28+
$this->pool = $pool;
29+
30+
if ($pool instanceof AdapterInterface) {
31+
$this->createCacheItem = \Closure::bind(
32+
function ($key, $value) {
33+
CacheItem::validateKey($key);
34+
$item = new CacheItem();
35+
$item->key = $key;
36+
$item->value = $value;
37+
38+
return $item;
39+
},
40+
null,
41+
CacheItem::class
42+
);
43+
} else {
44+
$this->createCacheItem = function ($key, $value) {
45+
return $this->pool->getItem($key)->set($value);
46+
};
47+
}
48+
}
49+
50+
/**
51+
* {@inheritdoc}
52+
*/
53+
public function get($key, $default = null)
54+
{
55+
$item = $this->pool->getItem($key);
56+
57+
return $item->isHit() ? $item->get() : $default;
58+
}
59+
60+
/**
61+
* {@inheritdoc}
62+
*/
63+
public function set($key, $value, $ttl = null)
64+
{
65+
$f = $this->createCacheItem;
66+
$item = $f($key, $value);
67+
if (null !== $ttl) {
68+
$item->expiresAfter($ttl);
69+
}
70+
71+
return $this->pool->save($item);
72+
}
73+
74+
/**
75+
* {@inheritdoc}
76+
*/
77+
public function delete($key)
78+
{
79+
$this->pool->deleteItem($key);
80+
}
81+
82+
/**
83+
* {@inheritdoc}
84+
*/
85+
public function clear()
86+
{
87+
$this->pool->clear();
88+
}
89+
90+
/**
91+
* {@inheritdoc}
92+
*/
93+
public function getMultiple($keys)
94+
{
95+
foreach ($this->pool->getItems($keys) as $key => $item) {
96+
yield $key => $item->get();
97+
}
98+
}
99+
100+
/**
101+
* {@inheritdoc}
102+
*/
103+
public function setMultiple($items, $ttl = null)
104+
{
105+
$f = $this->createCacheItem;
106+
$ok = true;
107+
108+
foreach ($items as $key => $value) {
109+
$item = $f($key, $value);
110+
if (null !== $ttl) {
111+
$item->expiresAfter($ttl);
112+
}
113+
$ok = $this->pool->saveDeferred($item) && $ok;
114+
}
115+
116+
return $this->pool->commit() && $ok;
117+
}
118+
119+
/**
120+
* {@inheritdoc}
121+
*/
122+
public function deleteMultiple($keys)
123+
{
124+
$this->pool->deleteItems($keys);
125+
}
126+
127+
/**
128+
* {@inheritdoc}
129+
*/
130+
public function has($key)
131+
{
132+
return $this->pool->hasItem($key);
133+
}
134+
135+
/**
136+
* {@inheritdoc}
137+
*/
138+
public function increment($key, $step = 1)
139+
{
140+
if ($this->pool instanceof CounterInterface) {
141+
return $this->pool->increment($key, $step);
142+
}
143+
if (!is_numeric($step)) {
144+
return false;
145+
}
146+
147+
$item = $this->pool->getItem($key);
148+
if (is_numeric($value = $item->get())) {
149+
$step += $value;
150+
}
151+
$item->set($step);
152+
153+
return $this->pool->save($item) ? $step : false;
154+
}
155+
156+
/**
157+
* {@inheritdoc}
158+
*/
159+
public function decrement($key, $step = 1)
160+
{
161+
return is_numeric($step) ? $this->increment($key, -$step) : false;
162+
}
163+
}

0 commit comments

Comments
 (0)