Skip to content

Commit

Permalink
perf: Add caching for ObjectMappingResolver.
Browse files Browse the repository at this point in the history
  • Loading branch information
priyadi committed Jan 16, 2024
1 parent 7ecc984 commit 4bcc751
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* refactor: Move mapping logic in `ObjectToObjectTransformer` to its own
service.
* refactor: Move more mapping logic to `ObjectMappingResolver`.
* perf: Add caching for `ObjectMappingResolver`.

## 0.5.12

Expand Down
14 changes: 14 additions & 0 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use Rekalogika\Mapper\Transformer\DateTimeTransformer;
use Rekalogika\Mapper\Transformer\InheritanceMapTransformer;
use Rekalogika\Mapper\Transformer\NullTransformer;
use Rekalogika\Mapper\Transformer\ObjectMappingResolver\CachingObjectMappingResolver;
use Rekalogika\Mapper\Transformer\ObjectMappingResolver\ObjectMappingResolver;
use Rekalogika\Mapper\Transformer\ObjectToArrayTransformer;
use Rekalogika\Mapper\Transformer\ObjectToObjectTransformer;
Expand Down Expand Up @@ -195,6 +196,19 @@
service('rekalogika.mapper.property_info'),
]);

$services
->set('rekalogika.mapper.cache.object_mapping_resolver')
->parent('cache.system')
->tag('cache.pool');

$services
->set('rekalogika.mapper.object_mapping_resolver.cache', CachingObjectMappingResolver::class)
->decorate('rekalogika.mapper.object_mapping_resolver')
->args([
service('.inner'),
service('rekalogika.mapper.cache.object_mapping_resolver')
]);

# transformer registry

$services
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Transformer\ObjectMappingResolver;

use Psr\Cache\CacheItemPoolInterface;
use Rekalogika\Mapper\Context\Context;
use Rekalogika\Mapper\Transformer\ObjectMappingResolver\Contracts\ObjectMapping;
use Rekalogika\Mapper\Transformer\ObjectMappingResolver\Contracts\ObjectMappingResolverInterface;

final class CachingObjectMappingResolver implements ObjectMappingResolverInterface
{
/**
* @var array<string,ObjectMapping>
*/
private array $cache = [];

public function __construct(
private ObjectMappingResolverInterface $decorated,
private CacheItemPoolInterface $cacheItemPool,
) {
}

public function resolveObjectMapping(
string $sourceClass,
string $targetClass,
Context $context
): ObjectMapping {
$cacheKey = $sourceClass . ':' . $targetClass;

if (isset($this->cache[$cacheKey])) {
return $this->cache[$cacheKey];
}

$cacheItem = $this->cacheItemPool->getItem($cacheKey);

if ($cacheItem->isHit()) {
/** @var mixed */
$cached = $cacheItem->get();

if ($cached instanceof ObjectMapping) {
return $this->cache[$cacheKey] = $cached;
}

unset($this->cache[$cacheKey]);
$this->cacheItemPool->deleteItem($cacheKey);
}

$objectMapping = $this->decorated
->resolveObjectMapping($sourceClass, $targetClass, $context);

$cacheItem->set($objectMapping);
$this->cacheItemPool->save($cacheItem);

return $this->cache[$cacheKey] = $objectMapping;
}
}

0 comments on commit 4bcc751

Please sign in to comment.