8000 [Cache] Allow and use generators in AbstractAdapter · symfony/symfony@5cd0317 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5cd0317

Browse files
[Cache] Allow and use generators in AbstractAdapter
1 parent cc84be9 commit 5cd0317

File tree

8 files changed

+77
-59
lines changed

8 files changed

+77
-59
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
"symfony/yaml": "self.version"
7777
},
7878
"require-dev": {
79-
"cache/integration-tests": "^0.6",
79+
"cache/integration-tests": "dev-master",
8080
"doctrine/cache": "~1.6",
8181
"doctrine/data-fixtures": "1.0.*",
8282
"doctrine/dbal": "~2.4",

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

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ function ($deferred, $namespace) {
6464
*
6565
* @param array $ids The cache identifiers to fetch.
6666
*
67-
* @return array The corresponding values found in the cache.
67+
* @return array|\Traversable The corresponding values found in the cache.
6868
*/
6969
abstract protected function doFetch(array $ids);
7070

@@ -80,9 +80,11 @@ abstract protected function doHave($id);
8080
/**
8181
* Deletes all items in the pool.
8282
*
83+
* @param string The prefix used for all identifiers managed by this pool.
84+
*
8385
* @return bool True if the pool was successfully cleared, false otherwise.
8486
*/
85-
abstract protected function doClear();
87+
abstract protected function doClear($namespace);
8688

8789
/**
8890
* Removes multiple items from the pool.
@@ -108,14 +110,10 @@ abstract protected function doSave(array $values, $lifetime);
108110
*/
109111
public function getItem($key)
110112
{
111-
$id = $this->getId($key);
112-
113113
if ($this->deferred) {
114114
$this->commit();
115115
}
116-
if (isset($this->deferred[$key])) {
117-
return $this->deferred[$key];
118-
}
116+
$id = $this->getId($key);
119117

120118
$f = $this->createCacheItem;
121119
$isHit = false;
@@ -136,40 +134,33 @@ public function getItems(array $keys = array())
136134
if ($this->deferred) {
137135
$this->commit();
138136
}
139-
$f = $this->createCacheItem;
140137
$ids = array();
141-
$items = array();
142138

143139
foreach ($keys as $key) {
144-
$id = $this->getId($key);
145-
146-
if (isset($this->deferred[$key])) {
147-
$items[$key] = $this->deferred[$key];
148-
} else {
149-
$ids[$key] = $id;
150-
}
140+
$ids[$key] = $this->getId($key);
151141
}
152142

153-
$values = $this->doFetch($ids);
154-
155-
foreach ($ids as $key => $id) {
156-
$isHit = isset($values[$id]);
157-
$items[$key] = $f($key, $isHit ? $values[$id] : null, $isHit);
158-
}
159-
160-
return $items;
143+
return $this->generateItems($ids);
161144
}
162145

163146
/**
164147
* {@inheritdoc}
165148
*/
166149
public function hasItem($key)
167150
{
168-
if ($this->deferred) {
169-
$this->commit();
151+
$id = $this->getId($key);
152+
153+
if (isset($this->deferred[$key])) {
154+
$item = (array) $this->deferred[$key];
155+
$ok = $this->doSave(array($item[CacheItem::CAST_PREFIX.'key'] => $item[CacheItem::CAST_PREFIX.'value']), $item[CacheItem::CAST_PREFIX.'lifetime']);
156+
unset($this->deferred[$key]);
157+
158+
if (true === $ok || array() === $ok) {
159+
return true;
160+
}
170161
}
171162

172-
return $this->doHave($this->getId($key));
163+
return $this->doHave($id);
173164
}
174165

175166
/**
@@ -179,7 +170,7 @@ public function clear()
179170
{
180171
$this->deferred = array();
181172

182-
return $this->doClear();
173+
return $this->doClear($this->namespace);
183174
}
184175

185176
/**
@@ -198,7 +189,7 @@ public function deleteItems(array $keys)
198189
$ids = array();
199190

200191
foreach ($keys as $key) {
201-
$ids[] = $this->getId($key);
192+
$ids[$key] = $this->getId($key);
202193
unset($this->deferred[$key]);
203194
}
204195

@@ -214,10 +205,12 @@ public function save(CacheItemInterface $item)
214205
return false;
215206
}
216207
$key = $item->getKey();
208+
if ($this->deferred) {
209+
$this->commit();
210+
}
217211
$this->deferred[$key] = $item;
218-
$this->commit();
219212

220-
return !isset($this->deferred[$key]);
213+
return $this->commit();
221214
}
222215

223216
/**
@@ -230,10 +223,7 @@ public function saveDeferred(CacheItemInterface $item)
230223
}
231224
try {
232225
$item = clone $item;
233-
} catch (\Error $e) {
234226
} catch (\Exception $e) {
235-
}
236-
if (isset($e)) {
237227
@trigger_error($e->__toString());
238228

239229
return false;
@@ -250,7 +240,6 @@ public function commit()
250240
{
251241
$f = $this->mergeByLifetime;
252242
$ko = array();
253-
$namespaceLen = strlen($this->namespace);
254243

255244
foreach ($f($this->deferred, $this->namespace) as $lifetime => $values) {
256245
if (true === $ok = $this->doSave($values, $lifetime)) {
@@ -259,13 +248,22 @@ public function commit()
259248
if (false === $ok) {
260249
$ok = array_keys($values);
261250
}
262-
foreach ($ok as $failedId) {
263-
$key = substr($failedId, $namespaceLen);
264-
$ko[$key] = $this->deferred[$key];
251+
foreach ($ok as $id) {
252+
$ko[$lifetime][] = array($id => $values[$id]);
253+
}
254+
}
255+
256+
$this->deferred = array();
257+
$ok = true;
258+
259+
// When bulk-save failed, retry each item individually
260+
foreach ($ko as $lifetime => $values) {
261+
foreach ($values as $v) {
262+
$ok = in_array($this->doSave($v, $lifetime), array(true, array()), true) && $ok;
265263
}
266264
}
267265

268-
return !$this->deferred = $ko;
266+
return $ok;
269267
}
270268

271269
public function __destruct()
@@ -289,4 +287,19 @@ private function getId($key)
289287

290288
return $this->namespace.$key;
291289
}
290+
291+
private function generateItems($ids)
292+
{
293+
$f = $this->createCacheItem;
294+
$keys = array_flip($ids);
295+
296+
foreach ($this->doFetch($ids) as $id => $value) {
297+
yield $keys[$id] => $f($keys[$id], $value, true);
298+
unset($keys[$id]);
299+
}
300+
301+
foreach ($keys as $key) {
302+
yield $key => $f($key, null, false);
303+
}
304+
}
292305
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ protected function doHave($id)
4848
/**
4949
* {@inheritdoc}
5050
*/
51-
protected function doClear()
51+
protected function doClear($namespace)
5252
{
5353
return apcu_clear_cache();
5454
}

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,10 @@ public function save(CacheItemInterface $item)
118118
if (!$item instanceof CacheItem) {
119119
return false;
120120
}
121-
static $prefix = "\0Symfony\Component\Cache\CacheItem\0";
122121
$item = (array) $item;
123-
$key = $item[$prefix.'key'];
124-
$value = $item[$prefix.'value'];
125-
$lifetime = $item[$prefix.'lifetime'];
122+
$key = $item[CacheItem::CAST_PREFIX.'key'];
123+
$value = $item[CacheItem::CAST_PREFIX.'value'];
124+
$lifetime = $item[CacheItem::CAST_PREFIX.'lifetime'];
126125

127126
if (0 > $lifetime) {
128127
return true;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ protected function doHave($id)
4545
/**
4646
* {@inheritdoc}
4747
*/
48-
protected function doClear()
48+
protected function doClear($namespace)
4949
{
5050
return $this->provider->flushAll();
5151
}

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

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,7 @@ public function getItem($key)
5656
*/
5757
public function getItems(array $keys = array())
5858
{
59-
$f = $this->createCacheItem;
60-
$items = array();
61-
62-
foreach ($this->pool->getItems($keys) as $key => $item) {
63-
$items[$key] = $f($key, $item->get(), $item->isHit());
64-
}
65-
66-
return $items;
59+
return $this->generateItems($this->pool->getItems($keys));
6760
}
6861

6962
/**
@@ -127,12 +120,20 @@ private function doSave(CacheItemInterface $item, $method)
127120
if (!$item instanceof CacheItem) {
128121
return false;
129122
}
130-
static $prefix = "\0Symfony\Component\Cache\CacheItem\0";
131123
$item = (array) $item;
132-
$poolItem = $this->pool->getItem($item[$prefix.'key']);
133-
$poolItem->set($item[$prefix.'value']);
134-
$poolItem->expiresAfter($item[$prefix.'lifetime']);
124+
$poolItem = $this->pool->getItem($item[CacheItem::CAST_PREFIX.'key']);
125+
$poolItem->set($item[CacheItem::CAST_PREFIX.'value']);
126+
$poolItem->expiresAfter($item[CacheItem::CAST_PREFIX.'lifetime']);
135127

136128
return $this->pool->$method($poolItem);
137129
}
130+
131+
private function generateItems($items)
132+
{
133+
$f = $this->createCacheItem;
134+
135+
foreach ($items as $key => $item) {
136+
yield $key => $f($key, $item->get(), $item->isHit());
137+
}
138+
}
138139
}

src/Symfony/Component/Cache/CacheItem.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
*/
2020
final class CacheItem implements CacheItemInterface
2121
{
22+
/**
23+
* @internal
24+
*/
25+
const CAST_PREFIX = "\0Symfony\Component\Cache\CacheItem\0";
26+
2227
private $key;
2328
private $value;
2429
private $isHit;

src/Symfony/Component/Cache/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"psr/cache": "~1.0"
2424
},
2525
"require-dev": {
26-
"cache/integration-tests": "^0.6",
26+
"cache/integration-tests": "dev-master",
2727
"doctrine/cache": "~1.6"
2828
},
2929
"autoload": {

0 commit comments

Comments
 (0)
0