From 0e6836eee943fdb6d3b76592ab861992074edb9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Sat, 15 Jul 2023 15:53:39 +0200 Subject: [PATCH] Optimize TypeRegistry::lookupName() from O(N) to O(1) --- src/Types/TypeRegistry.php | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Types/TypeRegistry.php b/src/Types/TypeRegistry.php index 762cc3f8672..0730e38ba9d 100644 --- a/src/Types/TypeRegistry.php +++ b/src/Types/TypeRegistry.php @@ -6,8 +6,8 @@ use Doctrine\DBAL\Exception; -use function array_search; -use function in_array; +use function assert; +use function spl_object_id; /** * The type registry is responsible for holding a map of all known DBAL types. @@ -17,11 +17,14 @@ final class TypeRegistry { /** @var array Map of type names and their corresponding flyweight objects. */ private array $instances; + /** @var array */ + private array $instancesReverseIndex; /** @param array $instances */ public function __construct(array $instances = []) { - $this->instances = []; + $this->instances = []; + $this->instancesReverseIndex = []; foreach ($instances as $name => $type) { $this->register($name, $type); } @@ -80,7 +83,8 @@ public function register(string $name, Type $type): void throw Exception::typeAlreadyRegistered($type); } - $this->instances[$name] = $type; + $this->instances[$name] = $type; + $this->instancesReverseIndex[spl_object_id($type)] = $name; } /** @@ -94,11 +98,12 @@ public function override(string $name, Type $type): void throw Exception::typeNotFound($name); } - if (! in_array($this->findTypeName($type), [$name, null], true)) { + if (($this->findTypeName($type) ?? $name) !== $name) { throw Exception::typeAlreadyRegistered($type); } - $this->instances[$name] = $type; + $this->instances[$name] = $type; + $this->instancesReverseIndex[spl_object_id($type)] = $name; } /** @@ -115,10 +120,9 @@ public function getMap(): array private function findTypeName(Type $type): ?string { - $name = array_search($type, $this->instances, true); - - if ($name === false) { - return null; + $name = $this->instancesReverseIndex[spl_object_id($type)] ?? null; + if ($name !== null) { + assert(($this->instances[$name] ?? null) === $type); } return $name;