From 9b3e99a47ea0684cb08d8bc9ad1fd54109713703 Mon Sep 17 00:00:00 2001 From: Priyadi Iman Nurcahyo <1102197+priyadi@users.noreply.github.com> Date: Wed, 17 Jan 2024 05:37:02 +0700 Subject: [PATCH] perf: Add caching for `TransformerRegistry`. --- CHANGELOG.md | 4 ++ config/services.php | 14 ++++ .../CachingTransformerRegistry.php | 67 +++++++++++++++++++ .../TransformerRegistry.php | 4 +- .../TransformerRegistryInterface.php | 8 +-- 5 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 src/TransformerRegistry/CachingTransformerRegistry.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d9e220..effa751 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## 0.5.15 + +* perf: Add caching for `TransformerRegistry`. + ## 0.5.14 * fix: Add missing deps to `composer.json` diff --git a/config/services.php b/config/services.php index d72bdb4..61a2632 100644 --- a/config/services.php +++ b/config/services.php @@ -37,6 +37,7 @@ use Rekalogika\Mapper\Transformer\StringToBackedEnumTransformer; use Rekalogika\Mapper\Transformer\TraversableToArrayAccessTransformer; use Rekalogika\Mapper\Transformer\TraversableToTraversableTransformer; +use Rekalogika\Mapper\TransformerRegistry\CachingTransformerRegistry; use Rekalogika\Mapper\TransformerRegistry\TransformerRegistry; use Rekalogika\Mapper\TypeResolver\CachingTypeResolver; use Rekalogika\Mapper\TypeResolver\TypeResolver; @@ -219,6 +220,19 @@ '$mappingFactory' => service('rekalogika.mapper.mapping_factory'), ]); + $services + ->set('rekalogika.mapper.cache.transformer_registry') + ->parent('cache.system') + ->tag('cache.pool'); + + $services + ->set('rekalogika.mapper.transformer_registry.cache', CachingTransformerRegistry::class) + ->decorate('rekalogika.mapper.transformer_registry') + ->args([ + service('.inner'), + service('rekalogika.mapper.cache.transformer_registry') + ]); + # method mapper $services diff --git a/src/TransformerRegistry/CachingTransformerRegistry.php b/src/TransformerRegistry/CachingTransformerRegistry.php new file mode 100644 index 0000000..99c0bf5 --- /dev/null +++ b/src/TransformerRegistry/CachingTransformerRegistry.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +namespace Rekalogika\Mapper\TransformerRegistry; + +use Psr\Cache\CacheItemPoolInterface; +use Rekalogika\Mapper\Transformer\Contracts\TransformerInterface; + +class CachingTransformerRegistry implements TransformerRegistryInterface +{ + /** + * @var array + */ + private array $findBySourceAndTargetTypesCache = []; + + public function __construct( + private TransformerRegistryInterface $decorated, + private CacheItemPoolInterface $cacheItemPool, + ) { + } + + public function get(string $id): TransformerInterface + { + return $this->decorated->get($id); + } + + public function findBySourceAndTargetTypes( + array $sourceTypes, + array $targetTypes, + ): SearchResult { + $cacheKey = md5(serialize($sourceTypes) . '--' . serialize($targetTypes)); + + if (isset($this->findBySourceAndTargetTypesCache[$cacheKey])) { + return $this->findBySourceAndTargetTypesCache[$cacheKey]; + } + + $cacheItem = $this->cacheItemPool->getItem($cacheKey); + + if ($cacheItem->isHit()) { + /** @var mixed */ + $result = $cacheItem->get(); + + if ($result instanceof SearchResult) { + return $this->findBySourceAndTargetTypesCache[$cacheKey] = $result; + } + + $this->cacheItemPool->deleteItem($cacheKey); + } + + $result = $this->decorated->findBySourceAndTargetTypes($sourceTypes, $targetTypes); + + $cacheItem->set($result); + $this->cacheItemPool->save($cacheItem); + + return $this->findBySourceAndTargetTypesCache[$cacheKey] = $result; + } +} diff --git a/src/TransformerRegistry/TransformerRegistry.php b/src/TransformerRegistry/TransformerRegistry.php index 1b7590c..b522475 100644 --- a/src/TransformerRegistry/TransformerRegistry.php +++ b/src/TransformerRegistry/TransformerRegistry.php @@ -117,8 +117,8 @@ private function findBySourceAndTargetType( } public function findBySourceAndTargetTypes( - iterable $sourceTypes, - iterable $targetTypes, + array $sourceTypes, + array $targetTypes, ): SearchResult { /** @var array */ $searchResultEntries = []; diff --git a/src/TransformerRegistry/TransformerRegistryInterface.php b/src/TransformerRegistry/TransformerRegistryInterface.php index 8126c83..43ba24d 100644 --- a/src/TransformerRegistry/TransformerRegistryInterface.php +++ b/src/TransformerRegistry/TransformerRegistryInterface.php @@ -22,12 +22,12 @@ interface TransformerRegistryInterface public function get(string $id): TransformerInterface; /** - * @param iterable $sourceTypes - * @param iterable $targetTypes + * @param array $sourceTypes + * @param array $targetTypes * @return SearchResult */ public function findBySourceAndTargetTypes( - iterable $sourceTypes, - iterable $targetTypes, + array $sourceTypes, + array $targetTypes, ): SearchResult; }