Skip to content

Commit fc1e05e

Browse files
committed
perf(relationships): pre-index processQueries relationship lookups
Relationships::processQueries() ran array_filter() over all relationships once per dotted Select value to find the relationship matching a given key, costing O(values * relationships) per call. Build a key -> Document map once at the top so each lookup is O(1) instead. phpstan baseline updated to drop the now-unused array_filter ignore and to reduce one Relationship::fromDocument count that the new map type makes provable.
1 parent e8cd9da commit fc1e05e

2 files changed

Lines changed: 12 additions & 10 deletions

File tree

phpstan-baseline.neon

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -897,12 +897,6 @@ parameters:
897897
-
898898
message: '#^Parameter \#2 \$attribute of static method Utopia\\Database\\Relationship\:\:fromDocument\(\) expects Utopia\\Database\\Document, mixed given\.$#'
899899
identifier: argument.type
900-
count: 2
901-
path: src/Database/Hook/Relationships.php
902-
903-
-
904-
message: '#^Parameter \#2 \$callback of function array_filter expects \(callable\(mixed\)\: bool\)\|null, Closure\(Utopia\\Database\\Document\)\: bool given\.$#'
905-
identifier: argument.type
906900
count: 1
907901
path: src/Database/Hook/Relationships.php
908902

src/Database/Hook/Relationships.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,17 @@ public function processQueries(array $relationships, array $queries): array
916916
{
917917
$nestedSelections = [];
918918

919+
// Pre-index relationships by key once so per-value lookups are O(1)
920+
// instead of O(relationships) with a fresh array_filter each iteration.
921+
/** @var array<string, Document> $relationshipsByKey */
922+
$relationshipsByKey = [];
923+
/** @var Document $relationship */
924+
foreach ($relationships as $relationship) {
925+
/** @var string $relKey */
926+
$relKey = $relationship->getAttribute('key', $relationship->getId());
927+
$relationshipsByKey[$relKey] = $relationship;
928+
}
929+
919930
foreach ($queries as $query) {
920931
if ($query->getMethod() !== Method::Select) {
921932
continue;
@@ -931,10 +942,7 @@ public function processQueries(array $relationships, array $queries): array
931942
$nesting = \explode('.', $value);
932943
$selectedKey = \array_shift($nesting);
933944

934-
$relationship = \array_values(\array_filter(
935-
$relationships,
936-
fn (Document $relationship) => Attribute::fromDocument($relationship)->key === $selectedKey,
937-
))[0] ?? null;
945+
$relationship = $relationshipsByKey[$selectedKey] ?? null;
938946

939947
if (! $relationship) {
940948
continue;

0 commit comments

Comments
 (0)