Skip to content

Commit ff71914

Browse files
committed
Merge branch '5.1' into 5.x
* 5.1: Optimize circular collection by removing flattening
2 parents deb6aa0 + 0b52dff commit ff71914

File tree

1 file changed

+18
-45
lines changed

1 file changed

+18
-45
lines changed

Dumper/PhpDumper.php

Lines changed: 18 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -426,69 +426,42 @@ private function analyzeReferences()
426426
$this->singleUsePrivateIds[$id] = $id;
427427
}
428428

429-
$newNodes = [];
430-
if (!$this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $newNodes)) {
431-
foreach ($newNodes as $newNodeId => $_) {
432-
$checkedNodes[$newNodeId] = [];
433-
}
434-
continue;
435-
}
436-
437-
$nodesToFlatten = $newNodes;
438-
do {
439-
$changedNodes = [];
440-
foreach ($nodesToFlatten as $newNodeId => $_) {
441-
$deps = &$checkedNodes[$newNodeId];
442-
foreach ($deps as $id => [$path, $depsByConstructor]) {
443-
foreach ($checkedNodes[$id] as $depsId => [$subPath, $subDepsByConstructor]) {
444-
if (!isset($deps[$depsId]) || ($depsByConstructor && $subDepsByConstructor && !$deps[$depsId][1])) {
445-
array_unshift($subPath, $id);
446-
$deps[$depsId] = [$subPath, $depsByConstructor && $subDepsByConstructor];
447-
$changedNodes += $newNodes[$newNodeId] ?? [];
448-
}
449-
}
450-
}
451-
}
452-
} while ($nodesToFlatten = $changedNodes);
453-
454-
foreach ($newNodes as $newNodeId => $_) {
455-
if (null !== $n = $checkedNodes[$newNodeId][$newNodeId] ?? null) {
456-
$this->addCircularReferences($newNodeId, $n[0], $n[1]);
457-
}
458-
}
429+
$this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes);
459430
}
460431

461432
$this->container->getCompiler()->getServiceReferenceGraph()->clear();
462433
$this->singleUsePrivateIds = array_diff_key($this->singleUsePrivateIds, $this->circularReferences);
463434
}
464435

465-
private function collectCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array &$newNodes, array $path = []): bool
436+
private function collectCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array $path = [], bool $byConstructor = true): void
466437
{
467-
$path[$sourceId] = true;
468-
$checkedNodes[$sourceId] = [];
469-
$newNodes[$sourceId] = [];
470-
$circular = false;
438+
$path[$sourceId] = $byConstructor;
439+
$checkedNodes[$sourceId] = true;
471440
foreach ($edges as $edge) {
472441
$node = $edge->getDestNode();
473442
$id = $node->getId();
474-
if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isWeak()) {
443+
444+
if (!($definition = $node->getValue()) instanceof Definition || $sourceId === $id || ($edge->isLazy() && ($this->proxyDumper ?? $this->getProxyDumper())->isProxyCandidate($definition)) || $edge->isWeak()) {
475445
continue;
476446
}
477447

478448
if (isset($path[$id])) {
479-
$circular = true;
449+
$loop = null;
450+
$loopByConstructor = $edge->isReferencedByConstructor();
451+
foreach ($path as $k => $pathByConstructor) {
452+
if (null !== $loop) {
453+
$loop[] = $k;
454+
$loopByConstructor = $loopByConstructor && $pathByConstructor;
455+
} elseif ($k === $id) {
456+
$loop = [];
457+
}
458+
}
459+
$this->addCircularReferences($id, $loop, $loopByConstructor);
480460
} elseif (!isset($checkedNodes[$id])) {
481-
$circular = $this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $newNodes, $path) || $circular;
482-
}
483-
484-
$checkedNodes[$sourceId][$id] = [[], $edge->isReferencedByConstructor()];
485-
if (isset($newNodes[$id])) {
486-
$newNodes[$id][$sourceId] = true;
461+
$this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $path, $edge->isReferencedByConstructor());
487462
}
488463
}
489464
unset($path[$sourceId]);
490-
491-
return $circular;
492465
}
493466

494467
private function addCircularReferences(string $sourceId, array $currentPath, bool $byConstructor)

0 commit comments

Comments
 (0)