Skip to content

Commit fa65dfa

Browse files
[PropertyInfo] Use a single cache item per method
1 parent 21d0197 commit fa65dfa

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ class PropertyInfoCacheExtractor implements PropertyInfoExtractorInterface
2424
{
2525
private $propertyInfoExtractor;
2626
private $cacheItemPool;
27+
28+
/**
29+
* A cache of property information, first keyed by the method called and
30+
* then by the serialized method arguments.
31+
*
32+
* @var array
33+
*/
2734
private $arrayCache = [];
2835

2936
public function __construct(PropertyInfoExtractorInterface $propertyInfoExtractor, CacheItemPoolInterface $cacheItemPool)
@@ -98,22 +105,34 @@ private function extract($method, array $arguments)
98105
}
99106

100107
// Calling rawurlencode escapes special characters not allowed in PSR-6's keys
101-
$key = rawurlencode($method.'.'.$serializedArguments);
102-
103-
if (\array_key_exists($key, $this->arrayCache)) {
104-
return $this->arrayCache[$key];
108+
$encodedMethod = \rawurlencode($method);
109+
if (\array_key_exists($encodedMethod, $this->arrayCache) && \array_key_exists($serializedArguments, $this->arrayCache[$encodedMethod])) {
110+
return $this->arrayCache[$encodedMethod][$serializedArguments];
105111
}
106112

107-
$item = $this->cacheItemPool->getItem($key);
113+
$item = $this->cacheItemPool->getItem($encodedMethod);
108114

115+
$data = $item->get();
109116
if ($item->isHit()) {
110-
return $this->arrayCache[$key] = $item->get();
117+
$this->arrayCache[$encodedMethod] = $data[$encodedMethod];
118+
// Only match if the specific arguments have been cached.
119+
if (\array_key_exists($serializedArguments, $data[$encodedMethod])) {
120+
return $this->arrayCache[$encodedMethod][$serializedArguments];
121+
}
122+
}
123+
124+
// It's possible that the method has been called, but with different
125+
// arguments, in which case $data will already be initialized.
126+
if (!$data) {
127+
$data = [];
111128
}
112129

113130
$value = \call_user_func_array([$this->propertyInfoExtractor, $method], $arguments);
114-
$item->set($value);
131+
$data[$encodedMethod][$serializedArguments] = $value;
132+
$this->arrayCache[$encodedMethod][$serializedArguments] = $value;
133+
$item->set($data);
115134
$this->cacheItemPool->save($item);
116135

117-
return $this->arrayCache[$key] = $value;
136+
return $this->arrayCache[$encodedMethod][$serializedArguments];
118137
}
119138
}

0 commit comments

Comments
 (0)