Skip to content

Commit

Permalink
feature #20851 [Cache] Add CacheItem::getPreviousTags() (nicolas-grekas)
Browse files Browse the repository at this point in the history
This PR was merged into the 3.3-dev branch.

Discussion
----------

[Cache] Add CacheItem::getPreviousTags()

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

As discussed in #19728

Commits
-------

da35466 [Cache] Add CacheItem::getPreviousTags()
  • Loading branch information
fabpot committed Mar 22, 2017
2 parents 9761b44 + da35466 commit 59dd752
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 11 deletions.
39 changes: 29 additions & 10 deletions src/Symfony/Component/Cache/Adapter/TagAwareAdapter.php
Expand Up @@ -25,6 +25,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface
private $itemsAdapter;
private $deferred = array();
private $createCacheItem;
private $setCacheItemTags;
private $getTagsByKey;
private $invalidateTags;
private $tagsAdapter;
Expand All @@ -38,7 +39,6 @@ function ($key, $value, CacheItem $protoItem) {
$item = new CacheItem();
$item->key = $key;
$item->value = $value;
$item->isHit = false;
$item->defaultLifetime = $protoItem->defaultLifetime;
$item->expiry = $protoItem->expiry;
$item->innerItem = $protoItem->innerItem;
Expand All @@ -49,6 +49,26 @@ function ($key, $value, CacheItem $protoItem) {
null,
CacheItem::class
);
$this->setCacheItemTags = \Closure::bind(
function (CacheItem $item, $key, array &$itemTags) {
if (!$item->isHit) {
return $item;
}
if (isset($itemTags[$key])) {
foreach ($itemTags[$key] as $tag => $version) {
$item->prevTags[$tag] = $tag;
}
unset($itemTags[$key]);
} else {
$item->value = null;
$item->isHit = false;
}

return $item;
},
null,
CacheItem::class
);
$this->getTagsByKey = \Closure::bind(
function ($deferred) {
$tagsByKey = array();
Expand Down Expand Up @@ -256,12 +276,12 @@ public function __destruct()

private function generateItems($items, array $tagKeys)
{
$bufferedItems = $itemTags = $invalidKeys = array();
$f = $this->createCacheItem;
$bufferedItems = $itemTags = array();
$f = $this->setCacheItemTags;

foreach ($items as $key => $item) {
if (!$tagKeys) {
yield $key => isset($invalidKeys[self::TAGS_PREFIX.$key]) ? $f($key, null, $item) : $item;
yield $key => $f($item, self::TAGS_PREFIX.$key, $itemTags);
continue;
}
if (!isset($tagKeys[$key])) {
Expand All @@ -270,24 +290,23 @@ private function generateItems($items, array $tagKeys)
}

unset($tagKeys[$key]);
if ($tags = $item->get()) {
$itemTags[$key] = $tags;
}
$itemTags[$key] = $item->get() ?: array();

if (!$tagKeys) {
$tagVersions = $this->getTagVersions($itemTags);

foreach ($itemTags as $key => $tags) {
foreach ($tags as $tag => $version) {
if ($tagVersions[$tag] !== $version) {
$invalidKeys[$key] = true;
unset($itemTags[$key]);
continue 2;
}
}
}
$itemTags = $tagVersions = $tagKeys = null;
$tagVersions = $tagKeys = null;

foreach ($bufferedItems as $key => $item) {
yield $key => isset($invalidKeys[self::TAGS_PREFIX.$key]) ? $f($key, null, $item) : $item;
yield $key => $f($item, self::TAGS_PREFIX.$key, $itemTags);
}
$bufferedItems = null;
}
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Cache/CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@ CHANGELOG
3.3.0
-----

* [EXPERIMENTAL] added CacheItem::getPreviousTags() to get bound tags coming from the pool storage if any
* added PSR-16 "Simple Cache" implementations for all existing PSR-6 adapters
* added Psr6Cache and SimpleCacheAdapter for bidirectional interoperability between PSR-6 and PSR-16
* added MemcachedAdapter (PSR-6) and MemcachedCache (PSR-16)
Expand Down
15 changes: 14 additions & 1 deletion src/Symfony/Component/Cache/CacheItem.php
Expand Up @@ -22,10 +22,11 @@ final class CacheItem implements CacheItemInterface
{
protected $key;
protected $value;
protected $isHit;
protected $isHit = false;
protected $expiry;
protected $defaultLifetime;
protected $tags = array();
protected $prevTags = array();
protected $innerItem;
protected $poolHash;

Expand Down Expand Up @@ -130,6 +131,18 @@ public function tag($tags)
return $this;
}

/**
* Returns the list of tags bound to the value coming from the pool storage if any.
*
* @return array
*
* @experimental in version 3.3
*/
public function getPreviousTags()
{
return $this->prevTags;
}

/**
* Validates a cache key according to PSR-6.
*
Expand Down
11 changes: 11 additions & 0 deletions src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php
Expand Up @@ -114,4 +114,15 @@ public function testTagItemExpiry()

$this->assertFalse($pool->getItem('foo')->isHit());
}

public function testGetPreviousTags()
{
$pool = $this->createCachePool();

$i = $pool->getItem('k');
$pool->save($i->tag('foo'));

$i = $pool->getItem('k');
$this->assertSame(array('foo' => 'foo'), $i->getPreviousTags());
}
}

0 comments on commit 59dd752

Please sign in to comment.