Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 78fff0c

Browse files
committed
[Cache] Optimize fetching of tags
1 parent 3c07197 commit 78fff0c

File tree

2 files changed

+50
-24
lines changed

2 files changed

+50
-24
lines changed

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

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ static function (array $items, array $itemTags) {
7979
);
8080
self::$setTagVersions ??= \Closure::bind(
8181
static function (array $items, array $tagVersions) {
82-
$now = null;
83-
foreach ($items as $key => $item) {
82+
foreach ($items as $item) {
8483
$item->newMetadata[CacheItem::METADATA_TAGS] = array_intersect_key($tagVersions, $item->newMetadata[CacheItem::METADATA_TAGS] ?? []);
8584
}
8685
},
@@ -347,10 +346,9 @@ private function getTagVersions(array $tagsByKey, bool $persistTags): array
347346

348347
foreach ($tagsByKey as $tags) {
349348
$tagVersions += $tags;
350-
351349
foreach ($tags as $tag => $version) {
352350
if ($tagVersions[$tag] !== $version) {
353-
unset($this->knownTagVersions[$tag]);
351+
$fetchTagVersions = true;
354352
}
355353
}
356354
}
@@ -360,42 +358,67 @@ private function getTagVersions(array $tagsByKey, bool $persistTags): array
360358
}
361359

362360
$now = microtime(true);
363-
$tags = [];
361+
$tags = $newTags = [];
364362
foreach ($tagVersions as $tag => $version) {
365-
$tags[$tag.static::TAGS_PREFIX] = $tag;
366-
$knownTagVersion = $this->knownTagVersions[$tag] ?? [0, null];
367-
if ($fetchTagVersions || $knownTagVersion[1] !== $version || $now - $knownTagVersion[0] >= $this->knownTagVersionsTtl) {
363+
$tags[$tag . static::TAGS_PREFIX] = $tag;
364+
$knownTagVersion = $this->knownTagVersions[$tag] ?? [0];
365+
if ($fetchTagVersions || $now - $knownTagVersion[0] >= $this->knownTagVersionsTtl) {
368366
// reuse previously fetched tag versions up to the ttl
369367
$fetchTagVersions = true;
368+
continue;
370369
}
371-
unset($this->knownTagVersions[$tag]); // For LRU tracking
372-
if ([0, null] !== $knownTagVersion) {
373-
$this->knownTagVersions[$tag] = $knownTagVersion;
370+
if ($persistTags) {
371+
if (null === $knownTagVersion[1]) {
372+
$newTags[$tag] = $knownTagVersion[2];
373+
continue;
374+
}
375+
$tagVersions[$tag] = $knownTagVersion[1];
376+
} elseif ($knownTagVersion[1] !== $version) {
377+
$fetchTagVersions = true;
374378
}
375379
}
376380

377381
if (!$fetchTagVersions) {
382+
if ($newTags) {
383+
foreach ($newTags as $tag => $version) {
384+
$tagVersions[$tag] = $version->get();
385+
$this->knownTagVersions[$tag] = [$now, $tagVersions[$tag], null];
386+
}
387+
388+
(self::$saveTags)($this->tags, $newTags);
389+
}
390+
378391
return $tagVersions;
379392
}
380393

381-
$newTags = [];
394+
if (\count($this->knownTagVersions) > self::MAX_NUMBER_OF_KNOWN_TAG_VERSIONS) {
395+
array_splice($this->knownTagVersions, 0, \count($this->knownTagVersions) >> 1);
396+
}
397+
398+
$newTags = $tagVersions = [];
382399
$newVersion = null;
383400
foreach ($this->tags->getItems(array_keys($tags)) as $tag => $version) {
401+
unset($this->knownTagVersions[$tag = $tags[$tag]]); // For LRU tracking
402+
$v = null;
384403
if (!$version->isHit()) {
385-
$newTags[$tag] = $version->set($newVersion ??= random_bytes(6));
404+
$version->set($newVersion ??= random_bytes(6));
405+
if ($persistTags) {
406+
$newTags[$tag] = $version;
407+
$tagVersions[$tag] = $newVersion;
408+
} else {
409+
$v = $version; // for future persisting
410+
$tagVersions[$tag] = null;
411+
}
412+
} else {
413+
$tagVersions[$tag] = $version->get();
386414
}
387-
$tagVersions[$tag = $tags[$tag]] = $version->get();
388-
$this->knownTagVersions[$tag] = [$now, $tagVersions[$tag]];
415+
$this->knownTagVersions[$tag] = [$now, $tagVersions[$tag], $v];
389416
}
390417

391-
if ($newTags && $persistTags) {
418+
if ($newTags) {
392419
(self::$saveTags)($this->tags, $newTags);
393420
}
394421

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);
397-
}
398-
399422
return $tagVersions;
400423
}
401424
}

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,18 @@ public function testKnownTagVersionsTtl()
6767

6868
$pool->save($item);
6969
$this->assertTrue($pool->getItem('foo')->isHit());
70-
$this->assertTrue($pool->getItem('foo')->isHit());
7170

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

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

7675
sleep(5);
7776

78-
$this->assertTrue($pool->getItem('foo')->isHit());
77+
$this->assertTrue($pool->getItem('foo')->isHit()); // known tag version is still used
78+
79+
sleep(10);
80+
81+
$this->assertFalse($pool->getItem('foo')->isHit()); // known tag version has expired
7982
}
8083

8184
public function testInvalidateTagsWithArrayAdapter()

0 commit comments

Comments
 (0)