diff --git a/src/Cache.php b/src/Cache.php index af626b66..3632c309 100644 --- a/src/Cache.php +++ b/src/Cache.php @@ -25,6 +25,7 @@ use function class_exists; use function get_debug_type; +use function is_readable; use function is_string; use function md5_file; use function sprintf; @@ -113,15 +114,16 @@ public function clear(string $prefix = ''): bool */ public function isHit(string $filename): bool { + $currentFingerprint = $this->getFingerprint($filename); + // Try to fetch item from cache - $item = $this->getItem($filename); + $item = $this->pool->getItem($this->getKey($filename, $currentFingerprint)); if (!$item->isHit()) { ++$this->misses; return false; } $fingerprintSaved = $item->get(); - $currentFingerprint = md5_file($filename); if ($currentFingerprint !== $fingerprintSaved) { ++$this->misses; @@ -151,11 +153,27 @@ public function __debugInfo(): array ]; } - private function getKey(string $filename): string + private function getKey(string $filename, ?string $fingerprint = null): string { + $fingerprint ??= $this->getFingerprint($filename); + if (null !== $fingerprint) { + return $fingerprint; + } + return str_replace(str_split(ItemInterface::RESERVED_CHARACTERS), '_', $filename); } + private function getFingerprint(string $filename): ?string + { + if (!is_readable($filename)) { + return null; + } + + $fingerprint = md5_file($filename); + + return is_string($fingerprint) ? $fingerprint : null; + } + /** * @since Release 9.6.0 */ diff --git a/tests/Cache/CacheTest.php b/tests/Cache/CacheTest.php index e745fa65..5e95c8ec 100644 --- a/tests/Cache/CacheTest.php +++ b/tests/Cache/CacheTest.php @@ -21,6 +21,7 @@ use Symfony\Component\Cache\CacheItem; use function dirname; +use function is_readable; use function md5_file; use function sha1_file; use function str_replace; @@ -141,10 +142,32 @@ public function testFilenameHasReservedCharacters(): void $this->assertEquals($fingerprint, self::$cache->getItem($filename)->get()); } + public function testSameContentsShareCacheItem(): void + { + $firstFilename = __DIR__ . '/Fixtures/releases/3118/test.fixture'; + $secondFilename = __DIR__ . '/Fixtures/releases/3119/test.fixture'; + $fingerprint = md5_file($firstFilename); + + $firstCacheItem = self::$cache->getItem($firstFilename); + $secondCacheItem = self::$cache->getItem($secondFilename); + + $this->assertSame($firstCacheItem->getKey(), $secondCacheItem->getKey()); + + $firstCacheItem->set($fingerprint); + $saved = self::$cache->saveItem($firstCacheItem); + + $this->assertTrue($saved); + $this->assertTrue(self::$cache->isHit($secondFilename)); + } + private function generateItems(array $values): Generator { foreach ($values as $filename => $processor) { - $key = str_replace('/', '_', $filename); + if (is_readable($filename)) { + $key = md5_file($filename); + } else { + $key = str_replace('/', '_', $filename); + } $value = $processor ? $processor($filename) : null; $isHit = (null !== $value); yield $key => (self::$createCacheItem)($key, $value, $isHit); diff --git a/tests/Cache/Fixtures/releases/3118/test.fixture b/tests/Cache/Fixtures/releases/3118/test.fixture new file mode 100644 index 00000000..859d1071 --- /dev/null +++ b/tests/Cache/Fixtures/releases/3118/test.fixture @@ -0,0 +1 @@ +same release contents diff --git a/tests/Cache/Fixtures/releases/3119/test.fixture b/tests/Cache/Fixtures/releases/3119/test.fixture new file mode 100644 index 00000000..859d1071 --- /dev/null +++ b/tests/Cache/Fixtures/releases/3119/test.fixture @@ -0,0 +1 @@ +same release contents