Skip to content

Commit

Permalink
Merge pull request #4698 from neos/task/speed-up-documentUriPathProje…
Browse files Browse the repository at this point in the history
…ction

TASK: Improve performance of `DocumentUriPathProjection`
  • Loading branch information
ahaeslich authored Nov 3, 2023
2 parents 439cda3 + dec12f4 commit 3d63397
Showing 1 changed file with 23 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ final class DocumentUriPathProjection implements ProjectionInterface, WithMarkSt
private DoctrineCheckpointStorage $checkpointStorage;
private ?DocumentUriPathFinder $stateAccessor = null;

/**
* @var array<string, array<string, bool>>
*/
private array $nodeTypeImplementsRuntimeCache = [];

public function __construct(
private readonly NodeTypeManager $nodeTypeManager,
private readonly Connection $dbal,
Expand Down Expand Up @@ -707,35 +712,33 @@ private function isNodeExplicitlyDisabled(DocumentNodeInfo $node): bool

private function isSiteNodeType(NodeTypeName $nodeTypeName): bool
{
// HACK: We consider the currently configured node type of the given node.
// This is a deliberate side effect of this projector!
if (!$this->nodeTypeManager->hasNodeType($nodeTypeName)) {
return false;
}
$nodeType = $this->nodeTypeManager->getNodeType($nodeTypeName);
return $nodeType->isOfType(NodeTypeNameFactory::forSite());
return $this->isNodeTypeOfType($nodeTypeName, NodeTypeNameFactory::forSite());
}

private function isDocumentNodeType(NodeTypeName $nodeTypeName): bool
{
// HACK: We consider the currently configured node type of the given node.
// This is a deliberate side effect of this projector!
if (!$this->nodeTypeManager->hasNodeType($nodeTypeName)) {
return false;
}
$nodeType = $this->nodeTypeManager->getNodeType($nodeTypeName);
return $nodeType->isOfType(NodeTypeNameFactory::forDocument());
return $this->isNodeTypeOfType($nodeTypeName, NodeTypeNameFactory::forDocument());
}

private function isShortcutNodeType(NodeTypeName $nodeTypeName): bool
{
// HACK: We consider the currently configured node type of the given node.
// This is a deliberate side effect of this projector!
if (!$this->nodeTypeManager->hasNodeType($nodeTypeName)) {
return false;
return $this->isNodeTypeOfType($nodeTypeName, NodeTypeNameFactory::forShortcut());
}

private function isNodeTypeOfType(NodeTypeName $nodeTypeName, NodeTypeName $superNodeTypeName): bool
{
if (!array_key_exists($superNodeTypeName->value, $this->nodeTypeImplementsRuntimeCache)) {
$this->nodeTypeImplementsRuntimeCache[$superNodeTypeName->value] = [];
}
if (!array_key_exists($nodeTypeName->value, $this->nodeTypeImplementsRuntimeCache[$superNodeTypeName->value])) {
// HACK: We consider the currently configured node type of the given node.
// This is a deliberate side effect of this projector!
// Note: We could add some hash over all node type decisions to the projected read model
// to tell whether a replay is required (e.g. if a document node type was changed to a content type vice versa)
// With https://github.com/neos/neos-development-collection/issues/4468 this can be compared in the `getStatus()` implementation
$this->nodeTypeImplementsRuntimeCache[$superNodeTypeName->value][$nodeTypeName->value] = $this->nodeTypeManager->hasNodeType($nodeTypeName) && $this->nodeTypeManager->getNodeType($nodeTypeName)->isOfType($superNodeTypeName);
}
$nodeType = $this->nodeTypeManager->getNodeType($nodeTypeName);
return $nodeType->isOfType(NodeTypeNameFactory::forShortcut());
return $this->nodeTypeImplementsRuntimeCache[$superNodeTypeName->value][$nodeTypeName->value];
}

private function tryGetNode(\Closure $closure): ?DocumentNodeInfo
Expand Down

0 comments on commit 3d63397

Please sign in to comment.