8000 [Cache] Optimize caching of tags · symfony/symfony@68f309b · GitHub
[go: up one dir, main page]

Skip to content

Commit 68f309b

Browse files
sbelyshkinnicolas-grekas
authored andcommitted
[Cache] Optimize caching of tags
1 parent 6bc0882 commit 68f309b

File tree

2 files changed

+26
-24
lines changed

2 files changed

+26
-24
lines changed

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

+18-18
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ class TagAwareAdapter implements TagAwareAdapterInterface, TagAwareCacheInterfac
3939
use LoggerAwareTrait;
4040

4141
public const TAGS_PREFIX = "\0tags\0";
42-
private const MAX_NUMBER_OF_KNOWN_TAG_VERSIONS = 1000;
4342

4443
private array $deferred = [];
4544
private AdapterInterface $pool;
@@ -79,8 +78,7 @@ static function (array $items, array $itemTags) {
7978
);
8079
self::$setTagVersions ??= \Closure::bind(
8180
static function (array $items, array $tagVersions) {
82-
$now = null;
83-
foreach ($items as $key => $item) {
81+
foreach ($items as $item) {
8482
$item->newMetadata[CacheItem::METADATA_TAGS] = array_intersect_key($tagVersions, $item->newMetadata[CacheItem::METADATA_TAGS] ?? []);
8583
}
8684
},
@@ -343,14 +341,16 @@ public function __destruct()
343341
private function getTagVersions(array $tagsByKey, bool $persistTags): array
344342
{
345343
$tagVersions = [];
346-
$fetchTagVersions = false;
344+
$fetchTagVersions = $persistTags;
347345

348346
foreach ($tagsByKey as $tags) {
349347
$tagVersions += $tags;
350-
348+
if ($fetchTagVersions) {
349+
continue;
350+
}
351351
foreach ($tags as $tag => $version) {
352352
if ($tagVersions[$tag] !== $version) {
353-
unset($this->knownTagVersions[$tag]);
353+
$fetchTagVersions = true;
354354
}
355355
}
356356
}
@@ -364,14 +364,10 @@ private function getTagVersions(array $tagsByKey, bool $persistTags): array
364364
foreach ($tagVersions as $tag => $version) {
365365
$tags[$tag.static::TAGS_PREFIX] = $tag;
366366
$knownTagVersion = $this->knownTagVersions[$tag] ?? [0, null];
367-
if ($fetchTagVersions || $knownTagVersion[1] !== $version || $now - $knownTagVersion[0] >= $this->knownTagVersionsTtl) {
368-
// reuse previously fetched tag versions up to the ttl
367+
if ($fetchTagVersions || $now > $knownTagVersion[0] || $knownTagVersion[1] !== $version) {
368+
// reuse previously fetched tag versions until the expiration
369369
$fetchTagVersions = true;
370370
}
371-
unset($this->knownTagVersions[$tag]); // For LRU tracking
372-
if ([0, null] !== $knownTagVersion) {
373-
$this->knownTagVersions[$tag] = $knownTagVersion;
374-
}
375371
}
376372

377373
if (!$fetchTagVersions) {
@@ -380,20 +376,24 @@ private function getTagVersions(array $tagsByKey, bool $persistTags): array
380376

381377
$newTags = [];
382378
$newVersion = null;
379+
$expiration = $now + $this->knownTagVersionsTtl;
383380
foreach ($this->tags->getItems(array_keys($tags)) as $tag => $version) {
384-
if (!$version->isHit()) {
381+
unset($this->knownTagVersions[$tag = $tags[$tag]]); // update FIFO
382+
if (null !== $tagVersions[$tag] = $version->get()) {
383+
$this->knownTagVersions[$tag] = [$expiration, $tagVersions[$tag]];
384+
} elseif ($persistTags) {
385385
$newTags[$tag] = $version->set($newVersion ??= random_bytes(6));
386+
$tagVersions[$tag] = $newVersion;
387+
$this->knownTagVersions[$tag] = [$expiration, $newVersion];
386388
}
387-
$tagVersions[$tag = $tags[$tag]] = $version->get();
388-
$this->knownTagVersions[$tag] = [$now, $tagVersions[$tag]];
389389
}
390390

391-
if ($newTags && $persistTags) {
391+
if ($newTags) {
392392
(self::$saveTags)($this->tags, $newTags);
393393
}
394394

395-
if (\count($this->knownTagVersions) > $maxTags = max(self::MAX_NUMBER_OF_KNOWN_TAG_VERSIONS, \count($newTags) << 1)) {
396-
array_splice($this->knownTagVersions, 0, $maxTags >> 1);
395+
while ($now > ($this->knownTagVersions[$tag = array_key_first($this->knownTagVersions)][0] ?? \INF)) {
396+
unset($this->knownTagVersions[$tag]);
397397
}
398398

399399
return $tagVersions;

src/Symfony/Component/Cache/Tests/Adapter/TagAwareAdapterTest.php

+8-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Symfony\Component\Cache\Tests\Adapter;
1313

1414
use PHPUnit\Framework\MockObject\MockObject;
15-
use Psr\Cache\CacheItemInterface;
1615
use Psr\Cache\CacheItemPoolInterface;
1716
use Symfony\Component\Cache\Adapter\AdapterInterface;
1817
use Symfony\Component\Cache\Adapter\ArrayAdapter;
@@ -67,15 +66,18 @@ public function testKnownTagVersionsTtl()
6766

6867
$pool->save($item);
6968
$this->assertTrue($pool->getItem('foo')->isHit());
70-
$this->assertTrue($pool->getItem('foo')->isHit());
7169

72-
sleep(20);
70+
$tagsPool->deleteItem('baz'.TagAwareAdapter::TAGS_PREFIX); // tag invalidation
7371

74-
$this->assertTrue($pool->getItem('foo')->isHit());
72+
$this->assertTrue($pool->getItem('foo')->isHit()); // known tag version is used
7573

76-
sleep(5);
74+
sleep(10);
7775

78-
$this->assertTrue($pool->getItem('foo')->isHit());
76+
$this->assertTrue($pool->getItem('foo')->isHit()); // known tag version is still used
77+
78+
sleep(1);
79+
80+
$this->assertFalse($pool->getItem('foo')->isHit()); // known tag version has expired
7981
}
8082

8183
public function testInvalidateTagsWithArrayAdapter()

0 commit comments

Comments
 (0)
0